/src/openvswitch/lib/ofpbuf.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2016 Nicira, Inc. |
3 | | * |
4 | | * Licensed under the Apache License, Version 2.0 (the "License"); |
5 | | * you may not use this file except in compliance with the License. |
6 | | * You may obtain a copy of the License at: |
7 | | * |
8 | | * http://www.apache.org/licenses/LICENSE-2.0 |
9 | | * |
10 | | * Unless required by applicable law or agreed to in writing, software |
11 | | * distributed under the License is distributed on an "AS IS" BASIS, |
12 | | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
13 | | * See the License for the specific language governing permissions and |
14 | | * limitations under the License. |
15 | | */ |
16 | | |
17 | | #include <config.h> |
18 | | #include "openvswitch/ofpbuf.h" |
19 | | #include <stdlib.h> |
20 | | #include <string.h> |
21 | | #include "openvswitch/dynamic-string.h" |
22 | | #include "util.h" |
23 | | |
24 | | static void |
25 | | ofpbuf_init__(struct ofpbuf *b, size_t allocated, enum ofpbuf_source source) |
26 | 0 | { |
27 | 0 | b->allocated = allocated; |
28 | 0 | b->source = source; |
29 | 0 | b->header = NULL; |
30 | 0 | b->msg = NULL; |
31 | 0 | ovs_list_poison(&b->list_node); |
32 | 0 | } |
33 | | |
34 | | static void |
35 | | ofpbuf_use__(struct ofpbuf *b, void *base, size_t allocated, size_t size, |
36 | | enum ofpbuf_source source) |
37 | 0 | { |
38 | 0 | b->base = base; |
39 | 0 | b->data = base; |
40 | 0 | b->size = size; |
41 | |
|
42 | 0 | ofpbuf_init__(b, allocated, source); |
43 | 0 | } |
44 | | |
45 | | /* Initializes 'b' as an empty ofpbuf that contains the 'allocated' bytes of |
46 | | * memory starting at 'base'. 'base' should be the first byte of a region |
47 | | * obtained from malloc(). It will be freed (with free()) if 'b' is resized or |
48 | | * freed. */ |
49 | | static void |
50 | | ofpbuf_use(struct ofpbuf *b, void *base, size_t allocated) |
51 | 0 | { |
52 | 0 | ofpbuf_use__(b, base, allocated, 0, OFPBUF_MALLOC); |
53 | 0 | } |
54 | | |
55 | | /* Converts ds into ofpbuf 'b'. 'b' contains the 'ds->allocated' bytes of |
56 | | * memory starting at 'ds->string'. 'ds' should not be modified any more. |
57 | | * The memory allocated for 'ds' will be freed (with free()) if 'b' is |
58 | | * resized or freed. */ |
59 | | void |
60 | | ofpbuf_use_ds(struct ofpbuf *b, const struct ds *ds) |
61 | 0 | { |
62 | 0 | ofpbuf_use__(b, ds->string, ds->allocated + 1, ds->length, OFPBUF_MALLOC); |
63 | 0 | } |
64 | | |
65 | | /* Initializes 'b' as an empty ofpbuf that contains the 'allocated' bytes of |
66 | | * memory starting at 'base'. 'base' should point to a buffer on the stack. |
67 | | * (Nothing actually relies on 'base' being allocated on the stack. It could |
68 | | * be static or malloc()'d memory. But stack space is the most common use |
69 | | * case.) |
70 | | * |
71 | | * 'base' should be appropriately aligned. Using an array of uint32_t or |
72 | | * uint64_t for the buffer is a reasonable way to ensure appropriate alignment |
73 | | * for 32- or 64-bit data. |
74 | | * |
75 | | * An ofpbuf operation that requires reallocating data will assert-fail if this |
76 | | * function was used to initialize it. Thus, one need not call ofpbuf_uninit() |
77 | | * on an ofpbuf initialized by this function (though doing so is harmless), |
78 | | * because it is guaranteed that 'b' does not own any heap-allocated memory. */ |
79 | | void |
80 | | ofpbuf_use_stack(struct ofpbuf *b, void *base, size_t allocated) |
81 | 0 | { |
82 | 0 | ofpbuf_use__(b, base, allocated, 0, OFPBUF_STACK); |
83 | 0 | } |
84 | | |
85 | | /* Initializes 'b' as an empty ofpbuf that contains the 'allocated' bytes of |
86 | | * memory starting at 'base'. 'base' should point to a buffer on the stack. |
87 | | * (Nothing actually relies on 'base' being allocated on the stack. It could |
88 | | * be static or malloc()'d memory. But stack space is the most common use |
89 | | * case.) |
90 | | * |
91 | | * 'base' should be appropriately aligned. Using an array of uint32_t or |
92 | | * uint64_t for the buffer is a reasonable way to ensure appropriate alignment |
93 | | * for 32- or 64-bit data. |
94 | | * |
95 | | * An ofpbuf operation that requires reallocating data will copy the provided |
96 | | * buffer into a malloc()'d buffer. Thus, it is wise to call ofpbuf_uninit() |
97 | | * on an ofpbuf initialized by this function, so that if it expanded into the |
98 | | * heap, that memory is freed. */ |
99 | | void |
100 | | ofpbuf_use_stub(struct ofpbuf *b, void *base, size_t allocated) |
101 | 0 | { |
102 | 0 | ofpbuf_use__(b, base, allocated, 0, OFPBUF_STUB); |
103 | 0 | } |
104 | | |
105 | | /* Initializes 'b' as an ofpbuf whose data starts at 'data' and continues for |
106 | | * 'size' bytes. This is appropriate for an ofpbuf that will be used to |
107 | | * inspect existing data, without moving it around or reallocating it, and |
108 | | * generally without modifying it at all. |
109 | | * |
110 | | * An ofpbuf operation that requires reallocating data will assert-fail if this |
111 | | * function was used to initialize it. */ |
112 | | void |
113 | | ofpbuf_use_const(struct ofpbuf *b, const void *data, size_t size) |
114 | 0 | { |
115 | 0 | ofpbuf_use__(b, CONST_CAST(void *, data), size, size, OFPBUF_STACK); |
116 | 0 | } |
117 | | |
118 | | /* Initializes 'b' as an ofpbuf whose data starts at 'data' and continues for |
119 | | * 'size' bytes. This is appropriate for an ofpbuf that will be mostly used to |
120 | | * inspect existing data, however, if needed, data may be occasionally changed. |
121 | | * |
122 | | * The first time the data is changed the provided buffer will be copied into |
123 | | * a malloc()'d buffer. Thus, it is wise to call ofpbuf_uninit() on an ofpbuf |
124 | | * initialized by this function, so that if it expanded into the heap, that |
125 | | * memory is freed. |
126 | | * |
127 | | * 'base' should be appropriately aligned. Using an array of uint32_t or |
128 | | * uint64_t for the buffer is a reasonable way to ensure appropriate alignment |
129 | | * for 32- or 64-bit data. */ |
130 | | void |
131 | | ofpbuf_use_data(struct ofpbuf *b, const void *data, size_t size) |
132 | 0 | { |
133 | 0 | ofpbuf_use__(b, CONST_CAST(void *, data), size, size, OFPBUF_STUB); |
134 | 0 | } |
135 | | |
136 | | /* Initializes 'b' as an empty ofpbuf with an initial capacity of 'size' |
137 | | * bytes. */ |
138 | | void |
139 | | ofpbuf_init(struct ofpbuf *b, size_t size) |
140 | 0 | { |
141 | 0 | ofpbuf_use(b, size ? xmalloc(size) : NULL, size); |
142 | 0 | } |
143 | | |
144 | | /* Frees memory that 'b' points to. */ |
145 | | void |
146 | | ofpbuf_uninit(struct ofpbuf *b) |
147 | 0 | { |
148 | 0 | if (b) { |
149 | 0 | if (b->source == OFPBUF_MALLOC) { |
150 | 0 | free(b->base); |
151 | 0 | } |
152 | 0 | } |
153 | 0 | } |
154 | | |
155 | | /* Frees memory that 'b' points to and allocates a new ofpbuf */ |
156 | | void |
157 | | ofpbuf_reinit(struct ofpbuf *b, size_t size) |
158 | 0 | { |
159 | 0 | ofpbuf_uninit(b); |
160 | 0 | ofpbuf_init(b, size); |
161 | 0 | } |
162 | | |
163 | | /* Creates and returns a new ofpbuf with an initial capacity of 'size' |
164 | | * bytes. */ |
165 | | struct ofpbuf * |
166 | | ofpbuf_new(size_t size) |
167 | 0 | { |
168 | 0 | struct ofpbuf *b = xmalloc(sizeof *b); |
169 | 0 | ofpbuf_init(b, size); |
170 | 0 | return b; |
171 | 0 | } |
172 | | |
173 | | /* Creates and returns a new ofpbuf with an initial capacity of 'size + |
174 | | * headroom' bytes, reserving the first 'headroom' bytes as headroom. */ |
175 | | struct ofpbuf * |
176 | | ofpbuf_new_with_headroom(size_t size, size_t headroom) |
177 | 0 | { |
178 | 0 | struct ofpbuf *b = ofpbuf_new(size + headroom); |
179 | 0 | ofpbuf_reserve(b, headroom); |
180 | 0 | return b; |
181 | 0 | } |
182 | | |
183 | | /* Creates and returns a new ofpbuf that initially contains a copy of the |
184 | | * 'buffer->size' bytes of data starting at 'buffer->data' with no headroom or |
185 | | * tailroom. */ |
186 | | struct ofpbuf * |
187 | | ofpbuf_clone(const struct ofpbuf *buffer) |
188 | 0 | { |
189 | 0 | return ofpbuf_clone_with_headroom(buffer, 0); |
190 | 0 | } |
191 | | |
192 | | /* Creates and returns a new ofpbuf whose data are copied from 'buffer'. The |
193 | | * returned ofpbuf will additionally have 'headroom' bytes of headroom. */ |
194 | | struct ofpbuf * |
195 | | ofpbuf_clone_with_headroom(const struct ofpbuf *b, size_t headroom) |
196 | 0 | { |
197 | 0 | struct ofpbuf *new_buffer; |
198 | |
|
199 | 0 | new_buffer = ofpbuf_clone_data_with_headroom(b->data, b->size, headroom); |
200 | 0 | if (b->header) { |
201 | 0 | ptrdiff_t header_offset = (char *) b->header - (char *) b->data; |
202 | |
|
203 | 0 | new_buffer->header = (char *) new_buffer->data + header_offset; |
204 | 0 | } |
205 | 0 | if (b->msg) { |
206 | 0 | ptrdiff_t msg_offset = (char *) b->msg - (char *) b->data; |
207 | |
|
208 | 0 | new_buffer->msg = (char *) new_buffer->data + msg_offset; |
209 | 0 | } |
210 | |
|
211 | 0 | return new_buffer; |
212 | 0 | } |
213 | | |
214 | | /* Creates and returns a new ofpbuf that initially contains a copy of the |
215 | | * 'size' bytes of data starting at 'data' with no headroom or tailroom. */ |
216 | | struct ofpbuf * |
217 | | ofpbuf_clone_data(const void *data, size_t size) |
218 | 0 | { |
219 | 0 | return ofpbuf_clone_data_with_headroom(data, size, 0); |
220 | 0 | } |
221 | | |
222 | | /* Creates and returns a new ofpbuf that initially contains 'headroom' bytes of |
223 | | * headroom followed by a copy of the 'size' bytes of data starting at |
224 | | * 'data'. */ |
225 | | struct ofpbuf * |
226 | | ofpbuf_clone_data_with_headroom(const void *data, size_t size, size_t headroom) |
227 | 0 | { |
228 | 0 | struct ofpbuf *b = ofpbuf_new_with_headroom(size, headroom); |
229 | 0 | ofpbuf_put(b, data, size); |
230 | 0 | return b; |
231 | 0 | } |
232 | | |
233 | | static void |
234 | | ofpbuf_copy__(struct ofpbuf *b, uint8_t *new_base, |
235 | | size_t new_headroom, size_t new_tailroom) |
236 | 0 | { |
237 | 0 | const uint8_t *old_base = b->base; |
238 | 0 | size_t old_headroom = ofpbuf_headroom(b); |
239 | 0 | size_t old_tailroom = ofpbuf_tailroom(b); |
240 | 0 | size_t copy_headroom = MIN(old_headroom, new_headroom); |
241 | 0 | size_t copy_tailroom = MIN(old_tailroom, new_tailroom); |
242 | |
|
243 | 0 | memcpy(&new_base[new_headroom - copy_headroom], |
244 | 0 | &old_base[old_headroom - copy_headroom], |
245 | 0 | copy_headroom + b->size + copy_tailroom); |
246 | 0 | } |
247 | | |
248 | | /* Reallocates 'b' so that it has exactly 'new_headroom' and 'new_tailroom' |
249 | | * bytes of headroom and tailroom, respectively. */ |
250 | | static void |
251 | | ofpbuf_resize__(struct ofpbuf *b, size_t new_headroom, size_t new_tailroom) |
252 | 0 | { |
253 | 0 | void *new_base, *new_data; |
254 | 0 | size_t new_allocated; |
255 | |
|
256 | 0 | new_allocated = new_headroom + b->size + new_tailroom; |
257 | |
|
258 | 0 | switch (b->source) { |
259 | 0 | case OFPBUF_MALLOC: |
260 | 0 | if (new_headroom == ofpbuf_headroom(b)) { |
261 | 0 | new_base = xrealloc(b->base, new_allocated); |
262 | 0 | } else { |
263 | 0 | new_base = xmalloc(new_allocated); |
264 | 0 | ofpbuf_copy__(b, new_base, new_headroom, new_tailroom); |
265 | 0 | free(b->base); |
266 | 0 | } |
267 | 0 | break; |
268 | | |
269 | 0 | case OFPBUF_STACK: |
270 | 0 | OVS_NOT_REACHED(); |
271 | | |
272 | 0 | case OFPBUF_STUB: |
273 | 0 | b->source = OFPBUF_MALLOC; |
274 | 0 | new_base = xmalloc(new_allocated); |
275 | 0 | ofpbuf_copy__(b, new_base, new_headroom, new_tailroom); |
276 | 0 | break; |
277 | | |
278 | 0 | default: |
279 | 0 | OVS_NOT_REACHED(); |
280 | 0 | } |
281 | | |
282 | 0 | b->allocated = new_allocated; |
283 | 0 | b->base = new_base; |
284 | |
|
285 | 0 | new_data = (char *) new_base + new_headroom; |
286 | 0 | if (b->data != new_data) { |
287 | 0 | if (b->header) { |
288 | 0 | ptrdiff_t header_offset = (char *) b->header - (char *) b->data; |
289 | |
|
290 | 0 | b->header = (char *) new_data + header_offset; |
291 | 0 | } |
292 | 0 | if (b->msg) { |
293 | 0 | ptrdiff_t msg_offset = (char *) b->msg - (char *) b->data; |
294 | |
|
295 | 0 | b->msg = (char *) new_data + msg_offset; |
296 | 0 | } |
297 | 0 | b->data = new_data; |
298 | 0 | } |
299 | 0 | } |
300 | | |
301 | | /* Ensures that 'b' has room for at least 'size' bytes at its tail end, |
302 | | * reallocating and copying its data if necessary. Its headroom, if any, is |
303 | | * preserved. */ |
304 | | void |
305 | | ofpbuf_prealloc_tailroom(struct ofpbuf *b, size_t size) |
306 | 0 | { |
307 | 0 | if (size > ofpbuf_tailroom(b)) { |
308 | 0 | ofpbuf_resize__(b, ofpbuf_headroom(b), MAX(size, 64)); |
309 | 0 | } |
310 | 0 | } |
311 | | |
312 | | /* Ensures that 'b' has room for at least 'size' bytes at its head, |
313 | | * reallocating and copying its data if necessary. Its tailroom, if any, is |
314 | | * preserved. */ |
315 | | void |
316 | | ofpbuf_prealloc_headroom(struct ofpbuf *b, size_t size) |
317 | 0 | { |
318 | 0 | if (size > ofpbuf_headroom(b)) { |
319 | 0 | ofpbuf_resize__(b, MAX(size, 64), ofpbuf_tailroom(b)); |
320 | 0 | } |
321 | 0 | } |
322 | | |
323 | | /* Trims the size of 'b' to fit its actual content, reducing its headroom and |
324 | | * tailroom to 0, if any. |
325 | | * |
326 | | * Buffers not obtained from malloc() are not resized, since that wouldn't save |
327 | | * any memory. |
328 | | * |
329 | | * Caller needs to updates 'b->header' and 'b->msg' so that they point to the |
330 | | * same locations in the data. (If they pointed into the tailroom or headroom |
331 | | * then they become invalid.) |
332 | | * |
333 | | */ |
334 | | void |
335 | | ofpbuf_trim(struct ofpbuf *b) |
336 | 0 | { |
337 | 0 | if (b->source == OFPBUF_MALLOC |
338 | 0 | && (ofpbuf_headroom(b) || ofpbuf_tailroom(b))) { |
339 | 0 | ofpbuf_resize__(b, 0, 0); |
340 | 0 | } |
341 | 0 | } |
342 | | |
343 | | /* Re-aligns the buffer data. Relies on malloc() to ensure proper alignment. |
344 | | * |
345 | | * This function should not be called for buffers of type OFPBUF_STACK. |
346 | | */ |
347 | | void |
348 | | ofpbuf_align(struct ofpbuf *b) |
349 | 0 | { |
350 | 0 | switch (b->source) { |
351 | 0 | case OFPBUF_MALLOC: |
352 | 0 | case OFPBUF_STUB: |
353 | | /* Resizing 'b' always reallocates the buffer, ensuring proper |
354 | | * alignment. |
355 | | */ |
356 | 0 | ofpbuf_resize__(b, 0, 0); |
357 | 0 | break; |
358 | 0 | case OFPBUF_STACK: |
359 | 0 | OVS_NOT_REACHED(); |
360 | 0 | break; |
361 | 0 | } |
362 | 0 | } |
363 | | |
364 | | /* If 'b' is shorter than 'length' bytes, pads its tail out with zeros to that |
365 | | * length. */ |
366 | | void |
367 | | ofpbuf_padto(struct ofpbuf *b, size_t length) |
368 | 0 | { |
369 | 0 | if (b->size < length) { |
370 | 0 | ofpbuf_put_zeros(b, length - b->size); |
371 | 0 | } |
372 | 0 | } |
373 | | |
374 | | /* Shifts all of the data within the allocated space in 'b' by 'delta' bytes. |
375 | | * For example, a 'delta' of 1 would cause each byte of data to move one byte |
376 | | * forward (from address 'p' to 'p+1'), and a 'delta' of -1 would cause each |
377 | | * byte to move one byte backward (from 'p' to 'p-1'). |
378 | | * |
379 | | * If used, user must make sure the 'header' and 'msg' pointers are updated |
380 | | * after shifting. |
381 | | */ |
382 | | void |
383 | | ofpbuf_shift(struct ofpbuf *b, int delta) |
384 | 0 | { |
385 | 0 | ovs_assert(delta > 0 ? delta <= ofpbuf_tailroom(b) |
386 | 0 | : delta < 0 ? -delta <= ofpbuf_headroom(b) |
387 | 0 | : true); |
388 | |
|
389 | 0 | if (delta != 0) { |
390 | 0 | char *dst = (char *) b->data + delta; |
391 | 0 | memmove(dst, b->data, b->size); |
392 | 0 | b->data = dst; |
393 | 0 | } |
394 | 0 | } |
395 | | |
396 | | /* Appends 'size' bytes of data to the tail end of 'b', reallocating and |
397 | | * copying its data if necessary. Returns a pointer to the first byte of the |
398 | | * new data, which is left uninitialized. */ |
399 | | void * |
400 | | ofpbuf_put_uninit(struct ofpbuf *b, size_t size) |
401 | 0 | { |
402 | 0 | void *p; |
403 | 0 | ofpbuf_prealloc_tailroom(b, size); |
404 | 0 | p = ofpbuf_tail(b); |
405 | 0 | b->size += size; |
406 | 0 | return p; |
407 | 0 | } |
408 | | |
409 | | /* Appends 'size' zeroed bytes to the tail end of 'b'. Data in 'b' is |
410 | | * reallocated and copied if necessary. Returns a pointer to the first byte of |
411 | | * the data's location in the ofpbuf. */ |
412 | | void * |
413 | | ofpbuf_put_zeros(struct ofpbuf *b, size_t size) |
414 | 0 | { |
415 | 0 | void *dst = ofpbuf_put_uninit(b, size); |
416 | 0 | nullable_memset(dst, 0, size); |
417 | 0 | return dst; |
418 | 0 | } |
419 | | |
420 | | /* Appends the 'size' bytes of data in 'p' to the tail end of 'b'. Data in 'b' |
421 | | * is reallocated and copied if necessary. Returns a pointer to the first |
422 | | * byte of the data's location in the ofpbuf. */ |
423 | | void * |
424 | | ofpbuf_put(struct ofpbuf *b, const void *p, size_t size) |
425 | 0 | { |
426 | 0 | if (!size) { |
427 | 0 | return ofpbuf_tail(b); |
428 | 0 | } |
429 | | |
430 | 0 | void *dst = ofpbuf_put_uninit(b, size); |
431 | 0 | memcpy(dst, p, size); |
432 | 0 | return dst; |
433 | 0 | } |
434 | | |
435 | | /* Parses as many pairs of hex digits as possible (possibly separated by spaces |
436 | | * or periods) from the beginning of 's', appending bytes for their values to |
437 | | * 'b'. Returns the first character of 's' that is not the first of a pair of |
438 | | * hex digits. If 'n' is nonnull, stores the number of bytes added to 'b' in |
439 | | * '*n'. */ |
440 | | char * |
441 | | ofpbuf_put_hex(struct ofpbuf *b, const char *s, size_t *n) |
442 | 0 | { |
443 | 0 | size_t initial_size = b->size; |
444 | 0 | for (;;) { |
445 | 0 | uint8_t byte; |
446 | 0 | bool ok; |
447 | |
|
448 | 0 | s += strspn(s, " .\t\r\n"); |
449 | 0 | byte = hexits_value(s, 2, &ok); |
450 | 0 | if (!ok) { |
451 | 0 | if (n) { |
452 | 0 | *n = b->size - initial_size; |
453 | 0 | } |
454 | 0 | return CONST_CAST(char *, s); |
455 | 0 | } |
456 | | |
457 | 0 | ofpbuf_put(b, &byte, 1); |
458 | 0 | s += 2; |
459 | 0 | } |
460 | 0 | } |
461 | | |
462 | | /* Reserves 'size' bytes of headroom so that they can be later allocated with |
463 | | * ofpbuf_push_uninit() without reallocating the ofpbuf. */ |
464 | | void |
465 | | ofpbuf_reserve(struct ofpbuf *b, size_t size) |
466 | 0 | { |
467 | 0 | ovs_assert(!b->size); |
468 | |
|
469 | 0 | if (!size) { |
470 | 0 | return; |
471 | 0 | } |
472 | 0 | ofpbuf_prealloc_tailroom(b, size); |
473 | 0 | b->data = (char*)b->data + size; |
474 | 0 | } |
475 | | |
476 | | /* Prefixes 'size' bytes to the head end of 'b', reallocating and copying its |
477 | | * data if necessary. Returns a pointer to the first byte of the data's |
478 | | * location in the ofpbuf. The new data is left uninitialized. */ |
479 | | void * |
480 | | ofpbuf_push_uninit(struct ofpbuf *b, size_t size) |
481 | 0 | { |
482 | 0 | if (!size) { |
483 | 0 | return b->data; |
484 | 0 | } |
485 | | |
486 | 0 | ofpbuf_prealloc_headroom(b, size); |
487 | 0 | b->data = (char*)b->data - size; |
488 | 0 | b->size += size; |
489 | 0 | return b->data; |
490 | 0 | } |
491 | | |
492 | | /* Prefixes 'size' zeroed bytes to the head end of 'b', reallocating and |
493 | | * copying its data if necessary. Returns a pointer to the first byte of the |
494 | | * data's location in the ofpbuf. */ |
495 | | void * |
496 | | ofpbuf_push_zeros(struct ofpbuf *b, size_t size) |
497 | 0 | { |
498 | 0 | void *dst = ofpbuf_push_uninit(b, size); |
499 | 0 | memset(dst, 0, size); |
500 | 0 | return dst; |
501 | 0 | } |
502 | | |
503 | | /* Copies the 'size' bytes starting at 'p' to the head end of 'b', reallocating |
504 | | * and copying its data if necessary. Returns a pointer to the first byte of |
505 | | * the data's location in the ofpbuf. */ |
506 | | void * |
507 | | ofpbuf_push(struct ofpbuf *b, const void *p, size_t size) |
508 | 0 | { |
509 | 0 | void *dst = ofpbuf_push_uninit(b, size); |
510 | 0 | memcpy(dst, p, size); |
511 | 0 | return dst; |
512 | 0 | } |
513 | | |
514 | | /* Inserts the 'n' bytes of 'data' into 'b' starting at the given 'offset', |
515 | | * moving data forward as necessary to make room. |
516 | | * |
517 | | * 'data' must not point inside 'b'. */ |
518 | | void |
519 | | ofpbuf_insert(struct ofpbuf *b, size_t offset, const void *data, size_t n) |
520 | 0 | { |
521 | 0 | if (offset < b->size) { |
522 | 0 | ofpbuf_put_uninit(b, n); /* b->size gets increased. */ |
523 | 0 | memmove((char *) b->data + offset + n, (char *) b->data + offset, |
524 | 0 | b->size - offset - n); |
525 | 0 | memcpy((char *) b->data + offset, data, n); |
526 | 0 | } else { |
527 | 0 | ovs_assert(offset == b->size); |
528 | 0 | ofpbuf_put(b, data, n); |
529 | 0 | } |
530 | 0 | } |
531 | | |
532 | | /* Returns the data in 'b' as a block of malloc()'d memory and frees the buffer |
533 | | * within 'b'. (If 'b' itself was dynamically allocated, e.g. with |
534 | | * ofpbuf_new(), then it should still be freed with, e.g., ofpbuf_delete().) */ |
535 | | void * |
536 | | ofpbuf_steal_data(struct ofpbuf *b) |
537 | 0 | { |
538 | 0 | void *p; |
539 | |
|
540 | 0 | if (b->source == OFPBUF_MALLOC && b->data == b->base) { |
541 | 0 | p = b->data; |
542 | 0 | } else { |
543 | 0 | p = xmemdup(b->data, b->size); |
544 | 0 | if (b->source == OFPBUF_MALLOC) { |
545 | 0 | free(b->base); |
546 | 0 | } |
547 | 0 | } |
548 | 0 | b->base = NULL; |
549 | 0 | b->data = NULL; |
550 | 0 | b->header = NULL; |
551 | 0 | b->msg = NULL; |
552 | 0 | return p; |
553 | 0 | } |
554 | | |
555 | | /* Returns a string that describes some of 'b''s metadata plus a hex dump of up |
556 | | * to 'maxbytes' from the start of the buffer. */ |
557 | | char * |
558 | | ofpbuf_to_string(const struct ofpbuf *b, size_t maxbytes) |
559 | 0 | { |
560 | 0 | struct ds s; |
561 | |
|
562 | 0 | ds_init(&s); |
563 | 0 | ds_put_format(&s, "size=%"PRIu32", allocated=%"PRIu32", head=%"PRIuSIZE", tail=%"PRIuSIZE"\n", |
564 | 0 | b->size, b->allocated, |
565 | 0 | ofpbuf_headroom(b), ofpbuf_tailroom(b)); |
566 | 0 | ds_put_hex_dump(&s, b->data, MIN(b->size, maxbytes), 0, false); |
567 | 0 | return ds_cstr(&s); |
568 | 0 | } |
569 | | |
570 | | /* Removes each of the "struct ofpbuf"s on 'list' from the list and frees |
571 | | * them. */ |
572 | | void |
573 | | ofpbuf_list_delete(struct ovs_list *list) |
574 | 0 | { |
575 | 0 | struct ofpbuf *b; |
576 | |
|
577 | 0 | LIST_FOR_EACH_POP (b, list_node, list) { |
578 | 0 | ofpbuf_delete(b); |
579 | 0 | } |
580 | 0 | } |