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 | } |