Home | History | Annotate | Download | only in compiler
      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
    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