Subversion Repositories Games.Chess Giants

Rev

Rev 116 | 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.    char *dest;
  86.  
  87.    // see if we need to grow the data
  88.    if (write_index + data_size > buffer->size)
  89.    {
  90.       // if so, reallocate data buffer at the right size
  91.       new_data = (char *) realloc (buffer->data, write_index + data_size);
  92.       if (new_data == NULL)
  93.          return (0); // on failure, return an error value
  94.  
  95.       buffer->data = new_data; // save pointer to reallocated data
  96.    }
  97.  
  98.    // do dest and source overlap ?
  99.    dest = &buffer->data[write_index];
  100.    if (((data <= dest) && (data + data_size > dest)) || ((dest <= data) && (dest + data_size > data)))
  101.       memmove (&buffer->data[write_index], data, data_size); // if so, move data in place
  102.    else
  103.       memcpy (&buffer->data[write_index], data, data_size); // else write data in place (faster)
  104.    if (write_index + data_size > buffer->size)
  105.       buffer->size = write_index + data_size; // update data size only if it growed
  106.  
  107.    return (1); // buffer written successfully, return SUCCESS
  108. }
  109.  
  110.  
  111. int Buffer_ReadFromFile (buffer_t *buffer, const char *file_pathname)
  112. {
  113.    // this function copies the contents of file_pathname in a newly allocated data buffer
  114.    // and fills in the buffer size accordingly. It is up to the caller to free that buffer.
  115.    // Returns 1 on success, 0 on error.
  116.  
  117.    struct stat stat_buffer;
  118.    FILE *fp;
  119.  
  120.    // start by reporting a zero length
  121.    buffer->size = 0;
  122.  
  123.    // figure out file existence and size
  124.    if (stat (file_pathname, &stat_buffer) != 0)
  125.       return (0); // on failure, return an error value
  126.  
  127.    // allocate enough space for it
  128.    if ((buffer->data = (char *) malloc (stat_buffer.st_size)) == NULL)
  129.       return (0); // on failure, return an error value
  130.  
  131.    // open it for binary reading
  132.    fopen_s (&fp, file_pathname, "rb");
  133.    if (fp == NULL)
  134.    {
  135.       free (buffer->data);
  136.       return (0); // on failure, return an error value
  137.    }
  138.  
  139.    // and read it at once
  140.    if (fread (buffer->data, 1, stat_buffer.st_size, fp) != (size_t) stat_buffer.st_size)
  141.    {
  142.       free (buffer->data);
  143.       return (0); // on failure, return an error value
  144.    }
  145.  
  146.    fclose (fp); // finished, close file
  147.    buffer->size = stat_buffer.st_size; // report its size
  148.  
  149.    return (1); // and return SUCCESS
  150. }
  151.  
  152.  
  153. int Buffer_ReadFromFileW (buffer_t *buffer, const wchar_t *file_pathname)
  154. {
  155.    // this function copies the contents of file_pathname in a newly allocated data buffer
  156.    // and fills in the buffer size accordingly. It is up to the caller to free that buffer.
  157.    // Returns 1 on success, 0 on error.
  158.  
  159.    struct _stat stat_buffer;
  160.    FILE *fp;
  161.  
  162.    // start by reporting a zero length
  163.    buffer->size = 0;
  164.  
  165.    // figure out file existence and size
  166.    if (_wstat (file_pathname, &stat_buffer) != 0)
  167.       return (0); // on failure, return an error value
  168.  
  169.    // allocate enough space for it
  170.    if ((buffer->data = (char *) malloc (stat_buffer.st_size)) == NULL)
  171.       return (0); // on failure, return an error value
  172.  
  173.                   // open it for binary reading
  174.    _wfopen_s (&fp, file_pathname, L"rb");
  175.    if (fp == NULL)
  176.    {
  177.       free (buffer->data);
  178.       return (0); // on failure, return an error value
  179.    }
  180.  
  181.    // and read it at once
  182.    if (fread (buffer->data, 1, stat_buffer.st_size, fp) != (size_t) stat_buffer.st_size)
  183.    {
  184.       free (buffer->data);
  185.       return (0); // on failure, return an error value
  186.    }
  187.  
  188.    fclose (fp); // finished, close file
  189.    buffer->size = stat_buffer.st_size; // report its size
  190.  
  191.    return (1); // and return SUCCESS
  192. }
  193.  
  194.  
  195. int Buffer_WriteToFile (buffer_t *buffer, const char *file_pathname)
  196. {
  197.    // this function copies the contents of buffer's data into the file pointed to by
  198.    // file_pathname. Returns 1 on success, 0 on error.
  199.  
  200.    FILE *fp;
  201.  
  202.    // open file for binary writing
  203.    fopen_s (&fp, file_pathname, "wb");
  204.    if (fp == NULL)
  205.       return (0);
  206.  
  207.    // and write it at once
  208.    if (fwrite (buffer->data, 1, buffer->size, fp) != (size_t) buffer->size)
  209.       return (0);
  210.  
  211.    fclose (fp); // finished, close file
  212.    return (1); // and return SUCCESS
  213. }
  214.  
  215.  
  216. int Buffer_WriteToFileW (buffer_t *buffer, const wchar_t *file_pathname)
  217. {
  218.    // this function copies the contents of buffer's data into the file pointed to by
  219.    // file_pathname. Returns 1 on success, 0 on error.
  220.  
  221.    FILE *fp;
  222.  
  223.    // open file for binary writing
  224.    _wfopen_s (&fp, file_pathname, L"wb");
  225.    if (fp == NULL)
  226.       return (0);
  227.  
  228.    // and write it at once
  229.    if (fwrite (buffer->data, 1, buffer->size, fp) != (size_t) buffer->size)
  230.       return (0);
  231.  
  232.    fclose (fp); // finished, close file
  233.    return (1); // and return SUCCESS
  234. }
  235.  
  236.  
  237. char *Buffer_Find (buffer_t *buffer, char *needle, unsigned long needle_length)
  238. {
  239.    // returns a pointer to the first occurence of needle in buffer haystack, or NULL if not found
  240.  
  241.    unsigned long byte_index;
  242.  
  243.    if (buffer->size < needle_length)
  244.       return (NULL); // consistency check: if buffer is too small for needle, return NULL
  245.  
  246.    // parse buffer from start to end
  247.    for (byte_index = 0; byte_index < buffer->size - needle_length; byte_index++)
  248.       if (memcmp (&buffer->data[byte_index], needle, needle_length) == 0)
  249.          return (&buffer->data[byte_index]); // return the first match we find
  250.  
  251.    return (NULL); // definitely no needle in buffer
  252. }
  253.  
  254.  
  255. int Buffer_Compare (buffer_t *buffer1, buffer_t *buffer2)
  256. {
  257.    // compares two buffers and return 0 if they match, non-zero if they differ.
  258.    // If their size differ, the difference between both is returned.
  259.    // If their content differ, the result of memcmp() is returned.
  260.  
  261.    if (buffer1->size != buffer2->size)
  262.       return (buffer2->size - buffer1->size); // buffers differ in size
  263.  
  264.    return (memcmp (buffer1->data, buffer2->data, buffer1->size)); // do a memcmp() on both buffers
  265. }
  266.  
  267.  
  268. unsigned long Buffer_OffsetOf (buffer_t *buffer, void *something)
  269. {
  270.    // returns the absolute offset of the data pointed to by something relatively to the beginning of buffer data
  271.  
  272.    return ((unsigned long) something - (unsigned long) buffer->data);
  273. }
  274.