Send PORT_STATUS messages on port and link changes. Add ability to remotely enable...
[sliver-openvswitch.git] / lib / buffer.c
index dc9887a..47600e6 100644 (file)
@@ -31,6 +31,7 @@
  * derivatives without specific, written prior permission.
  */
 
+#include <config.h>
 #include "buffer.h"
 #include <assert.h>
 #include <stdlib.h>
@@ -50,8 +51,9 @@ buffer_use(struct buffer *b, void *base, size_t allocated)
     b->base = b->data = base;
     b->allocated = allocated;
     b->size = 0;
-    b->l2 = b->l3 = b->l4 = NULL;
+    b->l2 = b->l3 = b->l4 = b->l7 = NULL;
     b->next = NULL;
+    b->private = NULL;
 }
 
 /* Initializes 'b' as a buffer with an initial capacity of 'size' bytes. */
@@ -128,7 +130,7 @@ buffer_tailroom(struct buffer *b)
 /* Ensures that 'b' has room for at least 'size' bytes at its tail end,
  * reallocating and copying its data if necessary. */
 void
-buffer_reserve_tailroom(struct buffer *b, size_t size) 
+buffer_prealloc_tailroom(struct buffer *b, size_t size) 
 {
     if (size > buffer_tailroom(b)) {
         size_t new_allocated = b->allocated + MAX(size, 64);
@@ -148,11 +150,14 @@ buffer_reserve_tailroom(struct buffer *b, size_t size)
         if (b->l4) {
             b->l4 += base_delta;
         }
+        if (b->l7) {
+            b->l7 += base_delta;
+        }
     }
 }
 
 void
-buffer_reserve_headroom(struct buffer *b, size_t size) 
+buffer_prealloc_headroom(struct buffer *b, size_t size) 
 {
     assert(size <= buffer_headroom(b));
 }
@@ -164,7 +169,7 @@ void *
 buffer_put_uninit(struct buffer *b, size_t size) 
 {
     void *p;
-    buffer_reserve_tailroom(b, size);
+    buffer_prealloc_tailroom(b, size);
     p = buffer_tail(b);
     b->size += size;
     return p;
@@ -181,17 +186,35 @@ buffer_put(struct buffer *b, const void *p, size_t size)
     return dst;
 }
 
+/* Reserves 'size' bytes of headroom so that they can be later allocated with
+ * buffer_push_uninit() without reallocating the buffer. */
+void
+buffer_reserve(struct buffer *b, size_t size) 
+{
+    assert(!b->size);
+    buffer_prealloc_tailroom(b, size);
+    b->data += size;
+}
+
 void *
 buffer_push_uninit(struct buffer *b, size_t size) 
 {
-    buffer_reserve_headroom(b, size);
+    buffer_prealloc_headroom(b, size);
     b->data -= size;
     b->size += size;
     return b->data;
 }
 
+void *
+buffer_push(struct buffer *b, const void *p, size_t size) 
+{
+    void *dst = buffer_push_uninit(b, size);
+    memcpy(dst, p, size);
+    return dst;
+}
+
 /* If 'b' contains at least 'offset + size' bytes of data, returns a pointer to
- * byte 'offset'.  Otherwise, returns a null pointers. */
+ * byte 'offset'.  Otherwise, returns a null pointer. */
 void *
 buffer_at(const struct buffer *b, size_t offset, size_t size) 
 {
@@ -242,3 +265,11 @@ buffer_pull(struct buffer *b, size_t size)
     return data;
 }
 
+/* If 'b' has at least 'size' bytes of data, removes that many bytes from the
+ * head end of 'b' and returns the first byte removed.  Otherwise, returns a
+ * null pointer without modifying 'b'. */
+void *
+buffer_try_pull(struct buffer *b, size_t size) 
+{
+    return b->size >= size ? buffer_pull(b, size) : NULL;
+}