X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=lib%2Fofpbuf.c;h=91ea36303f9f2d06be06d412f730f3d14eb1a4c4;hb=e05924baf0c757b579eef2b3743130ade4b1a93c;hp=5693eefda6af036bb0f3ca797c98d2a5ac5a3cdf;hpb=d295e8e97acae13552a5b220d3fbcff8201064a2;p=openvswitch diff --git a/lib/ofpbuf.c b/lib/ofpbuf.c index 5693eefd..91ea3630 100644 --- a/lib/ofpbuf.c +++ b/lib/ofpbuf.c @@ -36,10 +36,21 @@ ofpbuf_use(struct ofpbuf *b, void *base, size_t allocated) b->allocated = allocated; b->size = 0; b->l2 = b->l3 = b->l4 = b->l7 = NULL; - b->next = NULL; + list_poison(&b->list_node); b->private_p = NULL; } +/* Initializes 'b' as an ofpbuf whose data starts at 'data' and continues for + * 'size' bytes. This is appropriate for an ofpbuf that will be used to + * inspect existing data, without moving it around or reallocating it, and + * generally without modifying it at all. */ +void +ofpbuf_use_const(struct ofpbuf *b, const void *data, size_t size) +{ + ofpbuf_use(b, (void *) data, size); + b->size = size; +} + /* Initializes 'b' as an empty ofpbuf with an initial capacity of 'size' * bytes. */ void @@ -75,12 +86,32 @@ ofpbuf_new(size_t size) return b; } +/* Creates and returns a new ofpbuf with an initial capacity of 'size + + * headroom' bytes, reserving the first 'headroom' bytes as headroom. */ +struct ofpbuf * +ofpbuf_new_with_headroom(size_t size, size_t headroom) +{ + struct ofpbuf *b = ofpbuf_new(size + headroom); + ofpbuf_reserve(b, headroom); + return b; +} + struct ofpbuf * ofpbuf_clone(const struct ofpbuf *buffer) { return ofpbuf_clone_data(buffer->data, buffer->size); } +/* Creates and returns a new ofpbuf whose data are copied from 'buffer'. The + * returned ofpbuf will additionally have 'headroom' bytes of headroom. */ +struct ofpbuf * +ofpbuf_clone_with_headroom(const struct ofpbuf *buffer, size_t headroom) +{ + struct ofpbuf *b = ofpbuf_new_with_headroom(buffer->size, headroom); + ofpbuf_put(b, buffer->data, buffer->size); + return b; +} + struct ofpbuf * ofpbuf_clone_data(const void *data, size_t size) { @@ -211,6 +242,33 @@ ofpbuf_put(struct ofpbuf *b, const void *p, size_t size) return dst; } +/* Parses as many pairs of hex digits as possible (possibly separated by + * spaces) from the beginning of 's', appending bytes for their values to 'b'. + * Returns the first character of 's' that is not the first of a pair of hex + * digits. If 'n' is nonnull, stores the number of bytes added to 'b' in + * '*n'. */ +char * +ofpbuf_put_hex(struct ofpbuf *b, const char *s, size_t *n) +{ + size_t initial_size = b->size; + for (;;) { + uint8_t byte; + bool ok; + + s += strspn(s, " "); + byte = hexits_value(s, 2, &ok); + if (!ok) { + if (n) { + *n = b->size - initial_size; + } + return (char *) s; + } + + ofpbuf_put(b, &byte, 1); + s += 2; + } +} + /* Reserves 'size' bytes of headroom so that they can be later allocated with * ofpbuf_push_uninit() without reallocating the ofpbuf. */ void @@ -324,3 +382,16 @@ ofpbuf_to_string(const struct ofpbuf *b, size_t maxbytes) ds_put_hex_dump(&s, b->data, MIN(b->size, maxbytes), 0, false); return ds_cstr(&s); } + +/* Removes each of the "struct ofpbuf"s on 'list' from the list and frees + * them. */ +void +ofpbuf_list_delete(struct list *list) +{ + struct ofpbuf *b, *next; + + LIST_FOR_EACH_SAFE (b, next, list_node, list) { + list_remove(&b->list_node); + ofpbuf_delete(b); + } +}