Mercurial > code
annotate pack.c @ 115:1d0e5580d402
Reduce code for cosmetic
author | David Demelier <markand@malikania.fr> |
---|---|
date | Mon, 13 Feb 2012 19:46:22 +0100 |
parents | c66fb578a7c4 |
children | 09fb5267c906 |
rev | line source |
---|---|
56 | 1 /* |
98 | 2 * pack.c -- endian dependant binary file reader |
3 * | |
4 * Copyright (c) 2011, 2012, David Demelier <markand@malikania.fr> | |
56 | 5 * |
6 * Permission to use, copy, modify, and/or distribute this software for any | |
7 * purpose with or without fee is hereby granted, provided that the above | |
8 * copyright notice and this permission notice appear in all copies. | |
9 * | |
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | |
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | |
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | |
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | |
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | |
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | |
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |
17 */ | |
18 | |
19 #include <stdio.h> | |
20 #include <stdlib.h> | |
21 #include <stdint.h> | |
22 #include <stdarg.h> | |
80 | 23 #include <string.h> |
56 | 24 #include <ctype.h> |
25 | |
26 #include "pack.h" | |
27 | |
28 /* -------------------------------------------------------- | |
29 * structure definitions | |
30 * -------------------------------------------------------- */ | |
31 | |
103
7fefa3a34461
pack.c now directly write to the file
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
32 typedef void (*ConvertFn)(void *); |
56 | 33 |
34 /* -------------------------------------------------------- | |
35 * prototypes | |
36 * -------------------------------------------------------- */ | |
37 | |
38 static size_t pack_getsize(char); | |
103
7fefa3a34461
pack.c now directly write to the file
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
39 static ConvertFn pack_getconvert_by_tok(char); |
7fefa3a34461
pack.c now directly write to the file
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
40 static ConvertFn pack_getconvert_by_size(size_t); |
115
1d0e5580d402
Reduce code for cosmetic
David Demelier <markand@malikania.fr>
parents:
104
diff
changeset
|
41 static void pack_convert16(uint16_t *); |
1d0e5580d402
Reduce code for cosmetic
David Demelier <markand@malikania.fr>
parents:
104
diff
changeset
|
42 static void pack_convert32(uint32_t *); |
1d0e5580d402
Reduce code for cosmetic
David Demelier <markand@malikania.fr>
parents:
104
diff
changeset
|
43 static void pack_convert64(uint64_t *); |
103
7fefa3a34461
pack.c now directly write to the file
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
44 static void pack_write_one(int, FILE *, uint64_t, size_t); |
7fefa3a34461
pack.c now directly write to the file
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
45 static void pack_write_multiple(int, FILE *, uint8_t *, int, size_t); |
56 | 46 |
47 /* -------------------------------------------------------- | |
48 * private functions | |
49 * -------------------------------------------------------- */ | |
50 | |
51 #define LENGTH(x) (sizeof (x) / sizeof (x[0])) | |
52 | |
53 /* | |
54 * Associative structure, the `tok' member is used for the format | |
55 * and define the integer size. The convert function reverse the | |
56 * bytes if it is needed. | |
57 */ | |
58 | |
59 static struct integer { | |
60 char tok; /* format char */ | |
61 size_t tocopy; /* size */ | |
103
7fefa3a34461
pack.c now directly write to the file
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
62 ConvertFn convert; /* conversion function */ |
56 | 63 } sizes[] = { |
115
1d0e5580d402
Reduce code for cosmetic
David Demelier <markand@malikania.fr>
parents:
104
diff
changeset
|
64 { 'c', sizeof (uint8_t), NULL }, |
1d0e5580d402
Reduce code for cosmetic
David Demelier <markand@malikania.fr>
parents:
104
diff
changeset
|
65 { 's', sizeof (uint16_t), (ConvertFn)pack_convert16 }, |
1d0e5580d402
Reduce code for cosmetic
David Demelier <markand@malikania.fr>
parents:
104
diff
changeset
|
66 { 'i', sizeof (uint32_t), (ConvertFn)pack_convert32 }, |
1d0e5580d402
Reduce code for cosmetic
David Demelier <markand@malikania.fr>
parents:
104
diff
changeset
|
67 { 'l', sizeof (uint64_t), (ConvertFn)pack_convert64 } |
56 | 68 }; |
69 | |
70 /* | |
71 * Parse the format, return 0 on success or -1 on failure. | |
72 */ | |
73 | |
74 #define PACK_GETARG(i, ap, tok) \ | |
75 do { \ | |
76 switch ((tok)) { \ | |
77 case 'c': \ | |
78 case 's': \ | |
79 case 'i': \ | |
80 (i) = va_arg((ap), unsigned); \ | |
81 break; \ | |
82 case 'l': \ | |
83 (i) = va_arg((ap), uint64_t); \ | |
84 default: \ | |
85 break; \ | |
86 } \ | |
87 } while (/* CONSTCOND */ 0) | |
88 | |
89 /* | |
90 * Little helper to get number of element when the user wants a array of | |
91 * objects. Sets the nelem to 0 on array failure or 1 on normal count. | |
92 */ | |
93 | |
94 #define PACK_GETNELEM(nelem, p) \ | |
95 do { \ | |
96 if (p[1] == '[') { \ | |
97 if (p[2] != ']') \ | |
115
1d0e5580d402
Reduce code for cosmetic
David Demelier <markand@malikania.fr>
parents:
104
diff
changeset
|
98 nelem = (int)strtol(p + 2, NULL, 10); \ |
56 | 99 else if (p[2] == ']') \ |
100 nelem = va_arg(ap, int); \ | |
101 \ | |
102 /* Go to the end of fmt and find ']' */ \ | |
103 while (*p != ']' && *p != '\0') \ | |
104 ++p; \ | |
105 } else \ | |
106 nelem = 1; \ | |
107 } while (/* CONSTCOND */ 0) | |
108 | |
109 /* | |
110 * Get the appropriate size associated with the `tok' character. If | |
111 * the token is not found the result is 0. | |
112 */ | |
113 | |
114 static size_t | |
115 pack_getsize(char tok) | |
116 { | |
117 struct integer *s; | |
118 unsigned int i; | |
119 | |
120 for (s = sizes, i = 0; i < LENGTH(sizes); ++s, ++i) | |
121 if (s->tok == tok) | |
122 return s->tocopy; | |
123 | |
124 return 0; | |
125 } | |
126 | |
127 /* | |
128 * Return the conversion function. | |
129 */ | |
130 | |
103
7fefa3a34461
pack.c now directly write to the file
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
131 static ConvertFn |
7fefa3a34461
pack.c now directly write to the file
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
132 pack_getconvert_by_tok(char tok) |
56 | 133 { |
134 struct integer *s; | |
135 unsigned int i; | |
136 | |
137 for (s = sizes, i = 0; i < LENGTH(sizes); ++s, ++i) | |
138 if (s->tok == tok) | |
139 return s->convert; | |
140 | |
141 return NULL; | |
142 } | |
143 | |
144 /* | |
103
7fefa3a34461
pack.c now directly write to the file
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
145 * Same but by size. |
7fefa3a34461
pack.c now directly write to the file
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
146 */ |
7fefa3a34461
pack.c now directly write to the file
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
147 |
7fefa3a34461
pack.c now directly write to the file
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
148 static ConvertFn |
7fefa3a34461
pack.c now directly write to the file
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
149 pack_getconvert_by_size(size_t size) |
7fefa3a34461
pack.c now directly write to the file
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
150 { |
7fefa3a34461
pack.c now directly write to the file
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
151 struct integer *s; |
7fefa3a34461
pack.c now directly write to the file
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
152 unsigned int i; |
7fefa3a34461
pack.c now directly write to the file
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
153 |
7fefa3a34461
pack.c now directly write to the file
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
154 for (s = sizes, i = 0; i < LENGTH(sizes); ++s, ++i) |
7fefa3a34461
pack.c now directly write to the file
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
155 if (s->tocopy == size) |
7fefa3a34461
pack.c now directly write to the file
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
156 return s->convert; |
7fefa3a34461
pack.c now directly write to the file
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
157 |
7fefa3a34461
pack.c now directly write to the file
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
158 return NULL; |
7fefa3a34461
pack.c now directly write to the file
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
159 } |
7fefa3a34461
pack.c now directly write to the file
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
160 |
7fefa3a34461
pack.c now directly write to the file
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
161 /* |
56 | 162 * Conversion functions. They reverse the bytes without any |
163 * check. | |
164 */ | |
165 | |
166 static void | |
115
1d0e5580d402
Reduce code for cosmetic
David Demelier <markand@malikania.fr>
parents:
104
diff
changeset
|
167 pack_convert16(uint16_t *x) |
56 | 168 { |
169 *x = pack_swap16(*x); | |
170 } | |
171 | |
172 static void | |
115
1d0e5580d402
Reduce code for cosmetic
David Demelier <markand@malikania.fr>
parents:
104
diff
changeset
|
173 pack_convert32(uint32_t *x) |
56 | 174 { |
175 *x = pack_swap32(*x); | |
176 } | |
177 | |
178 static void | |
115
1d0e5580d402
Reduce code for cosmetic
David Demelier <markand@malikania.fr>
parents:
104
diff
changeset
|
179 pack_convert64(uint64_t *x) |
56 | 180 { |
181 *x = pack_swap64(*x); | |
182 } | |
183 | |
103
7fefa3a34461
pack.c now directly write to the file
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
184 static void |
7fefa3a34461
pack.c now directly write to the file
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
185 pack_write_one(int ptype, FILE *fp, uint64_t it, size_t size) |
56 | 186 { |
103
7fefa3a34461
pack.c now directly write to the file
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
187 uint64_t cv = it; |
7fefa3a34461
pack.c now directly write to the file
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
188 |
7fefa3a34461
pack.c now directly write to the file
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
189 if (ptype != PACK_HOST_BYTEORDER) { |
7fefa3a34461
pack.c now directly write to the file
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
190 ConvertFn conv = pack_getconvert_by_size(size); |
7fefa3a34461
pack.c now directly write to the file
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
191 |
7fefa3a34461
pack.c now directly write to the file
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
192 if (conv != NULL) |
7fefa3a34461
pack.c now directly write to the file
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
193 conv(&cv); |
7fefa3a34461
pack.c now directly write to the file
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
194 } |
7fefa3a34461
pack.c now directly write to the file
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
195 |
7fefa3a34461
pack.c now directly write to the file
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
196 fwrite(&cv, size, 1, fp); |
7fefa3a34461
pack.c now directly write to the file
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
197 } |
56 | 198 |
103
7fefa3a34461
pack.c now directly write to the file
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
199 static void |
7fefa3a34461
pack.c now directly write to the file
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
200 pack_write_multiple(int ptype, FILE *fp, uint8_t *arr, int length, size_t size) |
7fefa3a34461
pack.c now directly write to the file
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
201 { |
7fefa3a34461
pack.c now directly write to the file
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
202 uint64_t cv; |
7fefa3a34461
pack.c now directly write to the file
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
203 int i; |
7fefa3a34461
pack.c now directly write to the file
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
204 ConvertFn conv = NULL; |
7fefa3a34461
pack.c now directly write to the file
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
205 |
7fefa3a34461
pack.c now directly write to the file
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
206 if (ptype != PACK_HOST_BYTEORDER) |
7fefa3a34461
pack.c now directly write to the file
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
207 conv = pack_getconvert_by_size(size); |
56 | 208 |
103
7fefa3a34461
pack.c now directly write to the file
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
209 for (i = 0; i < length; ++i) { |
7fefa3a34461
pack.c now directly write to the file
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
210 cv = arr[i * size]; |
7fefa3a34461
pack.c now directly write to the file
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
211 if (conv != NULL) |
7fefa3a34461
pack.c now directly write to the file
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
212 conv(&cv); |
7fefa3a34461
pack.c now directly write to the file
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
213 |
7fefa3a34461
pack.c now directly write to the file
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
214 fwrite(&cv, size, 1, fp); |
7fefa3a34461
pack.c now directly write to the file
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
215 } |
56 | 216 } |
217 | |
218 /* -------------------------------------------------------- | |
219 * public functions | |
220 * -------------------------------------------------------- */ | |
221 | |
222 /* | |
223 * Function that writes everything to the file `path'. These functions | |
224 * does not append to the file, so if you want successive call to append | |
225 * variables use fpack instead. | |
226 * Returns 0 on success or -1 on failure. | |
227 */ | |
228 | |
229 int | |
57
311eaa9d004c
Renamed pack_* fonction for our guidelines
David Demelier <markand@malikania.fr>
parents:
56
diff
changeset
|
230 pack_write(int ptype, const char *path, const char *fmt, ...) |
56 | 231 { |
232 va_list ap; | |
233 int status; | |
234 | |
235 va_start(ap, fmt); | |
57
311eaa9d004c
Renamed pack_* fonction for our guidelines
David Demelier <markand@malikania.fr>
parents:
56
diff
changeset
|
236 status = pack_vwrite(ptype, path, fmt, ap); |
56 | 237 va_end(ap); |
238 | |
239 return status; | |
240 } | |
241 | |
242 int | |
57
311eaa9d004c
Renamed pack_* fonction for our guidelines
David Demelier <markand@malikania.fr>
parents:
56
diff
changeset
|
243 pack_vwrite(int ptype, const char *path, const char *fmt, va_list ap) |
56 | 244 { |
245 FILE *fp; | |
246 int status; | |
247 | |
248 if ((fp = fopen(path, "w+b")) == NULL) | |
249 return -1; | |
250 | |
57
311eaa9d004c
Renamed pack_* fonction for our guidelines
David Demelier <markand@malikania.fr>
parents:
56
diff
changeset
|
251 status = pack_vfwrite(ptype, fp, fmt, ap); |
56 | 252 fclose(fp); |
253 | |
254 return status; | |
255 } | |
256 | |
257 /* | |
258 * Write to a file that is already open. The function does not call | |
259 * fclose() so you need to do it yourself later. | |
260 */ | |
261 | |
262 int | |
57
311eaa9d004c
Renamed pack_* fonction for our guidelines
David Demelier <markand@malikania.fr>
parents:
56
diff
changeset
|
263 pack_fwrite(int ptype, FILE *fp, const char *fmt, ...) |
56 | 264 { |
265 va_list ap; | |
266 int status; | |
267 | |
268 va_start(ap, fmt); | |
57
311eaa9d004c
Renamed pack_* fonction for our guidelines
David Demelier <markand@malikania.fr>
parents:
56
diff
changeset
|
269 status = pack_vfwrite(ptype, fp, fmt, ap); |
56 | 270 va_end(ap); |
271 | |
272 return status; | |
273 } | |
274 | |
275 int | |
57
311eaa9d004c
Renamed pack_* fonction for our guidelines
David Demelier <markand@malikania.fr>
parents:
56
diff
changeset
|
276 pack_vfwrite(int ptype, FILE *fp, const char *fmt, va_list ap) |
56 | 277 { |
103
7fefa3a34461
pack.c now directly write to the file
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
278 int nelem; |
7fefa3a34461
pack.c now directly write to the file
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
279 size_t size; |
7fefa3a34461
pack.c now directly write to the file
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
280 char tok; |
7fefa3a34461
pack.c now directly write to the file
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
281 const char *p; |
56 | 282 |
103
7fefa3a34461
pack.c now directly write to the file
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
283 for (p = fmt; *p != '\0'; ++p) { |
7fefa3a34461
pack.c now directly write to the file
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
284 if (isspace(*p)) |
7fefa3a34461
pack.c now directly write to the file
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
285 continue; |
7fefa3a34461
pack.c now directly write to the file
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
286 |
7fefa3a34461
pack.c now directly write to the file
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
287 tok = *p; |
7fefa3a34461
pack.c now directly write to the file
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
288 size = pack_getsize(tok); |
7fefa3a34461
pack.c now directly write to the file
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
289 |
7fefa3a34461
pack.c now directly write to the file
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
290 /* Bad character */ |
7fefa3a34461
pack.c now directly write to the file
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
291 if (size == 0) |
7fefa3a34461
pack.c now directly write to the file
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
292 continue; |
56 | 293 |
103
7fefa3a34461
pack.c now directly write to the file
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
294 PACK_GETNELEM(nelem, p); |
7fefa3a34461
pack.c now directly write to the file
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
295 if (nelem == 0) |
7fefa3a34461
pack.c now directly write to the file
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
296 continue; |
56 | 297 |
103
7fefa3a34461
pack.c now directly write to the file
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
298 /* |
7fefa3a34461
pack.c now directly write to the file
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
299 * If i is 1, then we only have one integer, if it's more |
7fefa3a34461
pack.c now directly write to the file
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
300 * than one, user may have given an array of something else. |
7fefa3a34461
pack.c now directly write to the file
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
301 */ |
7fefa3a34461
pack.c now directly write to the file
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
302 if (nelem == 1) { |
7fefa3a34461
pack.c now directly write to the file
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
303 uint64_t item; |
56 | 304 |
103
7fefa3a34461
pack.c now directly write to the file
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
305 PACK_GETARG(item, ap, tok); |
7fefa3a34461
pack.c now directly write to the file
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
306 pack_write_one(ptype, fp, item, size); |
7fefa3a34461
pack.c now directly write to the file
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
307 } else { |
7fefa3a34461
pack.c now directly write to the file
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
308 uint8_t *arr; |
7fefa3a34461
pack.c now directly write to the file
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
309 |
7fefa3a34461
pack.c now directly write to the file
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
310 arr = va_arg(ap, uint8_t *); |
7fefa3a34461
pack.c now directly write to the file
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
311 pack_write_multiple(ptype, fp, arr, nelem, size); |
56 | 312 } |
313 } | |
314 | |
103
7fefa3a34461
pack.c now directly write to the file
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
315 return 0; |
56 | 316 } |
317 | |
318 /* | |
319 * Function that read the binary file and restore values to the same format | |
320 * as pack functions. Arguments must be pointer of enough space to store | |
321 * the values. | |
322 */ | |
323 | |
324 int | |
57
311eaa9d004c
Renamed pack_* fonction for our guidelines
David Demelier <markand@malikania.fr>
parents:
56
diff
changeset
|
325 pack_read(int ptype, const char *path, const char *fmt, ...) |
56 | 326 { |
327 va_list ap; | |
328 int status; | |
329 | |
330 va_start(ap, fmt); | |
57
311eaa9d004c
Renamed pack_* fonction for our guidelines
David Demelier <markand@malikania.fr>
parents:
56
diff
changeset
|
331 status = pack_vread(ptype, path, fmt, ap); |
56 | 332 va_end(ap); |
333 | |
334 return status; | |
335 } | |
336 | |
337 int | |
57
311eaa9d004c
Renamed pack_* fonction for our guidelines
David Demelier <markand@malikania.fr>
parents:
56
diff
changeset
|
338 pack_vread(int ptype, const char *path, const char *fmt, va_list ap) |
56 | 339 { |
340 FILE *fp; | |
341 int status; | |
342 | |
343 if ((fp = fopen(path, "rb")) == NULL) | |
344 return -1; | |
345 | |
57
311eaa9d004c
Renamed pack_* fonction for our guidelines
David Demelier <markand@malikania.fr>
parents:
56
diff
changeset
|
346 status = pack_vfread(ptype, fp, fmt, ap); |
56 | 347 fclose(fp); |
348 | |
349 return status; | |
350 | |
351 } | |
352 | |
353 int | |
57
311eaa9d004c
Renamed pack_* fonction for our guidelines
David Demelier <markand@malikania.fr>
parents:
56
diff
changeset
|
354 pack_fread(int ptype, FILE *fp, const char *fmt, ...) |
56 | 355 { |
356 va_list ap; | |
357 int status; | |
358 | |
359 va_start(ap, fmt); | |
57
311eaa9d004c
Renamed pack_* fonction for our guidelines
David Demelier <markand@malikania.fr>
parents:
56
diff
changeset
|
360 status = pack_vfread(ptype, fp, fmt, ap); |
56 | 361 va_end(ap); |
362 | |
363 return status; | |
364 } | |
365 | |
366 int | |
57
311eaa9d004c
Renamed pack_* fonction for our guidelines
David Demelier <markand@malikania.fr>
parents:
56
diff
changeset
|
367 pack_vfread(int ptype, FILE *fp, const char *fmt, va_list ap) |
56 | 368 { |
369 const char *p; | |
104 | 370 uint8_t *ptr; |
56 | 371 size_t tocopy; |
103
7fefa3a34461
pack.c now directly write to the file
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
372 ConvertFn convert; |
56 | 373 |
374 for (p = fmt; *p != '\0'; ++p) { | |
375 char tok; | |
376 int nelem, i; | |
377 | |
378 if (isspace(*p)) | |
379 continue; | |
380 | |
381 tok = *p; | |
382 tocopy = pack_getsize(tok); | |
383 | |
384 /* Bad character */ | |
385 if (tocopy == 0) | |
386 continue; | |
387 | |
388 /* Determine how many element to read and copy */ | |
389 PACK_GETNELEM(nelem, p); | |
390 if (nelem == 0) | |
391 continue; | |
392 | |
104 | 393 if ((ptr = va_arg(ap, uint8_t *)) == NULL) |
56 | 394 continue; |
395 | |
396 for (i = 0; i < nelem; ++i) { | |
104 | 397 fread(&ptr[tocopy * i], tocopy, 1, fp); |
56 | 398 |
399 /* Convert if needed */ | |
103
7fefa3a34461
pack.c now directly write to the file
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
400 convert = pack_getconvert_by_tok(tok); |
56 | 401 if (ptype != PACK_HOST_BYTEORDER && convert != NULL) |
115
1d0e5580d402
Reduce code for cosmetic
David Demelier <markand@malikania.fr>
parents:
104
diff
changeset
|
402 convert((char *)ptr + (tocopy * i)); |
56 | 403 } |
404 } | |
405 | |
406 return 0; | |
407 } |