• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright © 2014 Intel Corporation
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice (including the next
12  * paragraph) shall be included in all copies or substantial portions of the
13  * Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21  * IN THE SOFTWARE.
22  */
23 
24 #ifndef BLOB_H
25 #define BLOB_H
26 
27 #include <stdbool.h>
28 #include <stddef.h>
29 #include <stdint.h>
30 #include <stdlib.h>
31 
32 #ifdef __cplusplus
33 extern "C" {
34 #endif
35 
36 /* The blob functions implement a simple, low-level API for serializing and
37  * deserializing.
38  *
39  * All objects written to a blob will be serialized directly, (without any
40  * additional meta-data to describe the data written). Therefore, it is the
41  * caller's responsibility to ensure that any data can be read later, (either
42  * by knowing exactly what data is expected, or by writing to the blob
43  * sufficient meta-data to describe what has been written).
44  *
45  * A blob is efficient in that it dynamically grows by doubling in size, so
46  * allocation costs are logarithmic.
47  */
48 
49 struct blob {
50    /* The data actually written to the blob. */
51    uint8_t *data;
52 
53    /** Number of bytes that have been allocated for \c data. */
54    size_t allocated;
55 
56    /** The number of bytes that have actual data written to them. */
57    size_t size;
58 
59    /** True if \c data a fixed allocation that we cannot resize
60     *
61     * \see blob_init_fixed
62     */
63    bool fixed_allocation;
64 
65    /**
66     * True if we've ever failed to realloc or if we go pas the end of a fixed
67     * allocation blob.
68     */
69    bool out_of_memory;
70 };
71 
72 /* When done reading, the caller can ensure that everything was consumed by
73  * checking the following:
74  *
75  *   1. blob->current should be equal to blob->end, (if not, too little was
76  *      read).
77  *
78  *   2. blob->overrun should be false, (otherwise, too much was read).
79  */
80 struct blob_reader {
81    const uint8_t *data;
82    const uint8_t *end;
83    const uint8_t *current;
84    bool overrun;
85 };
86 
87 /**
88  * Init a new, empty blob.
89  */
90 void
91 blob_init(struct blob *blob);
92 
93 /**
94  * Init a new, fixed-size blob.
95  *
96  * A fixed-size blob has a fixed block of data that will not be freed on
97  * blob_finish and will never be grown.  If we hit the end, we simply start
98  * returning false from the write functions.
99  *
100  * If a fixed-size blob has a NULL data pointer then the data is written but
101  * it otherwise operates normally.  This can be used to determine the size
102  * that will be required to write a given data structure.
103  */
104 void
105 blob_init_fixed(struct blob *blob, void *data, size_t size);
106 
107 /**
108  * Finish a blob and free its memory.
109  *
110  * If \blob was initialized with blob_init_fixed, the data pointer is
111  * considered to be owned by the user and will not be freed.
112  */
113 static inline void
blob_finish(struct blob * blob)114 blob_finish(struct blob *blob)
115 {
116    if (!blob->fixed_allocation)
117       free(blob->data);
118 }
119 
120 /**
121  * Add some unstructured, fixed-size data to a blob.
122  *
123  * \return True unless allocation failed.
124  */
125 bool
126 blob_write_bytes(struct blob *blob, const void *bytes, size_t to_write);
127 
128 /**
129  * Reserve space in \blob for a number of bytes.
130  *
131  * Space will be allocated within the blob for these byes, but the bytes will
132  * be left uninitialized. The caller is expected to use \sa
133  * blob_overwrite_bytes to write to these bytes.
134  *
135  * \return An offset to space allocated within \blob to which \to_write bytes
136  * can be written, (or -1 in case of any allocation error).
137  */
138 intptr_t
139 blob_reserve_bytes(struct blob *blob, size_t to_write);
140 
141 /**
142  * Similar to \sa blob_reserve_bytes, but only reserves an uint32_t worth of
143  * space. Note that this must be used if later reading with \sa
144  * blob_read_uint32, since it aligns the offset correctly.
145  */
146 intptr_t
147 blob_reserve_uint32(struct blob *blob);
148 
149 /**
150  * Similar to \sa blob_reserve_bytes, but only reserves an intptr_t worth of
151  * space. Note that this must be used if later reading with \sa
152  * blob_read_intptr, since it aligns the offset correctly.
153  */
154 intptr_t
155 blob_reserve_intptr(struct blob *blob);
156 
157 /**
158  * Overwrite some data previously written to the blob.
159  *
160  * Writes data to an existing portion of the blob at an offset of \offset.
161  * This data range must have previously been written to the blob by one of the
162  * blob_write_* calls.
163  *
164  * For example usage, see blob_overwrite_uint32
165  *
166  * \return True unless the requested offset or offset+to_write lie outside
167  * the current blob's size.
168  */
169 bool
170 blob_overwrite_bytes(struct blob *blob,
171                      size_t offset,
172                      const void *bytes,
173                      size_t to_write);
174 
175 /**
176  * Add a uint32_t to a blob.
177  *
178  * \note This function will only write to a uint32_t-aligned offset from the
179  * beginning of the blob's data, so some padding bytes may be added to the
180  * blob if this write follows some unaligned write (such as
181  * blob_write_string).
182  *
183  * \return True unless allocation failed.
184  */
185 bool
186 blob_write_uint32(struct blob *blob, uint32_t value);
187 
188 /**
189  * Overwrite a uint32_t previously written to the blob.
190  *
191  * Writes a uint32_t value to an existing portion of the blob at an offset of
192  * \offset.  This data range must have previously been written to the blob by
193  * one of the blob_write_* calls.
194  *
195  *
196  * The expected usage is something like the following pattern:
197  *
198  *	size_t offset;
199  *
200  *	offset = blob_reserve_uint32(blob);
201  *	... various blob write calls, writing N items ...
202  *	blob_overwrite_uint32 (blob, offset, N);
203  *
204  * \return True unless the requested position or position+to_write lie outside
205  * the current blob's size.
206  */
207 bool
208 blob_overwrite_uint32(struct blob *blob,
209                       size_t offset,
210                       uint32_t value);
211 
212 /**
213  * Add a uint64_t to a blob.
214  *
215  * \note This function will only write to a uint64_t-aligned offset from the
216  * beginning of the blob's data, so some padding bytes may be added to the
217  * blob if this write follows some unaligned write (such as
218  * blob_write_string).
219  *
220  * \return True unless allocation failed.
221  */
222 bool
223 blob_write_uint64(struct blob *blob, uint64_t value);
224 
225 /**
226  * Add an intptr_t to a blob.
227  *
228  * \note This function will only write to an intptr_t-aligned offset from the
229  * beginning of the blob's data, so some padding bytes may be added to the
230  * blob if this write follows some unaligned write (such as
231  * blob_write_string).
232  *
233  * \return True unless allocation failed.
234  */
235 bool
236 blob_write_intptr(struct blob *blob, intptr_t value);
237 
238 /**
239  * Overwrite an intptr_t previously written to the blob.
240  *
241  * Writes a intptr_t value to an existing portion of the blob at an offset of
242  * \offset.  This data range must have previously been written to the blob by
243  * one of the blob_write_* calls.
244  *
245  * For example usage, see blob_overwrite_uint32
246  *
247  * \return True unless the requested position or position+to_write lie outside
248  * the current blob's size.
249  */
250 bool
251 blob_overwrite_intptr(struct blob *blob,
252                       size_t offset,
253                       intptr_t value);
254 
255 /**
256  * Add a NULL-terminated string to a blob, (including the NULL terminator).
257  *
258  * \return True unless allocation failed.
259  */
260 bool
261 blob_write_string(struct blob *blob, const char *str);
262 
263 /**
264  * Start reading a blob, (initializing the contents of \blob for reading).
265  *
266  * After this call, the caller can use the various blob_read_* functions to
267  * read elements from the data array.
268  *
269  * For all of the blob_read_* functions, if there is insufficient data
270  * remaining, the functions will do nothing, (perhaps returning default values
271  * such as 0). The caller can detect this by noting that the blob_reader's
272  * current value is unchanged before and after the call.
273  */
274 void
275 blob_reader_init(struct blob_reader *blob, const void *data, size_t size);
276 
277 /**
278  * Read some unstructured, fixed-size data from the current location, (and
279  * update the current location to just past this data).
280  *
281  * \note The memory returned belongs to the data underlying the blob reader. The
282  * caller must copy the data in order to use it after the lifetime of the data
283  * underlying the blob reader.
284  *
285  * \return The bytes read (see note above about memory lifetime).
286  */
287 const void *
288 blob_read_bytes(struct blob_reader *blob, size_t size);
289 
290 /**
291  * Read some unstructured, fixed-size data from the current location, copying
292  * it to \dest (and update the current location to just past this data)
293  */
294 void
295 blob_copy_bytes(struct blob_reader *blob, void *dest, size_t size);
296 
297 /**
298  * Read a uint32_t from the current location, (and update the current location
299  * to just past this uint32_t).
300  *
301  * \note This function will only read from a uint32_t-aligned offset from the
302  * beginning of the blob's data, so some padding bytes may be skipped.
303  *
304  * \return The uint32_t read
305  */
306 uint32_t
307 blob_read_uint32(struct blob_reader *blob);
308 
309 /**
310  * Read a uint64_t from the current location, (and update the current location
311  * to just past this uint64_t).
312  *
313  * \note This function will only read from a uint64_t-aligned offset from the
314  * beginning of the blob's data, so some padding bytes may be skipped.
315  *
316  * \return The uint64_t read
317  */
318 uint64_t
319 blob_read_uint64(struct blob_reader *blob);
320 
321 /**
322  * Read an intptr_t value from the current location, (and update the
323  * current location to just past this intptr_t).
324  *
325  * \note This function will only read from an intptr_t-aligned offset from the
326  * beginning of the blob's data, so some padding bytes may be skipped.
327  *
328  * \return The intptr_t read
329  */
330 intptr_t
331 blob_read_intptr(struct blob_reader *blob);
332 
333 /**
334  * Read a NULL-terminated string from the current location, (and update the
335  * current location to just past this string).
336  *
337  * \note The memory returned belongs to the data underlying the blob reader. The
338  * caller must copy the string in order to use the string after the lifetime
339  * of the data underlying the blob reader.
340  *
341  * \return The string read (see note above about memory lifetime). However, if
342  * there is no NULL byte remaining within the blob, this function returns
343  * NULL.
344  */
345 char *
346 blob_read_string(struct blob_reader *blob);
347 
348 #ifdef __cplusplus
349 }
350 #endif
351 
352 #endif /* BLOB_H */
353