Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  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. #pragma once
  25. #ifndef BLOB_H
  26. #define BLOB_H
  27.  
  28. #ifdef __cplusplus
  29. extern "C" {
  30. #endif
  31.  
  32. #include <stdint.h>
  33.  
  34. /* The blob functions implement a simple, low-level API for serializing and
  35.  * deserializing.
  36.  *
  37.  * All objects written to a blob will be serialized directly, (without any
  38.  * additional meta-data to describe the data written). Therefore, it is the
  39.  * caller's responsibility to ensure that any data can be read later, (either
  40.  * by knowing exactly what data is expected, or by writing to the blob
  41.  * sufficient meta-data to describe what has been written).
  42.  *
  43.  * A blob is efficient in that it dynamically grows by doubling in size, so
  44.  * allocation costs are logarithmic.
  45.  */
  46.  
  47. struct blob {
  48.    /* The data actually written to the blob. */
  49.    uint8_t *data;
  50.  
  51.    /** Number of bytes that have been allocated for \c data. */
  52.    size_t allocated;
  53.  
  54.    /** The number of bytes that have actual data written to them. */
  55.    size_t size;
  56. };
  57.  
  58. /* When done reading, the caller can ensure that everything was consumed by
  59.  * checking the following:
  60.  *
  61.  *   1. blob->current should be equal to blob->end, (if not, too little was
  62.  *      read).
  63.  *
  64.  *   2. blob->overrun should be false, (otherwise, too much was read).
  65.  */
  66. struct blob_reader {
  67.    uint8_t *data;
  68.    uint8_t *end;
  69.    uint8_t *current;
  70.    bool overrun;
  71. };
  72.  
  73. /**
  74.  * Create a new, empty blob, belonging to \mem_ctx.
  75.  *
  76.  * \return The new blob, (or NULL in case of allocation failure).
  77.  */
  78. struct blob *
  79. blob_create (void *mem_ctx);
  80.  
  81. /**
  82.  * Add some unstructured, fixed-size data to a blob.
  83.  *
  84.  * \return True unless allocation failed.
  85.  */
  86. bool
  87. blob_write_bytes (struct blob *blob, const void *bytes, size_t to_write);
  88.  
  89. /**
  90.  * Reserve space in \blob for a number of bytes.
  91.  *
  92.  * Space will be allocated within the blob for these byes, but the bytes will
  93.  * be left uninitialized. The caller is expected to use the return value to
  94.  * write directly (and immediately) to these bytes.
  95.  *
  96.  * \note The return value is valid immediately upon return, but can be
  97.  * invalidated by any other call to a blob function. So the caller should call
  98.  * blob_reserve_byes immediately before writing through the returned pointer.
  99.  *
  100.  * This function is intended to be used when interfacing with an existing API
  101.  * that is not aware of the blob API, (so that blob_write_bytes cannot be
  102.  * called).
  103.  *
  104.  * \return A pointer to space allocated within \blob to which \to_write bytes
  105.  * can be written, (or NULL in case of any allocation error).
  106.  */
  107. uint8_t *
  108. blob_reserve_bytes (struct blob *blob, size_t to_write);
  109.  
  110. /**
  111.  * Overwrite some data previously written to the blob.
  112.  *
  113.  * Writes data to an existing portion of the blob at an offset of \offset.
  114.  * This data range must have previously been written to the blob by one of the
  115.  * blob_write_* calls.
  116.  *
  117.  * For example usage, see blob_overwrite_uint32
  118.  *
  119.  * \return True unless the requested offset or offset+to_write lie outside
  120.  * the current blob's size.
  121.  */
  122. bool
  123. blob_overwrite_bytes (struct blob *blob,
  124.                       size_t offset,
  125.                       const void *bytes,
  126.                       size_t to_write);
  127.  
  128. /**
  129.  * Add a uint32_t to a blob.
  130.  *
  131.  * \note This function will only write to a uint32_t-aligned offset from the
  132.  * beginning of the blob's data, so some padding bytes may be added to the
  133.  * blob if this write follows some unaligned write (such as
  134.  * blob_write_string).
  135.  *
  136.  * \return True unless allocation failed.
  137.  */
  138. bool
  139. blob_write_uint32 (struct blob *blob, uint32_t value);
  140.  
  141. /**
  142.  * Overwrite a uint32_t previously written to the blob.
  143.  *
  144.  * Writes a uint32_t value to an existing portion of the blob at an offset of
  145.  * \offset.  This data range must have previously been written to the blob by
  146.  * one of the blob_write_* calls.
  147.  *
  148.  *
  149.  * The expected usage is something like the following pattern:
  150.  *
  151.  *      size_t offset;
  152.  *
  153.  *      offset = blob->size;
  154.  *      blob_write_uint32 (blob, 0); // placeholder
  155.  *      ... various blob write calls, writing N items ...
  156.  *      blob_overwrite_uint32 (blob, offset, N);
  157.  *
  158.  * \return True unless the requested position or position+to_write lie outside
  159.  * the current blob's size.
  160.  */
  161. bool
  162. blob_overwrite_uint32 (struct blob *blob,
  163.                        size_t offset,
  164.                        uint32_t value);
  165.  
  166. /**
  167.  * Add a uint64_t to a blob.
  168.  *
  169.  * \note This function will only write to a uint64_t-aligned offset from the
  170.  * beginning of the blob's data, so some padding bytes may be added to the
  171.  * blob if this write follows some unaligned write (such as
  172.  * blob_write_string).
  173.  *
  174.  * \return True unless allocation failed.
  175.  */
  176. bool
  177. blob_write_uint64 (struct blob *blob, uint64_t value);
  178.  
  179. /**
  180.  * Add an intptr_t to a blob.
  181.  *
  182.  * \note This function will only write to an intptr_t-aligned offset from the
  183.  * beginning of the blob's data, so some padding bytes may be added to the
  184.  * blob if this write follows some unaligned write (such as
  185.  * blob_write_string).
  186.  *
  187.  * \return True unless allocation failed.
  188.  */
  189. bool
  190. blob_write_intptr (struct blob *blob, intptr_t value);
  191.  
  192. /**
  193.  * Add a NULL-terminated string to a blob, (including the NULL terminator).
  194.  *
  195.  * \return True unless allocation failed.
  196.  */
  197. bool
  198. blob_write_string (struct blob *blob, const char *str);
  199.  
  200. /**
  201.  * Start reading a blob, (initializing the contents of \blob for reading).
  202.  *
  203.  * After this call, the caller can use the various blob_read_* functions to
  204.  * read elements from the data array.
  205.  *
  206.  * For all of the blob_read_* functions, if there is insufficient data
  207.  * remaining, the functions will do nothing, (perhaps returning default values
  208.  * such as 0). The caller can detect this by noting that the blob_reader's
  209.  * current value is unchanged before and after the call.
  210.  */
  211. void
  212. blob_reader_init (struct blob_reader *blob, uint8_t *data, size_t size);
  213.  
  214. /**
  215.  * Read some unstructured, fixed-size data from the current location, (and
  216.  * update the current location to just past this data).
  217.  *
  218.  * \note The memory returned belongs to the data underlying the blob reader. The
  219.  * caller must copy the data in order to use it after the lifetime of the data
  220.  * underlying the blob reader.
  221.  *
  222.  * \return The bytes read (see note above about memory lifetime).
  223.  */
  224. void *
  225. blob_read_bytes (struct blob_reader *blob, size_t size);
  226.  
  227. /**
  228.  * Read some unstructured, fixed-size data from the current location, copying
  229.  * it to \dest (and update the current location to just past this data)
  230.  */
  231. void
  232. blob_copy_bytes (struct blob_reader *blob, uint8_t *dest, size_t size);
  233.  
  234. /**
  235.  * Read a uint32_t from the current location, (and update the current location
  236.  * to just past this uint32_t).
  237.  *
  238.  * \note This function will only read from a uint32_t-aligned offset from the
  239.  * beginning of the blob's data, so some padding bytes may be skipped.
  240.  *
  241.  * \return The uint32_t read
  242.  */
  243. uint32_t
  244. blob_read_uint32 (struct blob_reader *blob);
  245.  
  246. /**
  247.  * Read a uint64_t from the current location, (and update the current location
  248.  * to just past this uint64_t).
  249.  *
  250.  * \note This function will only read from a uint64_t-aligned offset from the
  251.  * beginning of the blob's data, so some padding bytes may be skipped.
  252.  *
  253.  * \return The uint64_t read
  254.  */
  255. uint64_t
  256. blob_read_uint64 (struct blob_reader *blob);
  257.  
  258. /**
  259.  * Read an intptr_t value from the current location, (and update the
  260.  * current location to just past this intptr_t).
  261.  *
  262.  * \note This function will only read from an intptr_t-aligned offset from the
  263.  * beginning of the blob's data, so some padding bytes may be skipped.
  264.  *
  265.  * \return The intptr_t read
  266.  */
  267. intptr_t
  268. blob_read_intptr (struct blob_reader *blob);
  269.  
  270. /**
  271.  * Read a NULL-terminated string from the current location, (and update the
  272.  * current location to just past this string).
  273.  *
  274.  * \note The memory returned belongs to the data underlying the blob reader. The
  275.  * caller must copy the string in order to use the string after the lifetime
  276.  * of the data underlying the blob reader.
  277.  *
  278.  * \return The string read (see note above about memory lifetime). However, if
  279.  * there is no NULL byte remaining within the blob, this function returns
  280.  * NULL.
  281.  */
  282. char *
  283. blob_read_string (struct blob_reader *blob);
  284.  
  285. #ifdef __cplusplus
  286. }
  287. #endif
  288.  
  289. #endif /* BLOB_H */
  290.