/* Ensures that 'b' has room for at least 'size' bytes at its head, * reallocating and copying its data if necessary. Its tailroom, if any, is * preserved. */ void ofpbuf_prealloc_headroom(struct ofpbuf *b, size_t size) { if (size > ofpbuf_headroom(b)) { ofpbuf_resize__(b, MAX(size, 64), ofpbuf_tailroom(b)); } }
/* Trims the size of 'b' to fit its actual content, reducing its tailroom to * 0. Its headroom, if any, is preserved. */ void ofpbuf_trim(struct ofpbuf *b) { if (ofpbuf_tailroom(b) > 0) { ofpbuf_resize_tailroom__(b, 0); } }
/* Trims the size of 'b' to fit its actual content, reducing its headroom and * tailroom to 0, if any. * * Buffers not obtained from malloc() are not resized, since that wouldn't save * any memory. * * Caller needs to updates 'b->header' and 'b->msg' so that they point to the * same locations in the data. (If they pointed into the tailroom or headroom * then they become invalid.) * */ void ofpbuf_trim(struct ofpbuf *b) { if (b->source == OFPBUF_MALLOC && (ofpbuf_headroom(b) || ofpbuf_tailroom(b))) { ofpbuf_resize__(b, 0, 0); } }
/* Returns a string that describes some of 'b''s metadata plus a hex dump of up * to 'maxbytes' from the start of the buffer. */ char * ofpbuf_to_string(const struct ofpbuf *b, size_t maxbytes) { struct ds s; ds_init(&s); ds_put_format(&s, "size=%"PRIu32", allocated=%"PRIu32", head=%"PRIuSIZE", tail=%"PRIuSIZE"\n", b->size, b->allocated, ofpbuf_headroom(b), ofpbuf_tailroom(b)); ds_put_hex_dump(&s, b->data, MIN(b->size, maxbytes), 0, false); return ds_cstr(&s); }
/* Shifts all of the data within the allocated space in 'b' by 'delta' bytes. * For example, a 'delta' of 1 would cause each byte of data to move one byte * forward (from address 'p' to 'p+1'), and a 'delta' of -1 would cause each * byte to move one byte backward (from 'p' to 'p-1'). * * If used, user must make sure the 'header' and 'msg' pointers are updated * after shifting. */ void ofpbuf_shift(struct ofpbuf *b, int delta) { ovs_assert(delta > 0 ? delta <= ofpbuf_tailroom(b) : delta < 0 ? -delta <= ofpbuf_headroom(b) : true); if (delta != 0) { char *dst = (char *) b->data + delta; memmove(dst, b->data, b->size); b->data = dst; } }
/* Shifts all of the data within the allocated space in 'b' by 'delta' bytes. * For example, a 'delta' of 1 would cause each byte of data to move one byte * forward (from address 'p' to 'p+1'), and a 'delta' of -1 would cause each * byte to move one byte backward (from 'p' to 'p-1'). */ void ofpbuf_shift(struct ofpbuf *b, int delta) { ovs_assert(delta > 0 ? delta <= ofpbuf_tailroom(b) : delta < 0 ? -delta <= ofpbuf_headroom(b) : true); if (delta != 0) { char *dst = (char *) ofpbuf_data(b) + delta; memmove(dst, ofpbuf_data(b), ofpbuf_size(b)); ofpbuf_set_data(b, dst); } }
static void ofpbuf_copy__(struct ofpbuf *b, uint8_t *new_base, size_t new_headroom, size_t new_tailroom) { const uint8_t *old_base = b->base; size_t old_headroom = ofpbuf_headroom(b); size_t old_tailroom = ofpbuf_tailroom(b); size_t copy_headroom = MIN(old_headroom, new_headroom); size_t copy_tailroom = MIN(old_tailroom, new_tailroom); memcpy(&new_base[new_headroom - copy_headroom], &old_base[old_headroom - copy_headroom], copy_headroom + b->size + copy_tailroom); }