]>
git.proxmox.com Git - ovs.git/blob - lib/ofpbuf.c
2 * Copyright (c) 2008, 2009, 2010 Nicira Networks.
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:
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
22 #include "dynamic-string.h"
25 /* Initializes 'b' as an empty ofpbuf that contains the 'allocated' bytes of
26 * memory starting at 'base'.
28 * 'base' should ordinarily be the first byte of a region obtained from
29 * malloc(), but in circumstances where it can be guaranteed that 'b' will
30 * never need to be expanded or freed, it can be a pointer into arbitrary
33 ofpbuf_use(struct ofpbuf
*b
, void *base
, size_t allocated
)
35 b
->base
= b
->data
= base
;
36 b
->allocated
= allocated
;
38 b
->l2
= b
->l3
= b
->l4
= b
->l7
= NULL
;
43 /* Initializes 'b' as an empty ofpbuf with an initial capacity of 'size'
46 ofpbuf_init(struct ofpbuf
*b
, size_t size
)
48 ofpbuf_use(b
, size
? xmalloc(size
) : NULL
, size
);
51 /* Frees memory that 'b' points to. */
53 ofpbuf_uninit(struct ofpbuf
*b
)
60 /* Frees memory that 'b' points to and allocates a new ofpbuf */
62 ofpbuf_reinit(struct ofpbuf
*b
, size_t size
)
68 /* Creates and returns a new ofpbuf with an initial capacity of 'size'
71 ofpbuf_new(size_t size
)
73 struct ofpbuf
*b
= xmalloc(sizeof *b
);
79 ofpbuf_clone(const struct ofpbuf
*buffer
)
81 return ofpbuf_clone_data(buffer
->data
, buffer
->size
);
85 ofpbuf_clone_data(const void *data
, size_t size
)
87 struct ofpbuf
*b
= ofpbuf_new(size
);
88 ofpbuf_put(b
, data
, size
);
92 /* Frees memory that 'b' points to, as well as 'b' itself. */
94 ofpbuf_delete(struct ofpbuf
*b
)
102 /* Returns the number of bytes of headroom in 'b', that is, the number of bytes
103 * of unused space in ofpbuf 'b' before the data that is in use. (Most
104 * commonly, the data in a ofpbuf is at its beginning, and thus the ofpbuf's
107 ofpbuf_headroom(const struct ofpbuf
*b
)
109 return (char*)b
->data
- (char*)b
->base
;
112 /* Returns the number of bytes that may be appended to the tail end of ofpbuf
113 * 'b' before the ofpbuf must be reallocated. */
115 ofpbuf_tailroom(const struct ofpbuf
*b
)
117 return (char*)ofpbuf_end(b
) - (char*)ofpbuf_tail(b
);
120 /* Changes 'b->base' to 'new_base' and adjusts all of 'b''s internal pointers
121 * to reflect the change. */
123 ofpbuf_rebase__(struct ofpbuf
*b
, void *new_base
)
125 if (b
->base
!= new_base
) {
126 uintptr_t base_delta
= (char*)new_base
- (char*)b
->base
;
128 b
->data
= (char*)b
->data
+ base_delta
;
130 b
->l2
= (char*)b
->l2
+ base_delta
;
133 b
->l3
= (char*)b
->l3
+ base_delta
;
136 b
->l4
= (char*)b
->l4
+ base_delta
;
139 b
->l7
= (char*)b
->l7
+ base_delta
;
144 /* Reallocates 'b' so that it has exactly 'new_tailroom' bytes of tailroom. */
146 ofpbuf_resize_tailroom__(struct ofpbuf
*b
, size_t new_tailroom
)
148 b
->allocated
= ofpbuf_headroom(b
) + b
->size
+ new_tailroom
;
149 ofpbuf_rebase__(b
, xrealloc(b
->base
, b
->allocated
));
152 /* Ensures that 'b' has room for at least 'size' bytes at its tail end,
153 * reallocating and copying its data if necessary. Its headroom, if any, is
156 ofpbuf_prealloc_tailroom(struct ofpbuf
*b
, size_t size
)
158 if (size
> ofpbuf_tailroom(b
)) {
159 ofpbuf_resize_tailroom__(b
, MAX(size
, 64));
164 ofpbuf_prealloc_headroom(struct ofpbuf
*b
, size_t size
)
166 assert(size
<= ofpbuf_headroom(b
));
169 /* Trims the size of 'b' to fit its actual content, reducing its tailroom to
170 * 0. Its headroom, if any, is preserved. */
172 ofpbuf_trim(struct ofpbuf
*b
)
174 if (ofpbuf_tailroom(b
) > 0) {
175 ofpbuf_resize_tailroom__(b
, 0);
179 /* Appends 'size' bytes of data to the tail end of 'b', reallocating and
180 * copying its data if necessary. Returns a pointer to the first byte of the
181 * new data, which is left uninitialized. */
183 ofpbuf_put_uninit(struct ofpbuf
*b
, size_t size
)
186 ofpbuf_prealloc_tailroom(b
, size
);
192 /* Appends 'size' zeroed bytes to the tail end of 'b'. Data in 'b' is
193 * reallocated and copied if necessary. Returns a pointer to the first byte of
194 * the data's location in the ofpbuf. */
196 ofpbuf_put_zeros(struct ofpbuf
*b
, size_t size
)
198 void *dst
= ofpbuf_put_uninit(b
, size
);
199 memset(dst
, 0, size
);
203 /* Appends the 'size' bytes of data in 'p' to the tail end of 'b'. Data in 'b'
204 * is reallocated and copied if necessary. Returns a pointer to the first
205 * byte of the data's location in the ofpbuf. */
207 ofpbuf_put(struct ofpbuf
*b
, const void *p
, size_t size
)
209 void *dst
= ofpbuf_put_uninit(b
, size
);
210 memcpy(dst
, p
, size
);
214 /* Reserves 'size' bytes of headroom so that they can be later allocated with
215 * ofpbuf_push_uninit() without reallocating the ofpbuf. */
217 ofpbuf_reserve(struct ofpbuf
*b
, size_t size
)
220 ofpbuf_prealloc_tailroom(b
, size
);
221 b
->data
= (char*)b
->data
+ size
;
225 ofpbuf_push_uninit(struct ofpbuf
*b
, size_t size
)
227 ofpbuf_prealloc_headroom(b
, size
);
228 b
->data
= (char*)b
->data
- size
;
233 /* Prefixes 'size' zeroed bytes to the head end of 'b'. 'b' must have at least
234 * 'size' bytes of headroom. Returns a pointer to the first byte of the data's
235 * location in the ofpbuf. */
237 ofpbuf_push_zeros(struct ofpbuf
*b
, size_t size
)
239 void *dst
= ofpbuf_push_uninit(b
, size
);
240 memset(dst
, 0, size
);
245 ofpbuf_push(struct ofpbuf
*b
, const void *p
, size_t size
)
247 void *dst
= ofpbuf_push_uninit(b
, size
);
248 memcpy(dst
, p
, size
);
252 /* If 'b' contains at least 'offset + size' bytes of data, returns a pointer to
253 * byte 'offset'. Otherwise, returns a null pointer. */
255 ofpbuf_at(const struct ofpbuf
*b
, size_t offset
, size_t size
)
257 return offset
+ size
<= b
->size
? (char *) b
->data
+ offset
: NULL
;
260 /* Returns a pointer to byte 'offset' in 'b', which must contain at least
261 * 'offset + size' bytes of data. */
263 ofpbuf_at_assert(const struct ofpbuf
*b
, size_t offset
, size_t size
)
265 assert(offset
+ size
<= b
->size
);
266 return ((char *) b
->data
) + offset
;
269 /* Returns the byte following the last byte of data in use in 'b'. */
271 ofpbuf_tail(const struct ofpbuf
*b
)
273 return (char *) b
->data
+ b
->size
;
276 /* Returns the byte following the last byte allocated for use (but not
277 * necessarily in use) by 'b'. */
279 ofpbuf_end(const struct ofpbuf
*b
)
281 return (char *) b
->base
+ b
->allocated
;
284 /* Clears any data from 'b'. */
286 ofpbuf_clear(struct ofpbuf
*b
)
292 /* Removes 'size' bytes from the head end of 'b', which must contain at least
293 * 'size' bytes of data. Returns the first byte of data removed. */
295 ofpbuf_pull(struct ofpbuf
*b
, size_t size
)
297 void *data
= b
->data
;
298 assert(b
->size
>= size
);
299 b
->data
= (char*)b
->data
+ size
;
304 /* If 'b' has at least 'size' bytes of data, removes that many bytes from the
305 * head end of 'b' and returns the first byte removed. Otherwise, returns a
306 * null pointer without modifying 'b'. */
308 ofpbuf_try_pull(struct ofpbuf
*b
, size_t size
)
310 return b
->size
>= size
? ofpbuf_pull(b
, size
) : NULL
;
313 /* Returns a string that describes some of 'b''s metadata plus a hex dump of up
314 * to 'maxbytes' from the start of the buffer. */
316 ofpbuf_to_string(const struct ofpbuf
*b
, size_t maxbytes
)
321 ds_put_format(&s
, "size=%zu, allocated=%zu, head=%zu, tail=%zu\n",
322 b
->size
, b
->allocated
,
323 ofpbuf_headroom(b
), ofpbuf_tailroom(b
));
324 ds_put_hex_dump(&s
, b
->data
, MIN(b
->size
, maxbytes
), 0, false);