Subversion Repositories Games.Chess Giants

Rev

Rev 154 | Go to most recent revision | Details | 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;
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
}