}
#define FR_DBUFF_MEMSET_RETURN(_dbuff, _c, _inlen) FR_DBUFF_RETURN(fr_dbuff_memset, _dbuff, _c, _inlen)
+#define FR_DBUFF_NUM_IN_FUNC(_type) \
+static inline ssize_t fr_dbuff_##_type##_in(fr_dbuff_t *dbuff, _type##_t num) \
+{ \
+ size_t freespace = fr_dbuff_remaining(dbuff); \
+ fr_assert(!dbuff->is_const); \
+ if (sizeof(_type##_t) > freespace) return -(sizeof(_type##_t) - freespace); \
+ fr_net_from_##_type(dbuff->p, num); \
+ dbuff->p += sizeof(_type##_t); \
+ return dbuff->parent ? _fr_dbuff_advance(dbuff->parent, sizeof(_type##_t)) : ((ssize_t) sizeof(_type##_t)); \
+}
+FR_DBUFF_NUM_IN_FUNC(uint16)
+FR_DBUFF_NUM_IN_FUNC(uint32)
+FR_DBUFF_NUM_IN_FUNC(uint64)
+FR_DBUFF_NUM_IN_FUNC(int16)
+FR_DBUFF_NUM_IN_FUNC(int32)
+FR_DBUFF_NUM_IN_FUNC(int64)
+
/** Copy an unsigned 16-bit integer into a buffer in wire format (big endian)
*
* @param[in] dbuff to copy data to
* @param[in] num value to copy
* @return
- * 0 no data set
- * >0 (2, actually) the number of bytes set in the dbuff
- * <0 the number of bytes required
+ * - 0 no data set
+ * - >0 the number of bytes added to the dbuff (2).
+ * - <0 the number of bytes required
*/
-static inline ssize_t fr_dbuff_net_encode_uint16(fr_dbuff_t *dbuff, uint16_t num)
-{
- size_t freespace = fr_dbuff_remaining(dbuff);
-
- fr_assert(!dbuff->is_const);
-
- if (sizeof(uint16_t) > freespace) return -(sizeof(uint16_t) - freespace);
-
- fr_net_from_uint16(dbuff->p, num);
- dbuff->p += sizeof(uint16_t);
-
- return dbuff->parent ? _fr_dbuff_advance(dbuff->parent, sizeof(uint16_t)) : ((ssize_t) sizeof(uint16_t));
-}
-#define FR_DBUFF_NET_FROM_UINT16_RETURN(_dbuff, _num) FR_DBUFF_RETURN(fr_dbuff_net_from_uint16, _dbuff, _num)
+#define FR_DBUFF_UINT16_IN_RETURN(_dbuff, _num) FR_DBUFF_RETURN(fr_dbuff_uint16_in, _dbuff, _num)
/** Copy an unsigned 32-bit integer into a buffer in wire format (big endian)
*
- * @param[in] dbuff to copy data to
- * @param[in] num value to copy
+ * @param[in] _dbuff to copy data to
+ * @param[in] _num value to copy
* @return
- * 0 no data set
- * >0 (4, actually) the number of bytes set in the dbuff
- * <0 the number of bytes required
+ * - 0 no data set
+ * - >0 the number of bytes added to the dbuff (4).
+ * - <0 the number of bytes required
*/
-static inline ssize_t fr_dbuff_net_encode_uint32(fr_dbuff_t *dbuff, uint32_t num)
-{
- size_t freespace = fr_dbuff_remaining(dbuff);
-
- fr_assert(!dbuff->is_const);
-
- if (sizeof(uint32_t) > freespace) return -(sizeof(uint32_t) - freespace);
-
- fr_net_from_uint32(dbuff->p, num);
- dbuff->p += sizeof(uint32_t);
-
- return dbuff->parent ? _fr_dbuff_advance(dbuff->parent, sizeof(uint32_t)) : ((ssize_t) sizeof(uint32_t));
-}
-#define FR_DBUFF_NET_FROM_UINT32_RETURN(_dbuff, _num) FR_DBUFF_RETURN(fr_dbuff_net_from_uint32, _dbuff, _num)
+#define FR_DBUFF_UINT32_IN_RETURN(_dbuff, _num) FR_DBUFF_RETURN(fr_dbuff_uint32_in, _dbuff, _num)
/** Copy an unsigned 64-bit integer into a buffer in wire format (big endian)
*
* @param[in] dbuff to copy data to
* @param[in] num value to copy
* @return
- * 0 no data set
- * >0 (8, actually) the number of bytes set in the dbuff
- * <0 the number of bytes required
+ * - 0 no data set
+ * - >0 the number of bytes added to the dbuff (8).
+ * - <0 the number of bytes required
*/
-static inline ssize_t fr_dbuff_net_encode_uint64(fr_dbuff_t *dbuff, uint64_t num)
-{
- size_t freespace = fr_dbuff_remaining(dbuff);
-
- fr_assert(!dbuff->is_const);
-
- if (sizeof(uint64_t) > freespace) return -(sizeof(uint64_t) - freespace);
-
- fr_net_from_uint64(dbuff->p, num);
- dbuff->p += sizeof(uint64_t);
-
- return dbuff->parent ? _fr_dbuff_advance(dbuff->parent, sizeof(uint64_t)) : ((ssize_t) sizeof(uint64_t));
-}
-#define FR_DBUFF_NET_FROM_UINT64_RETURN(_dbuff, _num) FR_DBUFF_RETURN(fr_dbuff_net_from_uint64, _dbuff, _num)
+#define FR_DBUFF_UINT64_IN_RETURN(_dbuff, _num) FR_DBUFF_RETURN(fr_dbuff_uint64_in, _dbuff, _num)
/** Copy a signed 16-bit integer into a buffer in wire format (big endian)
*
* @param[in] dbuff to copy data to
* @param[in] num value to copy
* @return
- * 0 no data set
- * >0 (2, actually) the number of bytes set in the dbuff
- * <0 the number of bytes required
+ * - 0 no data set
+ * - >0 the number of bytes added to the dbuff (2).
+ * - <0 the number of bytes required
*/
-static inline ssize_t fr_dbuff_net_encode_int16(fr_dbuff_t *dbuff, int16_t num)
-{
- return fr_dbuff_net_encode_uint16(dbuff, (uint16_t) num);
-}
-#define FR_DBUFF_NET_FROM_INT16_RETURN(_dbuff, _num) FR_DBUFF_RETURN(fr_dbuff_net_from_int16, _dbuff, _num)
+#define FR_DBUFF_INT16_IN_RETURN(_dbuff, _num) FR_DBUFF_RETURN(fr_dbuff_int16_in, _dbuff, _num)
/** Copy a signed 32-bit integer into a buffer in wire format (big endian)
*
* @param[in] dbuff to copy data to
* @param[in] num value to copy
* @return
- * 0 no data set
- * >0 (4, actually) the number of bytes set in the dbuff
- * <0 the number of bytes required
+ * - 0 no data set
+ * - >0 the number of bytes added to the dbuff (4).
+ * - <0 the number of bytes required
*/
-static inline ssize_t fr_dbuff_net_encode_int32(fr_dbuff_t *dbuff, int32_t num)
-{
- return fr_dbuff_net_encode_uint32(dbuff, (uint32_t) num);
-}
-#define FR_DBUFF_NET_FROM_INT32_RETURN(_dbuff, _num) FR_DBUFF_RETURN(fr_dbuff_net_from_int32, _dbuff, _num)
+#define FR_DBUFF_INT32_IN_RETURN(_dbuff, _num) FR_DBUFF_RETURN(fr_dbuff_int32_in,, _dbuff, _num)
/** Copy a signed 64-bit integer into a buffer in wire format (big endian)
*
* @param[in] dbuff to copy data to
* @param[in] num value to copy
* @return
- * 0 no data set
- * >0 (8, actually) the number of bytes set in the dbuff
- * <0 the number of bytes required
+ * - 0 no data set
+ * - >0 the number of bytes added to the dbuff (8).
+ * - <0 the number of bytes required
*/
-static inline ssize_t fr_dbuff_net_encode_int64(fr_dbuff_t *dbuff, int64_t num)
-{
- return fr_dbuff_net_encode_uint64(dbuff, (uint64_t) num);
-}
-#define FR_DBUFF_NET_FROM_UINT64_RETURN(_dbuff, _num) FR_DBUFF_RETURN(fr_dbuff_net_from_uint64, _dbuff, _num)
+#define FR_DBUFF_INT64_IN_RETURN(_dbuff, _num) FR_DBUFF_RETURN(fr_dbuff_int64_in, _dbuff, _num)
-#define fr_dbuff_net_encode(dbuff, value) \
+#define fr_dbuff_in(dbuff, value) \
_Generic((value), \
- int16_t : fr_dbuff_net_encode_int16(dbuff, (int16_t) value), \
- int32_t : fr_dbuff_net_encode_int32(dbuff, (int32_t) value), \
- int64_t : fr_dbuff_net_encode_int64(dbuff, (int64_t) value), \
- uint16_t : fr_dbuff_net_encode_uint16(dbuff, (uint16_t) value), \
- uint32_t : fr_dbuff_net_encode_uint32(dbuff, (uint32_t) value), \
- uint64_t : fr_dbuff_net_encode_uint64(dbuff, (uint64_t) value) \
+ int16_t : fr_dbuff_int16_in(dbuff, (int16_t)value), \
+ int32_t : fr_dbuff_int32_in(dbuff, (int32_t)value), \
+ int64_t : fr_dbuff_int64_in(dbuff, (int64_t)value), \
+ uint16_t : fr_dbuff_uint16_in(dbuff, (uint16_t)value), \
+ uint32_t : fr_dbuff_uint32_in(dbuff, (uint32_t)value), \
+ uint64_t : fr_dbuff_uint64_in(dbuff, (uint64_t)value) \
)
-static inline ssize_t fr_dbuff_net_encode_uint64v(fr_dbuff_t *dbuff, uint64_t num)
+static inline ssize_t fr_dbuff_uint64v_in(fr_dbuff_t *dbuff, uint64_t num)
{
- size_t num_bytes = ROUND_UP_DIV((size_t)fr_high_bit_pos(num), 8);
+ size_t ret;
+ ret = ROUND_UP_DIV((size_t)fr_high_bit_pos(num | 0x08), 8);
num = ntohll(num);
- return fr_dbuff_memcpy_in(dbuff, ((uint8_t *)&num) + (sizeof(uint64_t) - num_bytes), num_bytes);
+
+ return fr_dbuff_memcpy_in(dbuff, ((uint8_t *)&num) + (sizeof(uint64_t) - ret), ret);
}
/** @} */
/** Test the various dbuff_net_encode() functions and macros
*
- * @note Passing constants to fr_dbuff_net_encode() as it is written results in
+ * @note Passing constants to fr_dbuff_in() as it is written results in
* warnings about narrowing casts on the constants--but those casts are in
* the underlying inlined fr_net_from*() functions. They have to be there;
* that's how those functions work. (The tests worked despite the warnings.)
memset(buff, 0, sizeof(buff));
fr_dbuff_init(&dbuff, buff, sizeof(buff));
- TEST_CHECK(fr_dbuff_net_encode(&dbuff, u16val) == sizeof(uint16_t));
+ TEST_CHECK(fr_dbuff_in(&dbuff, u16val) == sizeof(uint16_t));
TEST_CHECK(buff[0] == 0x12);
TEST_CHECK(buff[1] == 0x34);
memset(buff, 0, sizeof(buff));
fr_dbuff_init(&dbuff, buff, sizeof(buff));
- TEST_CHECK(fr_dbuff_net_encode(&dbuff, u32val) == sizeof(uint32_t));
+ TEST_CHECK(fr_dbuff_in(&dbuff, u32val) == sizeof(uint32_t));
TEST_CHECK(buff[0] == 0x12);
TEST_CHECK(buff[1] == 0x34);
TEST_CHECK(buff[2] == 0x56);
memset(buff, 0, sizeof(buff));
fr_dbuff_init(&dbuff, buff, sizeof(buff));
- TEST_CHECK(fr_dbuff_net_encode(&dbuff, u64val) == sizeof(uint64_t));
+ TEST_CHECK(fr_dbuff_in(&dbuff, u64val) == sizeof(uint64_t));
TEST_CHECK(buff[0] == 0x12);
TEST_CHECK(buff[1] == 0x34);
TEST_CHECK(buff[2] == 0x56);
memset(buff, 0, sizeof(buff));
fr_dbuff_init(&dbuff, buff, sizeof(buff));
- TEST_CHECK(fr_dbuff_net_encode(&dbuff, i16val) == sizeof(int16_t));
+ TEST_CHECK(fr_dbuff_in(&dbuff, i16val) == sizeof(int16_t));
TEST_CHECK(buff[0] == 0x12);
TEST_CHECK(buff[1] == 0x34);
memset(buff, 0, sizeof(buff));
fr_dbuff_init(&dbuff, buff, sizeof(buff));
- TEST_CHECK(fr_dbuff_net_encode(&dbuff, i32val) == sizeof(int32_t));
+ TEST_CHECK(fr_dbuff_in(&dbuff, i32val) == sizeof(int32_t));
TEST_CHECK(buff[0] == 0x00);
TEST_CHECK(buff[1] == 0x00);
TEST_CHECK(buff[2] == 0xd3);
memset(buff, 0, sizeof(buff));
fr_dbuff_init(&dbuff, buff, sizeof(buff));
- TEST_CHECK(fr_dbuff_net_encode(&dbuff, i64val) == sizeof(int64_t));
+ TEST_CHECK(fr_dbuff_in(&dbuff, i64val) == sizeof(int64_t));
TEST_CHECK(buff[0] == 0x12);
TEST_CHECK(buff[1] == 0x34);
TEST_CHECK(buff[2] == 0x56);
TEST_CASE("Generate wire format variable-width");
memset(buff, 0, sizeof(buff));
fr_dbuff_init(&dbuff, buff, sizeof(buff));
- TEST_CHECK(fr_dbuff_net_encode_uint64v(&dbuff, 0x12) == 1);
+ TEST_CHECK(fr_dbuff_uint64v_in(&dbuff, 0x12) == 1);
TEST_CHECK(buff[0] == 0x12);
memset(buff, 0, sizeof(buff));
fr_dbuff_init(&dbuff, buff, sizeof(buff));
- TEST_CHECK(fr_dbuff_net_encode_uint64v(&dbuff, 0x1234) == 2);
+ TEST_CHECK(fr_dbuff_uint64v_in(&dbuff, 0x1234) == 2);
TEST_CHECK(buff[0] == 0x12);
TEST_CHECK(buff[1] == 0x34);
memset(buff, 0, sizeof(buff));
fr_dbuff_init(&dbuff, buff, sizeof(buff));
- TEST_CHECK(fr_dbuff_net_encode_uint64v(&dbuff, 0x123456) == 3);
+ TEST_CHECK(fr_dbuff_uint64v_in(&dbuff, 0x123456) == 3);
TEST_CHECK(buff[0] == 0x12);
TEST_CHECK(buff[1] == 0x34);
TEST_CHECK(buff[2] == 0x56);
memset(buff, 0, sizeof(buff));
fr_dbuff_init(&dbuff, buff, sizeof(buff));
- TEST_CHECK(fr_dbuff_net_encode_uint64v(&dbuff, 0x12345678) == 4);
+ TEST_CHECK(fr_dbuff_uint64v_in(&dbuff, 0x12345678) == 4);
TEST_CHECK(buff[0] == 0x12);
TEST_CHECK(buff[1] == 0x34);
TEST_CHECK(buff[2] == 0x56);
memset(buff, 0, sizeof(buff));
fr_dbuff_init(&dbuff, buff, sizeof(buff));
- TEST_CHECK(fr_dbuff_net_encode_uint64v(&dbuff, 0x123456789a) == 5);
+ TEST_CHECK(fr_dbuff_uint64v_in(&dbuff, 0x123456789a) == 5);
TEST_CHECK(buff[0] == 0x12);
TEST_CHECK(buff[1] == 0x34);
TEST_CHECK(buff[2] == 0x56);
memset(buff, 0, sizeof(buff));
fr_dbuff_init(&dbuff, buff, sizeof(buff));
- TEST_CHECK(fr_dbuff_net_encode_uint64v(&dbuff, 0x123456789abc) == 6);
+ TEST_CHECK(fr_dbuff_uint64v_in(&dbuff, 0x123456789abc) == 6);
TEST_CHECK(buff[0] == 0x12);
TEST_CHECK(buff[1] == 0x34);
TEST_CHECK(buff[2] == 0x56);
memset(buff, 0, sizeof(buff));
fr_dbuff_init(&dbuff, buff, sizeof(buff));
- TEST_CHECK(fr_dbuff_net_encode_uint64v(&dbuff, 0x123456789abcde) == 7);
+ TEST_CHECK(fr_dbuff_uint64v_in(&dbuff, 0x123456789abcde) == 7);
TEST_CHECK(buff[0] == 0x12);
TEST_CHECK(buff[1] == 0x34);
TEST_CHECK(buff[2] == 0x56);
memset(buff, 0, sizeof(buff));
fr_dbuff_init(&dbuff, buff, sizeof(buff));
- TEST_CHECK(fr_dbuff_net_encode_uint64v(&dbuff, 0x123456789abcdef0) == 8);
+ TEST_CHECK(fr_dbuff_uint64v_in(&dbuff, 0x123456789abcdef0) == 8);
TEST_CHECK(buff[0] == 0x12);
TEST_CHECK(buff[1] == 0x34);
TEST_CHECK(buff[2] == 0x56);
TEST_CASE("Refuse to write to too-small space");
fr_dbuff_init(&dbuff, buff, sizeof(uint32_t));
- TEST_CHECK(fr_dbuff_net_encode(&dbuff, u64val) == -(ssize_t)(sizeof(uint64_t) - sizeof(uint32_t)));
+ TEST_CHECK(fr_dbuff_in(&dbuff, u64val) == -(ssize_t)(sizeof(uint64_t) - sizeof(uint32_t)));
}
*/
{ "fr_dbuff_init", test_dbuff_init },
{ "fr_dbuff_init_no_parent", test_dbuff_init_no_parent },
- { "fr_dbuff_net_encode", test_dbuff_net_encode },
+ { "fr_dbuff_in", test_dbuff_net_encode },
{ NULL }
};
fr_net_from_uint32(out + sizeof(uint32_t), (uint32_t)num);
}
+/** Write out an signed 16bit integer in wire format (big endian)
+ *
+ * @param[out] out Where to write the integer.
+ * @param[in] num to encode.
+ */
+static inline void fr_net_from_int16(uint8_t out[static sizeof(int16_t)], int16_t num)
+{
+ out[0] = (num >> 8) & 0xff;
+ out[1] = num & 0xff;
+}
+
+/** Write out an signed 32bit integer in wire format (big endian)
+ *
+ * @param[out] out Where to write the integer.
+ * @param[in] num to encode.
+ */
+static inline void fr_net_from_int32(uint8_t out[static sizeof(int32_t)], int32_t num)
+{
+ fr_net_from_uint16(out, (int16_t) (num >> 16));
+ fr_net_from_uint16(out + sizeof(int16_t), (int16_t) num);
+}
+
+/** Write out an signed 64bit integer in wire format (big endian)
+ *
+ * @param[out] out Where to write the integer.
+ * @param[in] num to encode.
+ */
+static inline void fr_net_from_int64(uint8_t out[static sizeof(uint64_t)], uint64_t num)
+{
+ fr_net_from_uint32(out, (int32_t)(num >> 32));
+ fr_net_from_uint32(out + sizeof(int32_t), (int32_t)num);
+}
+
/** Write out an unsigned 64bit integer in wire format using the fewest bytes possible
*
* @param[out] out Where to write big endian encoding of num.
static inline size_t fr_net_from_uint64v(uint8_t out[static sizeof(uint64_t)], uint64_t num)
{
size_t ret;
- /*
- * Special case for zero.
- */
- if (num == 0) {
- out[0] = 0;
- return 1;
- }
- ret = ROUND_UP_DIV((size_t)fr_high_bit_pos(num), 8);
+ ret = ROUND_UP_DIV((size_t)fr_high_bit_pos(num | 0x80), 8);
num = ntohll(num);
memcpy(out, ((uint8_t *)&num) + (sizeof(uint64_t) - ret), ret); /* aligned */
return ((uint64_t)fr_net_to_uint32(data) << 32) | fr_net_to_uint32(data + sizeof(uint32_t));
}
+/** Read an signed 16bit integer from wire format (big endian)
+ *
+ * @param[in] data To convert to a 16bit signed integer of native endianness.
+ * @return a 16 bit signed integer of native endianness.
+ */
+static inline int16_t fr_net_to_int16(int8_t const data[static sizeof(int16_t)])
+{
+ return (((int16_t)data[0]) << 8) | data[1];
+}
+
+/** Read an signed 32bit integer from wire format (big endian)
+ *
+ * @param[in] data To convert to a 32bit signed integer of native endianness.
+ * @return a 32 bit signed integer of native endianness.
+ */
+static inline int32_t fr_net_to_int32(int8_t const data[static sizeof(int32_t)])
+{
+ return ((int32_t)fr_net_to_int16(data) << 16) | fr_net_to_int16(data + sizeof(int16_t));
+}
+
+/** Read an signed 64bit integer from wire format (big endian)
+ *
+ * @param[in] data To convert to a 64bit signed integer of native endianness.
+ * @return a 64 bit signed integer of native endianness.
+ */
+static inline int64_t fr_net_to_int64(int8_t const data[static sizeof(int64_t)])
+{
+ return ((int64_t)fr_net_to_int32(data) << 32) | fr_net_to_int32(data + sizeof(int32_t));
+}
+
/** Read an unsigned 64bit integer from wire format (big endian) with a variable length encoding
*
* @param[in] data Buffer containing the number.
} else switch (value->enumv->flags.length) {
case 2:
if (date > UINT16_MAX) date = UINT16_MAX;
- fr_dbuff_net_encode(dbuff, (int16_t) date);
+ fr_dbuff_in(dbuff, (int16_t) date);
break;
date_size4:
case 4:
if (date > UINT32_MAX) date = UINT32_MAX;
- fr_dbuff_net_encode(dbuff, (int32_t) date);
+ fr_dbuff_in(dbuff, (int32_t) date);
break;
case 8:
- fr_dbuff_net_encode(dbuff, date);
+ fr_dbuff_in(dbuff, date);
break;
default:
} else if (date > INT16_MAX) {
date = INT16_MAX;
}
- fr_dbuff_net_encode(dbuff, (int16_t)date);
+ fr_dbuff_in(dbuff, (int16_t)date);
break;
delta_size4:
} else if (date > INT32_MAX) {
date = INT32_MAX;
}
- fr_dbuff_net_encode(dbuff, (int32_t)date);
+ fr_dbuff_in(dbuff, (int32_t)date);
break;
case 8:
- fr_dbuff_net_encode(dbuff, (int64_t)date);
+ fr_dbuff_in(dbuff, (int64_t)date);
break;
default:
* Encode the type and write the width of the
* integer to the encoding byte.
*/
- flen = fr_dbuff_net_encode_uint64v(dbuff, da->attr);
+ flen = fr_dbuff_uint64v_in(dbuff, da->attr);
enc_field[0] |= ((flen - 1) << 5);
/*