- // buffer.cpp 
-   
- #include "common.h" 
-   
-   
- // cross-platform facilities 
- #ifndef _WIN32 
- #define fopen_s(fp,filename,mode) *(fp) = fopen (filename, mode) 
- #endif // _WIN32 
-   
-   
- void Buffer_Initialize (buffer_t *buffer) 
- { 
-    // this function initializes a new buffer_t structure, resetting its data pointer and size. 
-   
-    buffer->data = NULL; // allocate max_size bytes for data 
-    buffer->size = 0; // reset size 
-   
-    return; // finished, buffer structure is empty 
- } 
-   
-   
- void Buffer_Forget (buffer_t *buffer) 
- { 
-    // this function forgets a buffer's contents, freeing its associated memory buffer, 
-    // and resets the buffer_t structure. 
-   
-    if (buffer->data != NULL) 
-       free (buffer->data); // free buffer data 
-    buffer->data = NULL; 
-    buffer->size = 0; // reset data size 
-   
-    return; // finished, buffer structure is virgin again 
- } 
-   
-   
- int Buffer_Append (buffer_t *buffer, char *data, unsigned long data_size) 
- { 
-    // this function appends the content of data to a buffer's data. 
-    // Returns 1 on success, 0 on error. 
-   
-    char *new_data; 
-   
-    // first, reallocate space to hold data_size bytes more 
-    new_data = (char *) realloc (buffer->data, buffer->size + data_size); 
-    if (new_data == NULL) 
-       return (0); // on failure, return an error value 
-   
-    buffer->data = new_data; // save pointer to reallocated data 
-    memcpy (&buffer->data[buffer->size], data, data_size); // write new data at the end 
-    buffer->size += data_size; // and increment buffer size 
-   
-    return (1); // buffer appended successfully, return SUCCESS 
- } 
-   
-   
- int Buffer_Prepend (buffer_t *buffer, char *data, unsigned long data_size) 
- { 
-    // this function prepends the content of data to a buffer's data. 
-    // Returns 1 on success, 0 on error. 
-   
-    char *new_data; 
-   
-    // first, reallocate space to hold data_size bytes more 
-    new_data = (char *) realloc (buffer->data, data_size + buffer->size); 
-    if (new_data == NULL) 
-       return (0); // on failure, return an error value 
-   
-    buffer->data = new_data; // save pointer to reallocated data 
-    if (buffer->size > 0) 
-       memmove (&buffer->data[data_size], buffer->data, buffer->size); // move existing data to the end 
-    memcpy (buffer->data, data, data_size); // write new data at the beginning 
-    buffer->size += data_size; // and increment buffer size 
-   
-    return (1); // buffer appended successfully, return SUCCESS 
- } 
-   
-   
- int Buffer_WriteAt (buffer_t *buffer, unsigned long write_index, char *data, unsigned long data_size) 
- { 
-    // this function writes the content of data to a buffer's data at position write_index. 
-    // Returns 1 on success, 0 on error. 
-   
-    char *new_data; 
-    char *dest; 
-   
-    // see if we need to grow the data 
-    if (write_index + data_size > buffer->size) 
-    { 
-       // if so, reallocate data buffer at the right size 
-       new_data = (char *) realloc (buffer->data, write_index + data_size); 
-       if (new_data == NULL) 
-          return (0); // on failure, return an error value 
-   
-       buffer->data = new_data; // save pointer to reallocated data 
-    } 
-   
-    // do dest and source overlap ? 
-    dest = &buffer->data[write_index]; 
-    if (((data <= dest) && (data + data_size > dest)) || ((dest <= data) && (dest + data_size > data))) 
-       memmove (&buffer->data[write_index], data, data_size); // if so, move data in place 
-    else 
-       memcpy (&buffer->data[write_index], data, data_size); // else write data in place (faster) 
-    if (write_index + data_size > buffer->size) 
-       buffer->size = write_index + data_size; // update data size only if it growed 
-   
-    return (1); // buffer written successfully, return SUCCESS 
- } 
-   
-   
- int Buffer_ReadFromFile (buffer_t *buffer, const char *file_pathname) 
- { 
-    // this function copies the contents of file_pathname in a newly allocated data buffer 
-    // and fills in the buffer size accordingly. It is up to the caller to free that buffer. 
-    // Returns 1 on success, 0 on error. 
-   
-    struct stat stat_buffer; 
-    FILE *fp; 
-   
-    // start by reporting a zero length 
-    buffer->size = 0; 
-   
-    // figure out file existence and size 
-    if (stat (file_pathname, &stat_buffer) != 0) 
-       return (0); // on failure, return an error value 
-   
-    // allocate enough space for it 
-    if ((buffer->data = (char *) malloc (stat_buffer.st_size)) == NULL) 
-       return (0); // on failure, return an error value 
-   
-    // open it for binary reading 
-    fopen_s (&fp, file_pathname, "rb"); 
-    if (fp == NULL) 
-    { 
-       free (buffer->data); 
-       return (0); // on failure, return an error value 
-    } 
-   
-    // and read it at once 
-    if (fread (buffer->data, 1, stat_buffer.st_size, fp) != (size_t) stat_buffer.st_size) 
-    { 
-       free (buffer->data); 
-       return (0); // on failure, return an error value 
-    } 
-   
-    fclose (fp); // finished, close file 
-    buffer->size = stat_buffer.st_size; // report its size 
-   
-    return (1); // and return SUCCESS 
- } 
-   
-   
- int Buffer_ReadFromFileW (buffer_t *buffer, const wchar_t *file_pathname) 
- { 
-    // this function copies the contents of file_pathname in a newly allocated data buffer 
-    // and fills in the buffer size accordingly. It is up to the caller to free that buffer. 
-    // Returns 1 on success, 0 on error. 
-   
-    struct _stat stat_buffer; 
-    FILE *fp; 
-   
-    // start by reporting a zero length 
-    buffer->size = 0; 
-   
-    // figure out file existence and size 
-    if (_wstat (file_pathname, &stat_buffer) != 0) 
-       return (0); // on failure, return an error value 
-   
-    // allocate enough space for it 
-    if ((buffer->data = (char *) malloc (stat_buffer.st_size)) == NULL) 
-       return (0); // on failure, return an error value 
-   
-                   // open it for binary reading 
-    _wfopen_s (&fp, file_pathname, L"rb"); 
-    if (fp == NULL) 
-    { 
-       free (buffer->data); 
-       return (0); // on failure, return an error value 
-    } 
-   
-    // and read it at once 
-    if (fread (buffer->data, 1, stat_buffer.st_size, fp) != (size_t) stat_buffer.st_size) 
-    { 
-       free (buffer->data); 
-       return (0); // on failure, return an error value 
-    } 
-   
-    fclose (fp); // finished, close file 
-    buffer->size = stat_buffer.st_size; // report its size 
-   
-    return (1); // and return SUCCESS 
- } 
-   
-   
- int Buffer_WriteToFile (buffer_t *buffer, const char *file_pathname) 
- { 
-    // this function copies the contents of buffer's data into the file pointed to by 
-    // file_pathname. Returns 1 on success, 0 on error. 
-   
-    FILE *fp; 
-   
-    // open file for binary writing 
-    fopen_s (&fp, file_pathname, "wb"); 
-    if (fp == NULL) 
-       return (0); 
-   
-    // and write it at once 
-    if (fwrite (buffer->data, 1, buffer->size, fp) != (size_t) buffer->size) 
-       return (0); 
-   
-    fclose (fp); // finished, close file 
-    return (1); // and return SUCCESS 
- } 
-   
-   
- int Buffer_WriteToFileW (buffer_t *buffer, const wchar_t *file_pathname) 
- { 
-    // this function copies the contents of buffer's data into the file pointed to by 
-    // file_pathname. Returns 1 on success, 0 on error. 
-   
-    FILE *fp; 
-   
-    // open file for binary writing 
-    _wfopen_s (&fp, file_pathname, L"wb"); 
-    if (fp == NULL) 
-       return (0); 
-   
-    // and write it at once 
-    if (fwrite (buffer->data, 1, buffer->size, fp) != (size_t) buffer->size) 
-       return (0); 
-   
-    fclose (fp); // finished, close file 
-    return (1); // and return SUCCESS 
- } 
-   
-   
- char *Buffer_Find (buffer_t *buffer, char *needle, unsigned long needle_length) 
- { 
-    // returns a pointer to the first occurence of needle in buffer haystack, or NULL if not found 
-   
-    unsigned long byte_index; 
-   
-    if (buffer->size < needle_length) 
-       return (NULL); // consistency check: if buffer is too small for needle, return NULL 
-   
-    // parse buffer from start to end 
-    for (byte_index = 0; byte_index < buffer->size - needle_length; byte_index++) 
-       if (memcmp (&buffer->data[byte_index], needle, needle_length) == 0) 
-          return (&buffer->data[byte_index]); // return the first match we find 
-   
-    return (NULL); // definitely no needle in buffer 
- } 
-   
-   
- int Buffer_Compare (buffer_t *buffer1, buffer_t *buffer2) 
- { 
-    // compares two buffers and return 0 if they match, non-zero if they differ. 
-    // If their size differ, the difference between both is returned. 
-    // If their content differ, the result of memcmp() is returned. 
-   
-    if (buffer1->size != buffer2->size) 
-       return (buffer2->size - buffer1->size); // buffers differ in size 
-   
-    return (memcmp (buffer1->data, buffer2->data, buffer1->size)); // do a memcmp() on both buffers 
- } 
-   
-   
- unsigned long Buffer_OffsetOf (buffer_t *buffer, void *something) 
- { 
-    // returns the absolute offset of the data pointed to by something relatively to the beginning of buffer data 
-   
-    return ((unsigned long) something - (unsigned long) buffer->data); 
- } 
-