Subversion Repositories Games.Chess Giants

Rev

Rev 154 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. // buffer.cpp
  2.  
  3. #include "common.h"
  4.  
  5.  
  6. // cross-platform facilities
  7. #ifndef _WIN32
  8. #define fopen_s(fp,filename,mode) *(fp) = fopen (filename, mode)
  9. #endif // _WIN32
  10.  
  11.  
  12. void Buffer_Initialize (buffer_t *buffer)
  13. {
  14.    // this function initializes a new buffer_t structure, resetting its data pointer and size.
  15.  
  16.    buffer->data = NULL; // allocate max_size bytes for data
  17.    buffer->size = 0; // reset size
  18.  
  19.    return; // finished, buffer structure is empty
  20. }
  21.  
  22.  
  23. void Buffer_Forget (buffer_t *buffer)
  24. {
  25.    // this function forgets a buffer's contents, freeing its associated memory buffer,
  26.    // and resets the buffer_t structure.
  27.  
  28.    if (buffer->data != NULL)
  29.       free (buffer->data); // free buffer data
  30.    buffer->data = NULL;
  31.    buffer->size = 0; // reset data size
  32.  
  33.    return; // finished, buffer structure is virgin again
  34. }
  35.  
  36.  
  37. int Buffer_Append (buffer_t *buffer, char *data, unsigned long data_size)
  38. {
  39.    // this function appends the content of data to a buffer's data.
  40.    // Returns 1 on success, 0 on error.
  41.  
  42.    char *new_data;
  43.  
  44.    // first, reallocate space to hold data_size bytes more
  45.    new_data = (char *) realloc (buffer->data, buffer->size + data_size);
  46.    if (new_data == NULL)
  47.       return (0); // on failure, return an error value
  48.  
  49.    buffer->data = new_data; // save pointer to reallocated data
  50.    memcpy (&buffer->data[buffer->size], data, data_size); // write new data at the end
  51.    buffer->size += data_size; // and increment buffer size
  52.  
  53.    return (1); // buffer appended successfully, return SUCCESS
  54. }
  55.  
  56.  
  57. int Buffer_Prepend (buffer_t *buffer, char *data, unsigned long data_size)
  58. {
  59.    // this function prepends the content of data to a buffer's data.
  60.    // Returns 1 on success, 0 on error.
  61.  
  62.    char *new_data;
  63.  
  64.    // first, reallocate space to hold data_size bytes more
  65.    new_data = (char *) realloc (buffer->data, data_size + buffer->size);
  66.    if (new_data == NULL)
  67.       return (0); // on failure, return an error value
  68.  
  69.    buffer->data = new_data; // save pointer to reallocated data
  70.    if (buffer->size > 0)
  71.       memmove (&buffer->data[data_size], buffer->data, buffer->size); // move existing data to the end
  72.    memcpy (buffer->data, data, data_size); // write new data at the beginning
  73.    buffer->size += data_size; // and increment buffer size
  74.  
  75.    return (1); // buffer appended successfully, return SUCCESS
  76. }
  77.  
  78.  
  79. int Buffer_WriteAt (buffer_t *buffer, unsigned long write_index, char *data, unsigned long data_size)
  80. {
  81.    // this function writes the content of data to a buffer's data at position write_index.
  82.    // Returns 1 on success, 0 on error.
  83.  
  84.    char *new_data;
  85.  
  86.    // see if we need to grow the data
  87.    if (write_index + data_size > buffer->size)
  88.    {
  89.       // if so, reallocate data buffer at the right size
  90.       new_data = (char *) realloc (buffer->data, write_index + data_size);
  91.       if (new_data == NULL)
  92.          return (0); // on failure, return an error value
  93.  
  94.       buffer->data = new_data; // save pointer to reallocated data
  95.    }
  96.  
  97.    memcpy (&buffer->data[write_index], data, data_size); // write data in place
  98.    if (write_index + data_size > buffer->size)
  99.       buffer->size = write_index + data_size; // update data size only if it growed
  100.  
  101.    return (1); // buffer written successfully, return SUCCESS
  102. }
  103.  
  104.  
  105. int Buffer_ReadFromFile (buffer_t *buffer, const char *file_pathname)
  106. {
  107.    // this function copies the contents of file_pathname in a newly allocated data buffer
  108.    // and fills in the buffer size accordingly. It is up to the caller to free that buffer.
  109.    // Returns 1 on success, 0 on error.
  110.  
  111.    struct stat stat_buffer;
  112.    FILE *fp;
  113.  
  114.    // start by reporting a zero length
  115.    buffer->size = 0;
  116.  
  117.    // figure out file existence and size
  118.    if (stat (file_pathname, &stat_buffer) != 0)
  119.       return (0); // on failure, return an error value
  120.  
  121.    // allocate enough space for it
  122.    if ((buffer->data = (char *) malloc (stat_buffer.st_size)) == NULL)
  123.       return (0); // on failure, return an error value
  124.  
  125.    // open it for binary reading
  126.    fopen_s (&fp, file_pathname, "rb");
  127.    if (fp == NULL)
  128.    {
  129.       free (buffer->data);
  130.       return (0); // on failure, return an error value
  131.    }
  132.  
  133.    // and read it at once
  134.    if (fread (buffer->data, 1, stat_buffer.st_size, fp) != (size_t) stat_buffer.st_size)
  135.    {
  136.       free (buffer->data);
  137.       return (0); // on failure, return an error value
  138.    }
  139.  
  140.    fclose (fp); // finished, close file
  141.    buffer->size = stat_buffer.st_size; // report its size
  142.  
  143.    return (1); // and return SUCCESS
  144. }
  145.  
  146.  
  147. int Buffer_ReadFromFileW (buffer_t *buffer, const wchar_t *file_pathname)
  148. {
  149.    // this function copies the contents of file_pathname in a newly allocated data buffer
  150.    // and fills in the buffer size accordingly. It is up to the caller to free that buffer.
  151.    // Returns 1 on success, 0 on error.
  152.  
  153.    struct _stat stat_buffer;
  154.    FILE *fp;
  155.  
  156.    // start by reporting a zero length
  157.    buffer->size = 0;
  158.  
  159.    // figure out file existence and size
  160.    if (_wstat (file_pathname, &stat_buffer) != 0)
  161.       return (0); // on failure, return an error value
  162.  
  163.    // allocate enough space for it
  164.    if ((buffer->data = (char *) malloc (stat_buffer.st_size)) == NULL)
  165.       return (0); // on failure, return an error value
  166.  
  167.                   // open it for binary reading
  168.    _wfopen_s (&fp, file_pathname, L"rb");
  169.    if (fp == NULL)
  170.    {
  171.       free (buffer->data);
  172.       return (0); // on failure, return an error value
  173.    }
  174.  
  175.    // and read it at once
  176.    if (fread (buffer->data, 1, stat_buffer.st_size, fp) != (size_t) stat_buffer.st_size)
  177.    {
  178.       free (buffer->data);
  179.       return (0); // on failure, return an error value
  180.    }
  181.  
  182.    fclose (fp); // finished, close file
  183.    buffer->size = stat_buffer.st_size; // report its size
  184.  
  185.    return (1); // and return SUCCESS
  186. }
  187.  
  188.  
  189. int Buffer_WriteToFile (buffer_t *buffer, const char *file_pathname)
  190. {
  191.    // this function copies the contents of buffer's data into the file pointed to by
  192.    // file_pathname. Returns 1 on success, 0 on error.
  193.  
  194.    FILE *fp;
  195.  
  196.    // open file for binary writing
  197.    fopen_s (&fp, file_pathname, "wb");
  198.    if (fp == NULL)
  199.       return (0);
  200.  
  201.    // and write it at once
  202.    if (fwrite (buffer->data, 1, buffer->size, fp) != (size_t) buffer->size)
  203.       return (0);
  204.  
  205.    fclose (fp); // finished, close file
  206.    return (1); // and return SUCCESS
  207. }
  208.  
  209.  
  210. int Buffer_WriteToFileW (buffer_t *buffer, const wchar_t *file_pathname)
  211. {
  212.    // this function copies the contents of buffer's data into the file pointed to by
  213.    // file_pathname. Returns 1 on success, 0 on error.
  214.  
  215.    FILE *fp;
  216.  
  217.    // open file for binary writing
  218.    _wfopen_s (&fp, file_pathname, L"wb");
  219.    if (fp == NULL)
  220.       return (0);
  221.  
  222.    // and write it at once
  223.    if (fwrite (buffer->data, 1, buffer->size, fp) != (size_t) buffer->size)
  224.       return (0);
  225.  
  226.    fclose (fp); // finished, close file
  227.    return (1); // and return SUCCESS
  228. }
  229.  
  230.  
  231. char *Buffer_Find (buffer_t *buffer, char *needle, unsigned long needle_length)
  232. {
  233.    // returns a pointer to the first occurence of needle in buffer haystack, or NULL if not found
  234.  
  235.    unsigned long byte_index;
  236.  
  237.    if (buffer->size < needle_length)
  238.       return (NULL); // consistency check: if buffer is too small for needle, return NULL
  239.  
  240.    // parse buffer from start to end
  241.    for (byte_index = 0; byte_index < buffer->size - needle_length; byte_index++)
  242.       if (memcmp (&buffer->data[byte_index], needle, needle_length) == 0)
  243.          return (&buffer->data[byte_index]); // return the first match we find
  244.  
  245.    return (NULL); // definitely no needle in buffer
  246. }
  247.  
  248.  
  249. int Buffer_Compare (buffer_t *buffer1, buffer_t *buffer2)
  250. {
  251.    // compares two buffers and return 0 if they match, non-zero if they differ.
  252.    // If their size differ, the difference between both is returned.
  253.    // If their content differ, the result of memcmp() is returned.
  254.  
  255.    if (buffer1->size != buffer2->size)
  256.       return (buffer2->size - buffer1->size); // buffers differ in size
  257.  
  258.    return (memcmp (buffer1->data, buffer2->data, buffer1->size)); // do a memcmp() on both buffers
  259. }
  260.  
  261.  
  262. unsigned long Buffer_OffsetOf (buffer_t *buffer, void *something)
  263. {
  264.    // returns the absolute offset of the data pointed to by something relatively to the beginning of buffer data
  265.  
  266.    return ((unsigned long) something - (unsigned long) buffer->data);
  267. }
  268.