]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
dbuff/sbuff: Shuffle functions so they're in the same order
authorArran Cudbard-Bell <a.cudbardb@freeradius.org>
Sat, 18 Jul 2020 20:06:20 +0000 (16:06 -0400)
committerArran Cudbard-Bell <a.cudbardb@freeradius.org>
Sat, 18 Jul 2020 20:06:20 +0000 (16:06 -0400)
src/lib/util/dbuff.h
src/lib/util/sbuff.c
src/lib/util/sbuff.h
src/protocols/radius/encode.c

index c4c50a86af91f9e05cf783e96850faef0a5c15fe..9c46e4523fc4efe544b0fe3332c9fb9cb7889560 100644 (file)
@@ -248,26 +248,6 @@ _fr_dbuff_init(_out, \
 }
 /** @} */
 
-/** @name dbuff position manipulation
- * @{
- */
-/** Reset the current position of the dbuff to the start of the string
- *
- */
-static inline uint8_t *fr_dbuff_start(fr_dbuff_t *dbuff)
-{
-       return dbuff->p = dbuff->start;
-}
-
-/** Reset the current position of the dbuff to the end of the string
- *
- */
-static inline uint8_t *fr_dbuff_end(fr_dbuff_t *dbuff)
-{
-       return dbuff->p = dbuff->end;
-}
-/** @} */
-
 /** @name Length checks
  * @{
  */
@@ -307,18 +287,37 @@ static inline size_t fr_dbuff_len(fr_dbuff_t const *dbuff)
 }
 /** @} */
 
-/** @name copy data to dbuff
- * @{
+/** @name Accessors
+ *
+ * Caching the values of these pointers or the pointer values from the dbuff
+ * directly is strongly discouraged as they can become invalidated during
+ * stream parsing or when printing to an auto-expanding buffer.
+ *
+ * These functions should only be used to pass dbuff pointers into 3rd party
+ * APIs.
  */
+static inline uint8_t *fr_dbuff_start(fr_dbuff_t *dbuff)
+{
+       return dbuff->start;
+}
 
-/** Generic wrapper macro to return if there's insufficient memory to satisfy the request on the dbuff
+static inline uint8_t *fr_dbuff_current(fr_dbuff_t *dbuff)
+{
+       return dbuff->p;
+}
+
+static inline uint8_t *fr_dbuff_end(fr_dbuff_t *dbuff)
+{
+       return dbuff->end;
+}
+/** @} */
+
+
+/** @name Position modification (recursive)
  *
+ * Change the current position of pointers in the dbuff and their children.
+ * @{
  */
-#define FR_DBUFF_RETURN(_func, ...) \
-do { \
-       ssize_t _slen = _func(__VA_ARGS__ ); \
-       if (_slen < 0) return _slen; \
-} while (0)
 
 /** Update the position of p in a list of dbuffs
  *
@@ -371,35 +370,126 @@ _fr_dbuff_set(_dst, \
                        size_t          : ((_dst)->p += (uintptr_t)(_src)) \
              ))
 
-/** Advance position in dbuff by N bytes without sanity checks
- *
- * @note Do not call this function directly.
- */
-static inline ssize_t CC_HINT(nonnull) _fr_dbuff_advance(fr_dbuff_t *dbuff, size_t inlen)
-{
-       dbuff->p += inlen;
-
-       return dbuff->adv_parent && dbuff->parent ? _fr_dbuff_advance(dbuff->parent, inlen) : (ssize_t)inlen;
-}
-
 /** Advance position in dbuff by N bytes
  *
  * @param[in] dbuff    to advance.
- * @param[in] inlen    How much to advance dbuff by.
+ * @param[in] n                How much to advance dbuff by.
  * @return
  *     - 0     not advanced.
  *     - >0    the number of bytes the dbuff was advanced by.
  *     - <0    the number of bytes required to complete the copy.
  */
-static inline ssize_t fr_dbuff_advance(fr_dbuff_t *dbuff, size_t inlen)
+static inline ssize_t fr_dbuff_advance(fr_dbuff_t *dbuff, size_t n)
 {
        size_t freespace = fr_dbuff_remaining(dbuff);
+       if (n > freespace) return -(n - freespace);
+       _fr_dbuff_set_recurse(dbuff, dbuff->p + n);
+       return n;
+}
+#define FR_DBUFF_ADVANCE_RETURN(_dbuff, _inlen) FR_DBUFF_RETURN(fr_dbuff_advance, _dbuff, _inlen)
 
-       if (inlen > freespace) return -(inlen - freespace);
+/** Reset the current position of the dbuff to the start of the string
+ *
+ */
+static inline uint8_t *fr_dbuff_set_to_start(fr_dbuff_t *dbuff)
+{
+       return dbuff->p = dbuff->start;
+}
+
+/** Reset the current position of the dbuff to the end of the string
+ *
+ */
+static inline uint8_t *fr_dbuff_set_to_end(fr_dbuff_t *dbuff)
+{
+       return dbuff->p = dbuff->end;
+}
+/** @} */
 
-       return _fr_dbuff_advance(dbuff, inlen);
+/** @name Add a marker to an dbuff
+ *
+ * Markers are used to indicate an area of the code is working at a particular
+ * point in a string buffer.
+ *
+ * If the dbuff is performing stream parsing, then markers are used to update
+ * any pointers to the buffer, as the data in the buffer is shifted to make
+ * room for new data from the stream.
+ *
+ * If the dbuff is being used to create strings, then the markers are updated
+ * if the buffer is re-allocated.
+ * @{
+ */
+/** Adds a new pointer to the beginning of the list of pointers to update
+ *
+ */
+static inline uint8_t *fr_dbuff_marker(fr_dbuff_marker_t *m, fr_dbuff_t *dbuff)
+{
+       m->next = dbuff->m;     /* Link into the head */
+       dbuff->m = m;
+
+       m->p = dbuff->p;        /* Set the current position in the dbuff */
+
+       return dbuff->p;
 }
-#define FR_DBUFF_ADVANCE_RETURN(_dbuff, _inlen) FR_DBUFF_RETURN(fr_dbuff_advance, _dbuff, _inlen)
+
+/** Trims the linked list backed to the specified pointer
+ *
+ * Pointers should be released in the inverse order to allocation.
+ *
+ * Alternatively the oldest pointer can be released, resulting in any newer pointer
+ * also being removed from the list.
+ *
+ * @param[in] m                to release.
+ */
+static inline void fr_dbuff_marker_release(fr_dbuff_marker_t *m, fr_dbuff_t *dbuff)
+{
+       dbuff->m = m->next;
+}
+
+/** Resets the position in an dbuff to specified marker
+ *
+ */
+static inline void fr_dbuff_set_to_marker(fr_dbuff_t *dbuff, fr_dbuff_marker_t *m)
+{
+       _fr_dbuff_set_recurse(dbuff, m->p);
+}
+
+/** Return the current position of the marker
+ *
+ */
+static inline uint8_t *fr_dbuff_marker_current(fr_dbuff_marker_t *m)
+{
+       return m->p;
+}
+
+/** How many free bytes remain in the buffer (calculated from marker)
+ *
+ */
+static inline size_t fr_dbuff_marker_remaining(fr_dbuff_t const *dbuff, fr_dbuff_marker_t *m)
+{
+       return dbuff->end - m->p;
+}
+
+/** How many bytes we've used in the buffer (calculated from marker)
+ *
+ */
+static inline size_t fr_dbuff_marker_used(fr_dbuff_t const *dbuff, fr_dbuff_marker_t *m)
+{
+       return m->p - dbuff->start;
+}
+/** @} */
+
+/** @name copy data to dbuff
+ * @{
+ */
+
+/** Generic wrapper macro to return if there's insufficient memory to satisfy the request on the dbuff
+ *
+ */
+#define FR_DBUFF_RETURN(_func, ...) \
+do { \
+       ssize_t _slen = _func(__VA_ARGS__ ); \
+       if (_slen < 0) return _slen; \
+} while (0)
 
 static inline ssize_t _fr_dbuff_memcpy_in(fr_dbuff_t *dbuff, uint8_t const *in, size_t inlen)
 {
@@ -411,16 +501,16 @@ static inline ssize_t _fr_dbuff_memcpy_in(fr_dbuff_t *dbuff, uint8_t const *in,
 
        memcpy(dbuff->p, in, inlen);
 
-       return _fr_dbuff_advance(dbuff, inlen);
+       return _fr_dbuff_set(dbuff, dbuff->p + inlen);
 }
 
-static inline ssize_t _fr_dbuff_memcpy_in_dbuff(fr_dbuff_t *out, fr_dbuff_t const *in, size_t inlen)
+static inline ssize_t _fr_dbuff_memcpy_in_dbuff(fr_dbuff_t *dbuff, fr_dbuff_t const *in, size_t inlen)
 {
        size_t outlen;
        fr_dbuff_t *in_m;
 
        if (inlen > fr_dbuff_remaining(in)) inlen = fr_dbuff_remaining(in);
-       outlen = fr_dbuff_remaining(out);
+       outlen = fr_dbuff_remaining(dbuff);
 
        /*
         *      If there's too many bytes, then
@@ -429,10 +519,10 @@ static inline ssize_t _fr_dbuff_memcpy_in_dbuff(fr_dbuff_t *out, fr_dbuff_t cons
         */
        if (inlen > outlen) return -(inlen - outlen);
 
-       (void)_fr_dbuff_memcpy_in(out, in->p, inlen);
+       (void)_fr_dbuff_memcpy_in(dbuff, in->p, inlen);
 
        memcpy(&in_m, &in, sizeof(in_m));       /* Stupid _Generic const issues */
-       return _fr_dbuff_advance(in_m, inlen);
+       return _fr_dbuff_set(in_m, dbuff->p + inlen);
 }
 
 /** Copy inlen bytes into the dbuff
@@ -487,23 +577,24 @@ static inline size_t _fr_dbuff_memcpy_in_partial(fr_dbuff_t *dbuff, uint8_t cons
 
        memcpy(dbuff->p, in, inlen);
 
-       return _fr_dbuff_advance(dbuff, inlen);
+       return _fr_dbuff_set(dbuff, dbuff->p + inlen);
 }
 
-static inline size_t _fr_dbuff_memcpy_in_dbuff_partial(fr_dbuff_t *out, fr_dbuff_t const *in, size_t inlen)
+static inline size_t _fr_dbuff_memcpy_in_dbuff_partial(fr_dbuff_t *dbuff, fr_dbuff_t const *in, size_t inlen)
 {
        size_t outlen;
        fr_dbuff_t *in_m;
 
        if (inlen > fr_dbuff_remaining(in)) inlen = fr_dbuff_remaining(in);
-       outlen = fr_dbuff_remaining(out);
+       outlen = fr_dbuff_remaining(dbuff);
 
        if (inlen > outlen) inlen = outlen;
 
-       (void)_fr_dbuff_memcpy_in(out, in->p, inlen);
+       (void)_fr_dbuff_memcpy_in(dbuff, in->p, inlen);
 
        memcpy(&in_m, &in, sizeof(in_m));       /* Stupid _Generic const issues */
-       return _fr_dbuff_advance(in_m, inlen);
+
+       return _fr_dbuff_set(in_m, dbuff->p + inlen);
 }
 
 /** Copy at most inlen bytes into the dbuff
@@ -579,101 +670,36 @@ static inline ssize_t fr_dbuff_memset(fr_dbuff_t *dbuff, uint8_t c, size_t inlen
 
        memset(dbuff->p, c, inlen);
 
-       return _fr_dbuff_advance(dbuff, inlen);
+       return _fr_dbuff_set(dbuff, dbuff->p + inlen);
 }
 #define FR_DBUFF_MEMSET_RETURN(_dbuff, _c, _inlen) FR_DBUFF_RETURN(fr_dbuff_memset, _dbuff, _c, _inlen)
 
-#define FR_DBUFF_NUM_IN_FUNC(_type) \
+#define FR_DBUFF_PARSE_INT_DEF(_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); \
-       return _fr_dbuff_advance(dbuff, sizeof(_type##_t)); \
+       return _fr_dbuff_set(dbuff, dbuff->p + 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    the number of bytes added to the dbuff (2).
- *     - <0    the number of bytes required
- */
-#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
- * @return
- *     - 0     no data set
- *     - >0    the number of bytes added to the dbuff (4).
- *     - <0    the number of bytes required
- */
-#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    the number of bytes added to the dbuff (8).
- *     - <0    the number of bytes required
- */
-#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    the number of bytes added to the dbuff (2).
- *     - <0    the number of bytes required
- */
-#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    the number of bytes added to the dbuff (4).
- *     - <0    the number of bytes required
- */
-#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    the number of bytes added to the dbuff (8).
- *     - <0    the number of bytes required
- */
-#define FR_DBUFF_INT64_IN_RETURN(_dbuff, _num) FR_DBUFF_RETURN(fr_dbuff_int64_in, _dbuff, _num)
-
-#define fr_dbuff_in(dbuff, value) \
-       _Generic((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) \
+FR_DBUFF_PARSE_INT_DEF(uint16)
+FR_DBUFF_PARSE_INT_DEF(uint32)
+FR_DBUFF_PARSE_INT_DEF(uint64)
+FR_DBUFF_PARSE_INT_DEF(int16)
+FR_DBUFF_PARSE_INT_DEF(int32)
+FR_DBUFF_PARSE_INT_DEF(int64)
+
+#define fr_dbuff_in(_dbuff, _value) \
+       _Generic((_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) \
        )
+#define FR_DBUFF_IN_RETURN(_dbuff, _value) FR_DBUFF_RETURN(fr_dbuff_in, _dbuff, _value)
 
 static inline ssize_t fr_dbuff_uint64v_in(fr_dbuff_t *dbuff, uint64_t num)
 {
@@ -686,79 +712,6 @@ static inline ssize_t fr_dbuff_uint64v_in(fr_dbuff_t *dbuff, uint64_t num)
 }
 /** @} */
 
-/** @name Add a marker to an dbuff
- *
- * Markers are used to indicate an area of the code is working at a particular
- * point in a string buffer.
- *
- * If the dbuff is performing stream parsing, then markers are used to update
- * any pointers to the buffer, as the data in the buffer is shifted to make
- * room for new data from the stream.
- *
- * If the dbuff is being used to create strings, then the markers are updated
- * if the buffer is re-allocated.
- * @{
- */
-/** Adds a new pointer to the beginning of the list of pointers to update
- *
- */
-static inline uint8_t *fr_dbuff_marker(fr_dbuff_marker_t *m, fr_dbuff_t *dbuff)
-{
-       m->next = dbuff->m;     /* Link into the head */
-       dbuff->m = m;
-
-       m->p = dbuff->p;        /* Set the current position in the dbuff */
-
-       return dbuff->p;
-}
-
-/** Trims the linked list backed to the specified pointer
- *
- * Pointers should be released in the inverse order to allocation.
- *
- * Alternatively the oldest pointer can be released, resulting in any newer pointer
- * also being removed from the list.
- *
- * @param[in] m                to release.
- */
-static inline void fr_dbuff_marker_release(fr_dbuff_marker_t *m, fr_dbuff_t *dbuff)
-{
-       dbuff->m = m->next;
-}
-
-/** Resets the position in an dbuff to specified marker
- *
- */
-static inline void fr_dbuff_set_to_marker(fr_dbuff_t *dbuff, fr_dbuff_marker_t *m)
-{
-       _fr_dbuff_set_recurse(dbuff, m->p);
-}
-
-/** Return the current position of the marker
- *
- */
-static inline uint8_t *fr_dbuff_marker_current(fr_dbuff_marker_t *m)
-{
-       return m->p;
-}
-
-/** How many free bytes remain in the buffer (calculated from marker)
- *
- */
-static inline size_t fr_dbuff_marker_remaining(fr_dbuff_t const *dbuff, fr_dbuff_marker_t *m)
-{
-       return dbuff->end - m->p;
-}
-
-/** How many bytes we've used in the buffer (calculated from marker)
- *
- */
-static inline size_t fr_dbuff_marker_used(fr_dbuff_t const *dbuff, fr_dbuff_marker_t *m)
-{
-       return m->p - dbuff->start;
-}
-/** @} */
-
 #ifdef __cplusplus
 }
 #endif
index 0e05e6de26a33c06be0398c5508980ed460cea0b..67c5001039ca3a43cd86f5076d3d9f0d8e68980d 100644 (file)
@@ -342,7 +342,7 @@ size_t fr_sbuff_out_bstrncpy_until(char *out, size_t outlen, fr_sbuff_t *in, siz
  *     - 0 no bytes copied.  Examine err.
  *     - >0 the number of bytes copied.
  */
-#define PARSE_INT_DEF(_name, _type, _min, _max, _max_char) \
+#define SBUFF_PARSE_INT_DEF(_name, _type, _min, _max, _max_char) \
 size_t fr_sbuff_out_##_name(fr_sbuff_parse_error_t *err, _type *out, fr_sbuff_t *in, bool no_trailing) \
 { \
        char            buff[_max_char + 1]; \
@@ -380,10 +380,10 @@ size_t fr_sbuff_out_##_name(fr_sbuff_parse_error_t *err, _type *out, fr_sbuff_t
        return end - buff; \
 }
 
-PARSE_INT_DEF(int8, int8_t, INT8_MIN, INT8_MAX, 2)
-PARSE_INT_DEF(int16, int16_t, INT16_MIN, INT16_MAX, 6)
-PARSE_INT_DEF(int32, int32_t, INT32_MIN, INT32_MAX, 11)
-PARSE_INT_DEF(int64, int64_t, INT64_MIN, INT64_MAX, 20)
+SBUFF_PARSE_INT_DEF(int8, int8_t, INT8_MIN, INT8_MAX, 2)
+SBUFF_PARSE_INT_DEF(int16, int16_t, INT16_MIN, INT16_MAX, 6)
+SBUFF_PARSE_INT_DEF(int32, int32_t, INT32_MIN, INT32_MAX, 11)
+SBUFF_PARSE_INT_DEF(int64, int64_t, INT64_MIN, INT64_MAX, 20)
 
 /** Used to define a number parsing functions for singed integers
  *
@@ -394,7 +394,7 @@ PARSE_INT_DEF(int64, int64_t, INT64_MIN, INT64_MAX, 20)
  *                     Can't use stringify because of width modifiers like 'u'
  *                     used in <stdint.h>.
  */
-#define PARSE_UINT_DEF(_name, _type, _max, _max_char) \
+#define SBUFF_PARSE_UINT_DEF(_name, _type, _max, _max_char) \
 size_t fr_sbuff_out_##_name(fr_sbuff_parse_error_t *err, _type *out, fr_sbuff_t *in, bool no_trailing) \
 { \
        char                    buff[_max_char + 1]; \
@@ -428,10 +428,10 @@ size_t fr_sbuff_out_##_name(fr_sbuff_parse_error_t *err, _type *out, fr_sbuff_t
        return end - buff; \
 }
 
-PARSE_UINT_DEF(uint8, uint8_t, UINT8_MAX, 1)
-PARSE_UINT_DEF(uint16, uint16_t, UINT16_MAX, 5)
-PARSE_UINT_DEF(uint32, uint32_t, UINT32_MAX, 10)
-PARSE_UINT_DEF(uint64, uint64_t, UINT64_MAX, 20)
+SBUFF_PARSE_UINT_DEF(uint8, uint8_t, UINT8_MAX, 1)
+SBUFF_PARSE_UINT_DEF(uint16, uint16_t, UINT16_MAX, 5)
+SBUFF_PARSE_UINT_DEF(uint32, uint32_t, UINT32_MAX, 10)
+SBUFF_PARSE_UINT_DEF(uint64, uint64_t, UINT64_MAX, 20)
 
 static bool float_chars[UINT8_MAX + 1] = {
        ['0'] = true, ['1'] = true, ['2'] = true, ['3'] = true, ['4'] = true,
@@ -448,7 +448,7 @@ static bool float_chars[UINT8_MAX + 1] = {
  *                     Can't use stringify because of width modifiers like 'u'
  *                     used in <stdint.h>.
  */
-#define PARSE_FLOAT_DEF(_name, _type, _func, _max_char) \
+#define SBUFF_PARSE_FLOAT_DEF(_name, _type, _func, _max_char) \
 size_t fr_sbuff_out_##_name(fr_sbuff_parse_error_t *err, _type *out, fr_sbuff_t *in, bool no_trailing) \
 { \
        char            buffer[_max_char + 1]; \
@@ -477,8 +477,8 @@ size_t fr_sbuff_out_##_name(fr_sbuff_parse_error_t *err, _type *out, fr_sbuff_t
        return fr_sbuff_advance(in, end - buffer); \
 }
 
-PARSE_FLOAT_DEF(float32, float, strtof, 100);
-PARSE_FLOAT_DEF(float64, double, strtod, 100);
+SBUFF_PARSE_FLOAT_DEF(float32, float, strtof, 100);
+SBUFF_PARSE_FLOAT_DEF(float64, double, strtod, 100);
 
 /** Copy bytes into the sbuff up to the first \0
  *
index 4fba9b39679f2fb01cbe0043843b66ad33510566..d8297932ffb78a100b7615a167ac498beed88dd8 100644 (file)
@@ -204,6 +204,222 @@ do { \
 
 /** @} */
 
+/** @name Accessors
+ *
+ * Caching the values of these pointers or the pointer values from the sbuff
+ * directly is strongly discouraged as they can become invalidated during
+ * stream parsing or when printing to an auto-expanding buffer.
+ *
+ * These functions should only be used to pass sbuff pointers into 3rd party
+ * APIs.
+ */
+static inline char *fr_sbuff_start(fr_sbuff_t *sbuff)
+{
+       return sbuff->start;
+}
+
+static inline char *fr_sbuff_current(fr_sbuff_t *sbuff)
+{
+       return sbuff->p;
+}
+
+static inline char *fr_sbuff_end(fr_sbuff_t *sbuff)
+{
+       return sbuff->end;
+}
+/** @} */
+
+/** @name Position modification (recursive)
+ *
+ * Change the current position of pointers in the sbuff and their children.
+ * @{
+ */
+
+/** Update the position of p in a list of sbuffs
+ *
+ * @note Do not call directly.
+ */
+static inline void _fr_sbuff_set_recurse(fr_sbuff_t *sbuff, char const *p)
+{
+       sbuff->p_i = p;
+       if (sbuff->adv_parent && sbuff->parent) _fr_sbuff_set_recurse(sbuff->parent, p);
+}
+
+/** Advance position in sbuff by N bytes
+ *
+ * @param[in] sbuff    to advance.
+ * @param[in] n                How much to advance sbuff by.
+ * @return
+ *     - 0     not advanced.
+ *     - >0    the number of bytes the sbuff was advanced by.
+ *     - <0    the number of bytes required to complete the advancement
+ */
+static inline ssize_t fr_sbuff_advance(fr_sbuff_t *sbuff, size_t n)
+{
+       size_t freespace = fr_sbuff_remaining(sbuff);
+       if (n > freespace) return -(n - freespace);
+       _fr_sbuff_set_recurse(sbuff, sbuff->p + n);
+       return n;
+}
+#define FR_SBUFF_ADVANCE_RETURN(_sbuff, _n) FR_SBUFF_RETURN(fr_sbuff_advance, _sbuff, _n)
+
+/** Set a new position for 'p' in an sbuff
+ *
+ * @param[out] sbuff   sbuff to set a position in.
+ * @param[in] p                Position to set.
+ * @return
+ *     - 0     not advanced.
+ *     - >0    the number of bytes the sbuff was advanced by.
+ *     - <0    the number of bytes required to complete the advancement
+ */
+static inline ssize_t _fr_sbuff_set(fr_sbuff_t *sbuff, char const *p)
+{
+       char const *c;
+
+       if (unlikely(p > sbuff->end)) return -(p - sbuff->end);
+       if (unlikely(p < sbuff->start)) return 0;
+
+       c = sbuff->p;
+       _fr_sbuff_set_recurse(sbuff, p);
+
+       return p - c;
+}
+
+/** Set the position in a sbuff using another sbuff, a char pointer, or a length
+ *
+ * @param[out] _dst    sbuff to advance.
+ * @param[in] _src     An sbuff, char pointer, or length value to advance
+ *                     _dst by.
+ * @return
+ *     - 0     not advanced.
+ *     - >0    the number of bytes the sbuff was advanced by.
+ *     - <0    the number of bytes required to complete the advancement
+ */
+#define fr_sbuff_set(_dst, _src) \
+_fr_sbuff_set(_dst, \
+             _Generic(_src, \
+                       fr_sbuff_t *    : (_src)->p, \
+                       char const *    : (_src), \
+                       char *          : (_src), \
+                       size_t          : ((_dst)->p += (uintptr_t)(_src)) \
+             ))
+
+
+/** Reset the current position of the sbuff to the start of the string
+ *
+ */
+static inline void fr_sbuff_set_to_start(fr_sbuff_t *sbuff)
+{
+       _fr_sbuff_set_recurse(sbuff, sbuff->start);
+}
+
+/** Reset the current position of the sbuff to the end of the string
+ *
+ */
+static inline void fr_sbuff_set_to_end(fr_sbuff_t *sbuff)
+{
+       _fr_sbuff_set_recurse(sbuff, sbuff->end);
+}
+/** @} */
+
+/** @name Add a marker to an sbuff
+ *
+ * Markers are used to indicate an area of the code is working at a particular
+ * point in a string buffer.
+ *
+ * If the sbuff is performing stream parsing, then markers are used to update
+ * any pointers to the buffer, as the data in the buffer is shifted to make
+ * room for new data from the stream.
+ *
+ * If the sbuff is being used to create strings, then the markers are updated
+ * if the buffer is re-allocated.
+ * @{
+ */
+/** Adds a new pointer to the beginning of the list of pointers to update
+ *
+ */
+static inline char *fr_sbuff_marker(fr_sbuff_marker_t *m, fr_sbuff_t *sbuff)
+{
+       m->next = sbuff->m;     /* Link into the head */
+       sbuff->m = m;
+
+       m->p = sbuff->p;        /* Set the current position in the sbuff */
+
+       return sbuff->p;
+}
+
+/** Trims the linked list backed to the specified pointer
+ *
+ * Pointers should be released in the inverse order to allocation.
+ *
+ * Alternatively the oldest pointer can be released, resulting in any newer pointer
+ * also being removed from the list.
+ *
+ * @param[in] m                to release.
+ */
+static inline void fr_sbuff_marker_release(fr_sbuff_marker_t *m, fr_sbuff_t *sbuff)
+{
+       if (unlikely(sbuff->m != m)) return;
+       sbuff->m = m->next;
+}
+
+/** Resets the position in an sbuff to specified marker
+ *
+ */
+static inline void fr_sbuff_set_to_marker(fr_sbuff_t *sbuff, fr_sbuff_marker_t *m)
+{
+       _fr_sbuff_set_recurse(sbuff, m->p);
+}
+
+/** Return the current position of the marker
+ *
+ */
+static inline char *fr_sbuff_marker_current(fr_sbuff_marker_t *m)
+{
+       return m->p;
+}
+
+/** How many free bytes remain in the buffer (calculated from marker)
+ *
+ */
+static inline size_t fr_sbuff_marker_remaining(fr_sbuff_t const *sbuff, fr_sbuff_marker_t *m)
+{
+       return sbuff->end - m->p;
+}
+
+/** How many bytes we've used in the buffer (calculated from marker)
+ *
+ */
+static inline size_t fr_sbuff_marker_used(fr_sbuff_t const *sbuff, fr_sbuff_marker_t *m)
+{
+       return m->p - sbuff->start;
+}
+/** @} */
+
+/** @name Position modification (non-recursive)
+ *
+ * Change the current position of pointers in the sbuff
+ * @{
+ */
+
+/** Set the start pointer to the current value of p
+ *
+ */
+static inline void fr_sbuff_trim_start(fr_sbuff_t *sbuff)
+{
+       sbuff->start = sbuff->p;
+}
+
+/** Set the end pointer to the current value of p
+ *
+ */
+static inline void fr_sbuff_trim_end(fr_sbuff_t *sbuff)
+{
+       sbuff->end = sbuff->p;
+}
+
+/** @} */
+
 /** @name Copy/print data to an sbuff
  *
  * These functions are typically used for printing.
@@ -483,226 +699,6 @@ static inline bool fr_sbuff_is_space(fr_sbuff_t *sbuff)
 }
 /** @} */
 
-/** @name Sbuff position manipulation
- * @{
- */
-
-/** @name Accessors
- *
- * Caching the values of these pointers or the pointer values from the sbuff
- * directly is strongly discouraged as they can become invalidated during
- * stream parsing or when printing to an auto-expanding buffer.
- *
- * These functions should only be used to pass sbuff pointers into 3rd party
- * APIs.
- */
-static inline char *fr_sbuff_start(fr_sbuff_t *sbuff)
-{
-       return sbuff->start;
-}
-
-static inline char *fr_sbuff_current(fr_sbuff_t *sbuff)
-{
-       return sbuff->p;
-}
-
-static inline char *fr_sbuff_end(fr_sbuff_t *sbuff)
-{
-       return sbuff->end;
-}
-/** @} */
-
-/** @name Position modification (recursive)
- *
- * Change the current position of pointers in the sbuff and their children.
- * @{
- */
-
-/** Update the position of p in a list of sbuffs
- *
- * @note Do not call directly.
- */
-static inline void _fr_sbuff_set_recurse(fr_sbuff_t *sbuff, char const *p)
-{
-       sbuff->p_i = p;
-       if (sbuff->adv_parent && sbuff->parent) _fr_sbuff_set_recurse(sbuff->parent, p);
-}
-
-/** Advance position in sbuff by N bytes
- *
- * @param[in] sbuff    to advance.
- * @param[in] n                How much to advance sbuff by.
- * @return
- *     - 0     not advanced.
- *     - >0    the number of bytes the sbuff was advanced by.
- *     - <0    the number of bytes required to complete the advancement
- */
-static inline ssize_t fr_sbuff_advance(fr_sbuff_t *sbuff, size_t n)
-{
-       size_t freespace = fr_sbuff_remaining(sbuff);
-       if (n > freespace) return -(n - freespace);
-       _fr_sbuff_set_recurse(sbuff, sbuff->p + n);
-       return n;
-}
-#define FR_SBUFF_ADVANCE_RETURN(_sbuff, _n) FR_SBUFF_RETURN(fr_sbuff_advance, _sbuff, _n)
-
-/** Set a new position for 'p' in an sbuff
- *
- * @param[out] sbuff   sbuff to set a position in.
- * @param[in] p                Position to set.
- * @return
- *     - 0     not advanced.
- *     - >0    the number of bytes the sbuff was advanced by.
- *     - <0    the number of bytes required to complete the advancement
- */
-static inline ssize_t _fr_sbuff_set(fr_sbuff_t *sbuff, char const *p)
-{
-       char const *c;
-
-       if (unlikely(p > sbuff->end)) return -(p - sbuff->end);
-       if (unlikely(p < sbuff->start)) return 0;
-
-       c = sbuff->p;
-       _fr_sbuff_set_recurse(sbuff, p);
-
-       return p - c;
-}
-
-/** Set the position in a sbuff using another sbuff, a char pointer, or a length
- *
- * @param[out] _dst    sbuff to advance.
- * @param[in] _src     An sbuff, char pointer, or length value to advance
- *                     _dst by.
- * @return
- *     - 0     not advanced.
- *     - >0    the number of bytes the sbuff was advanced by.
- *     - <0    the number of bytes required to complete the advancement
- */
-#define fr_sbuff_set(_dst, _src) \
-_fr_sbuff_set(_dst, \
-             _Generic(_src, \
-                       fr_sbuff_t *    : (_src)->p, \
-                       char const *    : (_src), \
-                       char *          : (_src), \
-                       size_t          : ((_dst)->p += (uintptr_t)(_src)) \
-             ))
-
-
-/** Reset the current position of the sbuff to the start of the string
- *
- */
-static inline void fr_sbuff_set_to_start(fr_sbuff_t *sbuff)
-{
-       _fr_sbuff_set_recurse(sbuff, sbuff->start);
-}
-
-/** Reset the current position of the sbuff to the end of the string
- *
- */
-static inline void fr_sbuff_set_to_end(fr_sbuff_t *sbuff)
-{
-       _fr_sbuff_set_recurse(sbuff, sbuff->end);
-}
-/** @} */
-
-/** @name Add a marker to an sbuff
- *
- * Markers are used to indicate an area of the code is working at a particular
- * point in a string buffer.
- *
- * If the sbuff is performing stream parsing, then markers are used to update
- * any pointers to the buffer, as the data in the buffer is shifted to make
- * room for new data from the stream.
- *
- * If the sbuff is being used to create strings, then the markers are updated
- * if the buffer is re-allocated.
- * @{
- */
-/** Adds a new pointer to the beginning of the list of pointers to update
- *
- */
-static inline char *fr_sbuff_marker(fr_sbuff_marker_t *m, fr_sbuff_t *sbuff)
-{
-       m->next = sbuff->m;     /* Link into the head */
-       sbuff->m = m;
-
-       m->p = sbuff->p;        /* Set the current position in the sbuff */
-
-       return sbuff->p;
-}
-
-/** Trims the linked list backed to the specified pointer
- *
- * Pointers should be released in the inverse order to allocation.
- *
- * Alternatively the oldest pointer can be released, resulting in any newer pointer
- * also being removed from the list.
- *
- * @param[in] m                to release.
- */
-static inline void fr_sbuff_marker_release(fr_sbuff_marker_t *m, fr_sbuff_t *sbuff)
-{
-       if (unlikely(sbuff->m != m)) return;
-       sbuff->m = m->next;
-}
-
-/** Resets the position in an sbuff to specified marker
- *
- */
-static inline void fr_sbuff_set_to_marker(fr_sbuff_t *sbuff, fr_sbuff_marker_t *m)
-{
-       _fr_sbuff_set_recurse(sbuff, m->p);
-}
-
-/** Return the current position of the marker
- *
- */
-static inline char *fr_sbuff_marker_current(fr_sbuff_marker_t *m)
-{
-       return m->p;
-}
-
-/** How many free bytes remain in the buffer (calculated from marker)
- *
- */
-static inline size_t fr_sbuff_marker_remaining(fr_sbuff_t const *sbuff, fr_sbuff_marker_t *m)
-{
-       return sbuff->end - m->p;
-}
-
-/** How many bytes we've used in the buffer (calculated from marker)
- *
- */
-static inline size_t fr_sbuff_marker_used(fr_sbuff_t const *sbuff, fr_sbuff_marker_t *m)
-{
-       return m->p - sbuff->start;
-}
-/** @} */
-
-/** @name Position modification (non-recursive)
- *
- * Change the current position of pointers in the sbuff
- * @{
- */
-
-/** Set the start pointer to the current value of p
- *
- */
-static inline void fr_sbuff_trim_start(fr_sbuff_t *sbuff)
-{
-       sbuff->start = sbuff->p;
-}
-
-/** Set the end pointer to the current value of p
- *
- */
-static inline void fr_sbuff_trim_end(fr_sbuff_t *sbuff)
-{
-       sbuff->end = sbuff->p;
-}
-
-/** @} */
-
 #ifdef __cplusplus
 }
 #endif
index 68914fd7752fb4956ac43e369635acd2b658fbba..cd5199c04f82cdf657035586c3ad982ebbf1a697 100644 (file)
@@ -1231,7 +1231,7 @@ static ssize_t encode_vsa_hdr(fr_dbuff_t *dbuff,
                return PAIR_ENCODE_FATAL_ERROR;
        }
 
-       FR_DBUFF_UINT32_IN_RETURN(&work_dbuff, da->attr);       /* Copy in the 32bit vendor ID */
+       FR_DBUFF_IN_RETURN(&work_dbuff, (uint32_t)da->attr);    /* Copy in the 32bit vendor ID */
 
        len = encode_vendor_attr_hdr(&FR_DBUFF_MAX(&work_dbuff, 255 - 6), da_stack, depth, cursor, encoder_ctx);
        if (len < 0) return len;