Subversion Repositories Games.Chess Giants

Rev

Rev 116 | Go to most recent revision | 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
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;
154 pmbaty 85
   char *dest;
116 pmbaty 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
 
154 pmbaty 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)
116 pmbaty 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
}