/[public]/psiconv/trunk/lib/psiconv/parse_simple.c
ViewVC logotype

Contents of /psiconv/trunk/lib/psiconv/parse_simple.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 64 - (show annotations)
Fri Dec 15 00:21:51 2000 UTC (18 years, 10 months ago) by frodo
File MIME type: text/plain
File size: 8203 byte(s)
(Frodo) Massive update: theoretically, all return codes are now checked.
        Untested - may have many typos.

1 /*
2 parse_simple.c - Part of psiconv, a PSION 5 file formats converter
3 Copyright (c) 1999, 2000 Frodo Looijaard <frodol@dds.nl>
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19
20 #include "config.h"
21 #include <stdlib.h>
22
23 #include "parse_routines.h"
24
25 psiconv_u8 psiconv_read_u8(const psiconv_buffer buf,int lev,psiconv_u32 off,
26 int *status)
27 {
28 psiconv_u8 *ptr;
29 ptr = psiconv_list_get(buf,off);
30 if (!ptr) {
31 psiconv_warn(lev,off,"Trying byte read past the end of the file");
32 if (status)
33 *status = -PSICONV_E_PARSE;
34 return 0;
35 }
36 if (status)
37 *status = 0;
38 return *ptr;
39 }
40
41 psiconv_u16 psiconv_read_u16(const psiconv_buffer buf,int lev,psiconv_u32 off,
42 int *status)
43 {
44 psiconv_u8 *ptr0,*ptr1;
45 ptr0 = psiconv_list_get(buf,off);
46 ptr1 = psiconv_list_get(buf,off+1);
47 if (!ptr0 || !ptr1) {
48 psiconv_warn(lev,off,"Trying word read past the end of the file");
49 if (status)
50 *status = -PSICONV_E_PARSE;
51 return 0;
52 }
53 if (status)
54 *status = 0;
55 return *ptr0 + (*ptr1 << 8);
56 }
57
58 psiconv_u32 psiconv_read_u32(const psiconv_buffer buf,int lev,psiconv_u32 off,
59 int *status)
60 {
61 psiconv_u8 *ptr0,*ptr1,*ptr2,*ptr3;
62 ptr0 = psiconv_list_get(buf,off);
63 ptr1 = psiconv_list_get(buf,off+1);
64 ptr2 = psiconv_list_get(buf,off+2);
65 ptr3 = psiconv_list_get(buf,off+3);
66 if (!ptr0 || !ptr1 || !ptr2 || !ptr3) {
67 psiconv_warn(lev,off,"Trying long read past the end of the file");
68 if (status)
69 *status = -PSICONV_E_PARSE;
70 return 0;
71 }
72 if (status)
73 *status = 0;
74 return *ptr0 + (*ptr1 << 8) + (*ptr2 << 16) + (*ptr3 << 24);
75 }
76
77 psiconv_S_t psiconv_read_S(const psiconv_buffer buf, int lev, psiconv_u32 off,
78 int *length,int *status)
79 {
80 psiconv_u8 temp;
81 psiconv_S_t res;
82 int len,localstatus;
83
84 psiconv_progress(lev+1,off,"Going to read a S length indicator");
85 temp = psiconv_read_u8(buf,lev+2,off,&localstatus);
86 if (localstatus)
87 goto ERROR;
88 if ((temp & 0x03) == 0x02) {
89 res = psiconv_read_u8(buf,lev+2,off,&localstatus) >> 2;
90 if (localstatus)
91 goto ERROR;
92 len = 1;
93 psiconv_debug(lev+2,off,"Indicator (1 byte): %02x",res);
94 } else if ((temp & 0x07) == 0x03) {
95 res = psiconv_read_u16(buf,lev+2,off,&localstatus) >> 3;
96 if (localstatus)
97 goto ERROR;
98 len = 2;
99 psiconv_debug(lev+2,off,"Indicator (2 bytes): %04x",res);
100 } else {
101 psiconv_warn(lev+2,off,"S indicator: unknown encoding!");
102 psiconv_debug(lev+2,off,"Raw data first byte: %02x",temp);
103 goto ERROR;
104 }
105
106 if (length)
107 *length = len;
108 if (status)
109 *status = 0;
110
111 psiconv_progress(lev+1,off+len-1,
112 "End of S length indicator (total length: %08x)", len);
113
114 return res;
115
116 ERROR:
117 psiconv_warn(lev+1,off,"Reading of S indicator failed");
118 if (status)
119 *status = localstatus;
120 if (length)
121 *length = 0;
122 return 0;
123 }
124
125 psiconv_X_t psiconv_read_X(const psiconv_buffer buf, int lev, psiconv_u32 off,
126 int *length, int *status)
127 {
128 psiconv_u8 temp;
129 psiconv_X_t res;
130 int len,localstatus;
131
132 psiconv_progress(lev+1,off,"Going to read a X length indicator");
133 temp = psiconv_read_u8(buf,lev+2,off,&localstatus);
134 if (localstatus)
135 goto ERROR;
136 if ((temp & 0x01) == 0x00) {
137 res = psiconv_read_u8(buf,lev+2,off,&localstatus) >> 1;
138 if (localstatus)
139 goto ERROR;
140 len = 1;
141 psiconv_debug(lev+2,off,"Indicator (1 byte): %02x",res);
142 } else if ((temp & 0x03) == 0x01) {
143 res = psiconv_read_u16(buf,lev+2,off,&localstatus) >> 2;
144 if (localstatus)
145 goto ERROR;
146 len = 2;
147 psiconv_debug(lev+2,off,"Indicator (2 bytes): %04x",res);
148 } else if ((temp & 0x07) == 0x03) {
149 res = psiconv_read_u32(buf,lev+2,off,&localstatus) >> 3;
150 if (localstatus)
151 goto ERROR;
152 len = 4;
153 psiconv_debug(lev+2,off,"Indicator (4 bytes): %08x",res);
154 } else {
155 psiconv_warn(lev+2,off,"X indicator: unknown encoding!");
156 psiconv_debug(lev+2,off,"Raw data first byte: %02x",temp);
157 goto ERROR;
158 }
159
160 if (length)
161 *length = len;
162 if (status)
163 *status = 0;
164
165 psiconv_progress(lev+1,off+len-1,
166 "End of X length indicator (total length: %08x)", len);
167
168 return res;
169
170 ERROR:
171 psiconv_warn(lev+1,off,"Reading of X indicator failed");
172 if (status)
173 *status = localstatus;
174 if (length)
175 *length = 0;
176 return 0;
177 }
178
179 psiconv_length_t psiconv_read_length(const psiconv_buffer buf, int lev,
180 psiconv_u32 off, int *length, int *status)
181 {
182 psiconv_length_t res;
183 int localstatus;
184
185 res = (2.54/1440.0) * ((psiconv_s32) psiconv_read_u32(buf,lev,off,
186 &localstatus));
187 if (localstatus) {
188 psiconv_warn(lev+1,off,"Reading of length failed");
189 if (length)
190 *length = 0;
191 if (status)
192 *status = localstatus;
193 return 0;
194 }
195 psiconv_debug(lev+1,off,"Length: %f",res);
196 if (length)
197 *length = 4;
198 if (status)
199 *status = 0;
200 return res;
201 }
202
203 psiconv_size_t psiconv_read_size(const psiconv_buffer buf, int lev,
204 psiconv_u32 off, int *length, int *status)
205 {
206 psiconv_size_t res;
207 int localstatus;
208 res = ((psiconv_s32) psiconv_read_u32(buf,lev,off,&localstatus)) / 20.0;
209 if (localstatus) {
210 psiconv_warn(lev+1,off,"Reading of size failed");
211 if (length)
212 *length = 0;
213 if (status)
214 *status = localstatus;
215 return 0;
216 }
217 psiconv_debug(lev+1,off,"Size: %f",res);
218 if (status)
219 *status = 0;
220 if (length)
221 *length = 4;
222 return res;
223 }
224
225 int psiconv_parse_bool(const psiconv_buffer buf, int lev, psiconv_u32 off,
226 int *length, psiconv_bool_t *result)
227 {
228 psiconv_u8 temp;
229 int localstatus;
230 temp = psiconv_read_u8(buf,lev,off,&localstatus);
231 if (localstatus) {
232 psiconv_warn(lev+1,off,"Reading of bool failed");
233 if (length)
234 *length = 0;
235 return localstatus;
236 }
237 if (length)
238 *length = 1;
239 if (temp == 0) {
240 *result = psiconv_bool_false;
241 return 0;
242 } else if (temp == 1) {
243 *result = psiconv_bool_true;
244 return 0;
245 }
246 psiconv_warn(lev+1,off,"Unknown value for boolean");
247 psiconv_debug(lev+1,off,"Boolean value: %02x",temp);
248 *result = psiconv_bool_true;
249 return 0;
250 }
251
252 psiconv_string_t psiconv_read_string(const psiconv_buffer buf,int lev,
253 psiconv_u32 off,int *length, int *status)
254 {
255 int stringlen,i,leng,len,localstatus;
256 psiconv_string_t result;
257 char *res_copy;
258
259 psiconv_progress(lev+1,off,"Going to read a string");
260
261 stringlen = psiconv_read_S(buf,lev+2,off,&leng,&localstatus);
262 if (localstatus)
263 goto ERROR1;
264 psiconv_debug(lev+2,off,"Length: %i",stringlen);
265 len = leng;
266
267 result = malloc(stringlen + 1);
268 if (!result)
269 goto ERROR1;
270 for (i = 0; (i < stringlen) && !localstatus; i++)
271 result[i] = psiconv_read_u8(buf,lev,off+i+len,&localstatus);
272 if (localstatus)
273 goto ERROR2;
274 result[stringlen] = 0;
275 len += stringlen;
276
277 res_copy = psiconv_make_printable(result);
278 if (!res_copy)
279 goto ERROR2;
280 psiconv_debug(lev+2,off,"Contents: `%s'",res_copy);
281 free(res_copy);
282
283 if (length)
284 *length = len;
285
286 if (status)
287 *status = 0;
288
289 psiconv_progress(lev+1,off+len-1,"End of string (total length: %08x)",len);
290
291 return result;
292
293 ERROR2:
294 free(result);
295 ERROR1:
296 psiconv_warn(lev+1,off,"Reading of string failed");
297 if (status)
298 *status = localstatus;
299 if (length)
300 *length = 0;
301 return NULL;
302 }

frodo@frodo.looijaard.name
ViewVC Help
Powered by ViewVC 1.1.26