X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=lib%2Fofpbuf.c;h=29698dcd83beefdedb2ba985f4305e63a9eaa4d9;hb=541bc79f73add327072470c9bc3febb4195cdb3c;hp=7e9653600c2c881bbc67e657fe08fb6ac494733a;hpb=933369b1194bce82bffa8cc1ccfdf82782cc5cde;p=openvswitch diff --git a/lib/ofpbuf.c b/lib/ofpbuf.c index 7e965360..29698dcd 100644 --- a/lib/ofpbuf.c +++ b/lib/ofpbuf.c @@ -47,9 +47,9 @@ ofpbuf_use(struct ofpbuf *b, void *base, size_t allocated) /* Initializes 'b' as an empty ofpbuf that contains the 'allocated' bytes of * memory starting at 'base'. 'base' should point to a buffer on the stack. - * If 'b' is resized, new memory will be allocated with malloc() and 'base' - * will not be freed. This is useful when a small stack-allocated buffer is - * normally appropriate but sometimes it must be expanded. + * + * An ofpbuf operation that requires reallocating data will assert-fail if this + * function was used to initialize it. * * 'base' should be appropriately aligned. Using an array of uint32_t or * uint64_t for the buffer is a reasonable way to ensure appropriate alignment @@ -74,7 +74,7 @@ ofpbuf_use_stack(struct ofpbuf *b, void *base, size_t allocated) void ofpbuf_use_const(struct ofpbuf *b, const void *data, size_t size) { - ofpbuf_use__(b, (void *) data, size, OFPBUF_CONST); + ofpbuf_use__(b, (void *) data, size, OFPBUF_STACK); b->size = size; } @@ -129,7 +129,7 @@ ofpbuf_new_with_headroom(size_t size, size_t headroom) struct ofpbuf * ofpbuf_clone(const struct ofpbuf *buffer) { - return ofpbuf_clone_data(buffer->data, buffer->size); + return ofpbuf_clone_with_headroom(buffer, 0); } /* Creates and returns a new ofpbuf whose data are copied from 'buffer'. The @@ -137,8 +137,27 @@ ofpbuf_clone(const struct ofpbuf *buffer) struct ofpbuf * ofpbuf_clone_with_headroom(const struct ofpbuf *buffer, size_t headroom) { - return ofpbuf_clone_data_with_headroom(buffer->data, buffer->size, - headroom); + struct ofpbuf *new_buffer; + uintptr_t data_delta; + + new_buffer = ofpbuf_clone_data_with_headroom(buffer->data, buffer->size, + headroom); + data_delta = (char *) new_buffer->data - (char *) buffer->data; + + if (buffer->l2) { + new_buffer->l2 = (char *) buffer->l2 + data_delta; + } + if (buffer->l3) { + new_buffer->l3 = (char *) buffer->l3 + data_delta; + } + if (buffer->l4) { + new_buffer->l4 = (char *) buffer->l4 + data_delta; + } + if (buffer->l7) { + new_buffer->l7 = (char *) buffer->l7 + data_delta; + } + + return new_buffer; } /* Creates and returns a new ofpbuf that initially contains a copy of the @@ -225,12 +244,6 @@ ofpbuf_resize__(struct ofpbuf *b, size_t new_headroom, size_t new_tailroom) break; case OFPBUF_STACK: - new_base = xmalloc(new_allocated); - ofpbuf_copy__(b, new_base, new_headroom, new_tailroom); - b->source = OFPBUF_MALLOC; - break; - - case OFPBUF_CONST: NOT_REACHED(); default: @@ -295,6 +308,16 @@ ofpbuf_trim(struct ofpbuf *b) } } +/* If 'b' is shorter than 'length' bytes, pads its tail out with zeros to that + * length. */ +void +ofpbuf_padto(struct ofpbuf *b, size_t length) +{ + if (b->size < length) { + ofpbuf_put_zeros(b, length - b->size); + } +} + /* Appends 'size' bytes of data to the tail end of 'b', reallocating and * copying its data if necessary. Returns a pointer to the first byte of the * new data, which is left uninitialized. */