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