Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. /*
  2.  * This file is part of LibParserUtils.
  3.  * Licensed under the MIT License,
  4.  *                http://www.opensource.org/licenses/mit-license.php
  5.  * Copyright 2008 John-Mark Bell <jmb@netsurf-browser.org>
  6.  */
  7.  
  8. #include <string.h>
  9.  
  10. #include <parserutils/utils/buffer.h>
  11.  
  12. #define DEFAULT_SIZE (4096)
  13.  
  14. /**
  15.  * Create a memory buffer
  16.  *
  17.  * \param alloc   Memory (de)allocation function
  18.  * \param pw      Pointer to client-specific private data
  19.  * \param buffer  Pointer to location to receive memory buffer
  20.  * \return PARSERUTILS_OK on success,
  21.  *         PARSERUTILS_BADPARM on bad parameters,
  22.  *         PARSERUTILS_NOMEM on memory exhausion
  23.  */
  24. parserutils_error parserutils_buffer_create(parserutils_alloc alloc, void *pw,
  25.                 parserutils_buffer **buffer)
  26. {
  27.         parserutils_buffer *b;
  28.  
  29.         if (alloc == NULL || buffer == NULL)
  30.                 return PARSERUTILS_BADPARM;
  31.  
  32.         b = alloc(NULL, sizeof(parserutils_buffer), pw);
  33.         if (b == NULL)
  34.                 return PARSERUTILS_NOMEM;
  35.  
  36.         b->data = alloc(NULL, DEFAULT_SIZE, pw);
  37.         if (b->data == NULL) {
  38.                 alloc(b, 0, pw);
  39.                 return PARSERUTILS_NOMEM;
  40.         }
  41.  
  42.         b->length = 0;
  43.         b->allocated = DEFAULT_SIZE;
  44.  
  45.         b->alloc = alloc;
  46.         b->pw = pw;
  47.  
  48.         *buffer = b;
  49.  
  50.         return PARSERUTILS_OK;
  51. }
  52.  
  53. /**
  54.  * Destroy a memory buffer
  55.  *
  56.  * \param buffer  The buffer to destroy
  57.  * \return PARSERUTILS_OK on success, appropriate error otherwise
  58.  */
  59. parserutils_error parserutils_buffer_destroy(parserutils_buffer *buffer)
  60. {
  61.         if (buffer == NULL)
  62.                 return PARSERUTILS_BADPARM;
  63.  
  64.         buffer->alloc(buffer->data, 0, buffer->pw);
  65.         buffer->alloc(buffer, 0, buffer->pw);
  66.  
  67.         return PARSERUTILS_OK;
  68. }
  69.  
  70. /**
  71.  * Append data to a memory buffer
  72.  *
  73.  * \param buffer  The buffer to append to
  74.  * \param data    The data to append
  75.  * \param len     The length, in bytes, of the data to append
  76.  * \return PARSERUTILS_OK on success, appropriate error otherwise.
  77.  */
  78. parserutils_error parserutils_buffer_append(parserutils_buffer *buffer,
  79.                 const uint8_t *data, size_t len)
  80. {
  81.         while (len >= buffer->allocated - buffer->length) {
  82.                 parserutils_error error = parserutils_buffer_grow(buffer);
  83.                 if (error != PARSERUTILS_OK)
  84.                         return error;
  85.         }
  86.  
  87.         memcpy(buffer->data + buffer->length, data, len);
  88.  
  89.         buffer->length += len;
  90.  
  91.         return PARSERUTILS_OK;
  92. }
  93.  
  94. /**
  95.  * Insert data into a memory buffer
  96.  *
  97.  * \param buffer  The buffer to insert into
  98.  * \param offset  The offset into the buffer to insert at
  99.  * \param data    The data to insert
  100.  * \param len     The length, in bytes, of the data to insert
  101.  * \return PARSERUTILS_OK on success, appropriate error otherwise
  102.  */
  103. parserutils_error parserutils_buffer_insert(parserutils_buffer *buffer,
  104.                 size_t offset, const uint8_t *data, size_t len)
  105. {
  106.         if (offset > buffer->length)
  107.                 return PARSERUTILS_BADPARM;
  108.  
  109.         if (offset == buffer->length)
  110.                 return parserutils_buffer_append(buffer, data, len);
  111.  
  112.         while (len >= buffer->allocated - buffer->length) {
  113.                 parserutils_error error = parserutils_buffer_grow(buffer);
  114.                 if (error != PARSERUTILS_OK)
  115.                         return error;
  116.         }
  117.  
  118.         memmove(buffer->data + offset + len,
  119.                         buffer->data + offset, buffer->length - offset);
  120.  
  121.         memcpy(buffer->data + offset, data, len);
  122.  
  123.         buffer->length += len;
  124.  
  125.         return PARSERUTILS_OK;
  126. }
  127.  
  128. /**
  129.  * Discard a section of a memory buffer
  130.  *
  131.  * \param buffer  The buffer to discard data from
  132.  * \param offset  The offset into the buffer of the start of the section
  133.  * \param len     The number of bytes to discard
  134.  * \return PARSERUTILS_OK on success, appropriate error otherwise.
  135.  */
  136. parserutils_error parserutils_buffer_discard(parserutils_buffer *buffer,
  137.                 size_t offset, size_t len)
  138. {
  139.         if (offset >= buffer->length || offset + len > buffer->length)
  140.                 return PARSERUTILS_BADPARM;
  141.  
  142.         memmove(buffer->data + offset, buffer->data + offset + len,
  143.                         buffer->length - len);
  144.  
  145.         buffer->length -= len;
  146.  
  147.         return PARSERUTILS_OK;
  148. }
  149.  
  150. /**
  151.  * Extend the amount of space allocated for a memory buffer
  152.  *
  153.  * \param buffer  The buffer to extend
  154.  * \return PARSERUTILS_OK on success, appropriate error otherwise.
  155.  */
  156. parserutils_error parserutils_buffer_grow(parserutils_buffer *buffer)
  157. {
  158.         uint8_t *temp = buffer->alloc(buffer->data,
  159.                         buffer->allocated * 2, buffer->pw);
  160.         if (temp == NULL)
  161.                 return PARSERUTILS_NOMEM;
  162.  
  163.         buffer->data = temp;
  164.         buffer->allocated *= 2;
  165.  
  166.         return PARSERUTILS_OK;
  167. }
  168.  
  169. parserutils_error parserutils_buffer_randomise(parserutils_buffer *buffer)
  170. {
  171. #ifndef NDEBUG
  172.         uint8_t *temp;
  173. #endif
  174.  
  175.         if (buffer == NULL)
  176.                 return PARSERUTILS_BADPARM;
  177.  
  178. #ifndef NDEBUG
  179.         temp = buffer->alloc(NULL, buffer->allocated, buffer->pw);
  180.         if (temp == NULL)
  181.                 return PARSERUTILS_NOMEM;
  182.  
  183.         memcpy(temp, buffer->data, buffer->length);
  184.  
  185.         memset(buffer->data, 0xff, buffer->length);
  186.  
  187.         /* Leak the buffer's current data, so we don't reuse it */
  188.         /* buffer->alloc(buffer->data, 0, buffer->pw); */
  189.  
  190.         buffer->data = temp;
  191. #endif
  192.  
  193.  
  194.         return PARSERUTILS_OK;
  195. }
  196.  
  197.