]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
sbuff/dbuff: Add marker advance/set poistion functions
authorArran Cudbard-Bell <a.cudbardb@freeradius.org>
Mon, 20 Jul 2020 16:00:43 +0000 (12:00 -0400)
committerArran Cudbard-Bell <a.cudbardb@freeradius.org>
Mon, 20 Jul 2020 16:00:54 +0000 (12:00 -0400)
src/lib/util/dbuff.h
src/lib/util/sbuff.h

index e14079ea041c4ad2c4800f217bca13fe4318e231..ce421a309d6d98781393c9b0cf64b0a26d40ab9a 100644 (file)
@@ -336,15 +336,15 @@ static inline void _fr_dbuff_set_recurse(fr_dbuff_t *dbuff, uint8_t const *p)
  * @param[out] dbuff   dbuff to set a position in.
  * @param[in] p                Position to set.
  * @return
- *     - 0     not advanced.
- *     - >0    the number of bytes the dbuff was advanced by.
- *     - <0    the number of bytes required to complete the advancement
+ *     - 0     not advanced (p out of range).
+ *     - >0    the number of bytes the dbuff advanced by.
+ *     - <0    the number of bytes the dbuff retreated by.
  */
 static inline ssize_t _fr_dbuff_set(fr_dbuff_t *dbuff, uint8_t const *p)
 {
        uint8_t *c;
 
-       if (unlikely(p > dbuff->end)) return -(p - dbuff->end);
+       if (unlikely(p > dbuff->end)) return 0;
        if (unlikely(p < dbuff->start)) return 0;
 
        c = dbuff->p;
@@ -359,7 +359,7 @@ static inline ssize_t _fr_dbuff_set(fr_dbuff_t *dbuff, uint8_t const *p)
  * @param[in] _src     An dbuff, char pointer, or length value to advance
  *                     _dst by.
  * @return
- *     - 0     not advanced.
+ *     - 0     not advanced (_src out of range).
  *     - >0    the number of bytes the dbuff was advanced by.
  *     - <0    the number of bytes required to complete the advancement
  */
@@ -383,8 +383,7 @@ _fr_dbuff_set(_dst, \
  */
 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);
+       if ((dbuff->p + n) > dbuff->end) return 0;
        _fr_dbuff_set_recurse(dbuff, dbuff->p + n);
        return n;
 }
@@ -456,6 +455,42 @@ static inline void fr_dbuff_marker_release(fr_dbuff_marker_t *m)
 #endif
 }
 
+/** Change the position in the buffer a marker points to
+ *
+ * @param[in] m                marker to alter.
+ * @param[in] p                Position to set.
+ * @return
+ *     - 0 on failure (p out of range), marker position will remain unchanged.
+ *     - >0 the number of bytes the marker advanced.
+ *     - <0 the number of bytes the marker retreated.
+ */
+static inline ssize_t fr_dbuff_marker_set(fr_dbuff_marker_t *m, uint8_t const *p)
+{
+       fr_dbuff_t      *dbuff = m->parent;
+       uint8_t         *current = m->p;
+
+       if (unlikely(p > dbuff->end)) return 0;
+       if (unlikely(p < dbuff->start)) return 0;
+
+       m->p_i = p;
+
+       return p - current;
+}
+
+/** Change the position in the buffer a marker points to
+ *
+ * @param[in] m                marker to alter.
+ * @param[in] len      how much to advance the marker by.
+ * @return
+ *     - 0 on failure (p out of range), marker position will remain unchanged.
+ *     - >0 the number of bytes the marker advanced.
+ *     - <0 the number of bytes the marker retreated.
+ */
+static inline ssize_t fr_dbuff_marker_advance(fr_dbuff_marker_t *m, size_t len)
+{
+       return fr_dbuff_marker_set(m, m->p + len);
+}
+
 /** Resets the position in an dbuff to specified marker
  *
  */
index d16d39de705efd823b513bc61a4931f25ffd82da..f80dc0da4b15484ef67f429814e170c9f710f033 100644 (file)
@@ -43,7 +43,7 @@ extern "C" {
 typedef struct fr_sbuff_s fr_sbuff_t;
 typedef struct fr_sbuff_ptr_s fr_sbuff_marker_t;
 
-typedef int(*fr_sbuff_extend_t)(fr_sbuff_t *sbuff, void *uctx);
+typedef int(*fr_sbuff_extend_t)(fr_sbuff_t *sbuff, size_t req_extenison);
 
 struct fr_sbuff_ptr_s {
        union {
@@ -79,6 +79,8 @@ struct fr_sbuff_s {
                                                        ///< buffer changes.
        fr_sbuff_extend_t       extend;                 //!< Function to re-populate or extend
                                                        ///< the buffer.
+       size_t                  shifted;                //!< How many bytes this sbuff has been
+                                                       ///< shifted since its creation.
 };
 
 typedef enum {
@@ -184,6 +186,14 @@ static inline size_t fr_sbuff_used(fr_sbuff_t const *sbuff)
        return sbuff->p - sbuff->start;
 }
 
+/** How many bytes we've used in the buffer including shifts
+ *
+ */
+static inline size_t fr_sbuff_used_total(fr_sbuff_t const *sbuff)
+{
+       return (sbuff->p - sbuff->start) + sbuff->shifted;
+}
+
 /** How many bytes in the buffer total
  *
  */
@@ -264,8 +274,7 @@ static inline void _fr_sbuff_set_recurse(fr_sbuff_t *sbuff, char const *p)
  */
 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);
+       if ((sbuff->p + n) > sbuff->end) return 0;
        _fr_sbuff_set_recurse(sbuff, sbuff->p + n);
        return n;
 }
@@ -284,7 +293,7 @@ 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->end)) return 0;
        if (unlikely(p < sbuff->start)) return 0;
 
        c = sbuff->p;
@@ -379,6 +388,42 @@ static inline void fr_sbuff_marker_release(fr_sbuff_marker_t *m)
 #endif
 }
 
+/** Change the position in the buffer a marker points to
+ *
+ * @param[in] m                marker to alter.
+ * @param[in] p                Position to set.
+ * @return
+ *     - 0 on failure (p out of range), marker position will remain unchanged.
+ *     - >0 the number of bytes the marker advanced.
+ *     - <0 the number of bytes the marker retreated.
+ */
+static inline ssize_t fr_sbuff_marker_set(fr_sbuff_marker_t *m, char const *p)
+{
+       fr_sbuff_t      *sbuff = m->parent;
+       char            *current = m->p;
+
+       if (unlikely(p > sbuff->end)) return 0;
+       if (unlikely(p < sbuff->start)) return 0;
+
+       m->p_i = p;
+
+       return p - current;
+}
+
+/** Change the position in the buffer a marker points to
+ *
+ * @param[in] m                marker to alter.
+ * @param[in] len      how much to advance the marker by.
+ * @return
+ *     - 0 on failure (p out of range), marker position will remain unchanged.
+ *     - >0 the number of bytes the marker advanced.
+ *     - <0 the number of bytes the marker retreated.
+ */
+static inline ssize_t fr_sbuff_marker_advance(fr_sbuff_marker_t *m, size_t len)
+{
+       return fr_sbuff_marker_set(m, m->p + len);
+}
+
 /** Resets the position in an sbuff to specified marker
  *
  */
@@ -536,10 +581,10 @@ do { \
        if (_match_len) *(_match_len) = _match_len_tmp; \
 } while (0)
 
-size_t fr_sbuff_out_talloc_bstrncpy_exact(TALLOC_CTX *ctx, char **out, fr_sbuff_t *in, size_t len);
-
 size_t fr_sbuff_out_talloc_bstrncpy(TALLOC_CTX *ctx, char **out, fr_sbuff_t *in, size_t len);
 
+size_t fr_sbuff_out_talloc_bstrncpy_exact(TALLOC_CTX *ctx, char **out, fr_sbuff_t *in, size_t len);
+
 size_t fr_sbuff_out_talloc_bstrncpy_allowed(TALLOC_CTX *ctx, char **out, fr_sbuff_t *in, size_t len,
                                             bool const allowed_chars[static UINT8_MAX + 1]);