Subversion Repositories Games.Chess Giants

Rev

Rev 154 | Details | Compare with Previous | Last modification | View Log | RSS feed

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