]> de.git.xonotic.org Git - xonotic/netradiant.git/blob - libs/picomodel/lwo/lwio.c
uncrustify! now the code is only ugly on the *inside*
[xonotic/netradiant.git] / libs / picomodel / lwo / lwio.c
1 /*
2    ======================================================================
3    lwio.c
4
5    Functions for reading basic LWO2 data types.
6
7    Ernie Wright  17 Sep 00
8    ====================================================================== */
9
10 #include "../picointernal.h"
11 #include "lwo2.h"
12
13
14 /*
15    ======================================================================
16    flen
17
18    This accumulates a count of the number of bytes read.  Callers can set
19    it at the beginning of a sequence of reads and then retrieve it to get
20    the number of bytes actually read.  If one of the I/O functions fails,
21    flen is set to an error code, after which the I/O functions ignore
22    read requests until flen is reset.
23    ====================================================================== */
24
25 #define INT_MIN     ( -2147483647 - 1 ) /* minimum (signed) int value */
26 #define FLEN_ERROR INT_MIN
27
28 static int flen;
29
30 void set_flen( int i ) { flen = i; }
31
32 int get_flen( void ) { return flen; }
33
34
35 #ifdef _WIN32
36 /*
37    =====================================================================
38    revbytes()
39
40    Reverses byte order in place.
41
42    INPUTS
43    bp       bytes to reverse
44    elsize   size of the underlying data type
45    elcount  number of elements to swap
46
47    RESULTS
48    Reverses the byte order in each of elcount elements.
49
50    This only needs to be defined on little-endian platforms, most
51    notably Windows.  lwo2.h replaces this with a #define on big-endian
52    platforms.
53    ===================================================================== */
54
55 void revbytes( void *bp, int elsize, int elcount ){
56         register unsigned char *p, *q;
57
58         p = ( unsigned char * ) bp;
59
60         if ( elsize == 2 ) {
61                 q = p + 1;
62                 while ( elcount-- ) {
63                         *p ^= *q;
64                         *q ^= *p;
65                         *p ^= *q;
66                         p += 2;
67                         q += 2;
68                 }
69                 return;
70         }
71
72         while ( elcount-- ) {
73                 q = p + elsize - 1;
74                 while ( p < q ) {
75                         *p ^= *q;
76                         *q ^= *p;
77                         *p ^= *q;
78                         ++p;
79                         --q;
80                 }
81                 p += elsize >> 1;
82         }
83 }
84 #endif
85
86
87 void *getbytes( picoMemStream_t *fp, int size ){
88         void *data;
89
90         if ( flen == FLEN_ERROR ) {
91                 return NULL;
92         }
93         if ( size < 0 ) {
94                 flen = FLEN_ERROR;
95                 return NULL;
96         }
97         data = _pico_alloc( size );
98         if ( !data ) {
99                 flen = FLEN_ERROR;
100                 return NULL;
101         }
102         if ( 1 != _pico_memstream_read( fp, data, size ) ) {
103                 flen = FLEN_ERROR;
104                 _pico_free( data );
105                 return NULL;
106         }
107
108         flen += size;
109         return data;
110 }
111
112
113 void skipbytes( picoMemStream_t *fp, int n ){
114         if ( flen == FLEN_ERROR ) {
115                 return;
116         }
117         if ( _pico_memstream_seek( fp, n, PICO_SEEK_CUR ) ) {
118                 flen = FLEN_ERROR;
119         }
120         else{
121                 flen += n;
122         }
123 }
124
125
126 int getI1( picoMemStream_t *fp ){
127         int i;
128
129         if ( flen == FLEN_ERROR ) {
130                 return 0;
131         }
132         i = _pico_memstream_getc( fp );
133         if ( i < 0 ) {
134                 flen = FLEN_ERROR;
135                 return 0;
136         }
137         if ( i > 127 ) {
138                 i -= 256;
139         }
140         flen += 1;
141         return i;
142 }
143
144
145 short getI2( picoMemStream_t *fp ){
146         short i;
147
148         if ( flen == FLEN_ERROR ) {
149                 return 0;
150         }
151         if ( 1 != _pico_memstream_read( fp, &i, 2 ) ) {
152                 flen = FLEN_ERROR;
153                 return 0;
154         }
155         revbytes( &i, 2, 1 );
156         flen += 2;
157         return i;
158 }
159
160
161 int getI4( picoMemStream_t *fp ){
162         int i;
163
164         if ( flen == FLEN_ERROR ) {
165                 return 0;
166         }
167         if ( 1 != _pico_memstream_read( fp, &i, 4 ) ) {
168                 flen = FLEN_ERROR;
169                 return 0;
170         }
171         revbytes( &i, 4, 1 );
172         flen += 4;
173         return i;
174 }
175
176
177 unsigned char getU1( picoMemStream_t *fp ){
178         int i;
179
180         if ( flen == FLEN_ERROR ) {
181                 return 0;
182         }
183         i = _pico_memstream_getc( fp );
184         if ( i < 0 ) {
185                 flen = FLEN_ERROR;
186                 return 0;
187         }
188         flen += 1;
189         return i;
190 }
191
192
193 unsigned short getU2( picoMemStream_t *fp ){
194         unsigned short i;
195
196         if ( flen == FLEN_ERROR ) {
197                 return 0;
198         }
199         if ( 1 != _pico_memstream_read( fp, &i, 2 ) ) {
200                 flen = FLEN_ERROR;
201                 return 0;
202         }
203         revbytes( &i, 2, 1 );
204         flen += 2;
205         return i;
206 }
207
208
209 unsigned int getU4( picoMemStream_t *fp ){
210         unsigned int i;
211
212         if ( flen == FLEN_ERROR ) {
213                 return 0;
214         }
215         if ( 1 != _pico_memstream_read( fp, &i, 4 ) ) {
216                 flen = FLEN_ERROR;
217                 return 0;
218         }
219         revbytes( &i, 4, 1 );
220         flen += 4;
221         return i;
222 }
223
224
225 int getVX( picoMemStream_t *fp ){
226         int i, c;
227
228         if ( flen == FLEN_ERROR ) {
229                 return 0;
230         }
231
232         c = _pico_memstream_getc( fp );
233         if ( c != 0xFF ) {
234                 i = c << 8;
235                 c = _pico_memstream_getc( fp );
236                 i |= c;
237                 flen += 2;
238         }
239         else {
240                 c = _pico_memstream_getc( fp );
241                 i = c << 16;
242                 c = _pico_memstream_getc( fp );
243                 i |= c << 8;
244                 c = _pico_memstream_getc( fp );
245                 i |= c;
246                 flen += 4;
247         }
248
249         if ( _pico_memstream_error( fp ) ) {
250                 flen = FLEN_ERROR;
251                 return 0;
252         }
253         return i;
254 }
255
256
257 float getF4( picoMemStream_t *fp ){
258         float f;
259
260         if ( flen == FLEN_ERROR ) {
261                 return 0.0f;
262         }
263         if ( 1 != _pico_memstream_read( fp, &f, 4 ) ) {
264                 flen = FLEN_ERROR;
265                 return 0.0f;
266         }
267         revbytes( &f, 4, 1 );
268         flen += 4;
269         return f;
270 }
271
272
273 char *getS0( picoMemStream_t *fp ){
274         char *s;
275         int i, c, len, pos;
276
277         if ( flen == FLEN_ERROR ) {
278                 return NULL;
279         }
280
281         pos = _pico_memstream_tell( fp );
282         for ( i = 1; ; i++ ) {
283                 c = _pico_memstream_getc( fp );
284                 if ( c <= 0 ) {
285                         break;
286                 }
287         }
288         if ( c < 0 ) {
289                 flen = FLEN_ERROR;
290                 return NULL;
291         }
292
293         if ( i == 1 ) {
294                 if ( _pico_memstream_seek( fp, pos + 2, PICO_SEEK_SET ) ) {
295                         flen = FLEN_ERROR;
296                 }
297                 else{
298                         flen += 2;
299                 }
300                 return NULL;
301         }
302
303         len = i + ( i & 1 );
304         s = _pico_alloc( len );
305         if ( !s ) {
306                 flen = FLEN_ERROR;
307                 return NULL;
308         }
309
310         if ( _pico_memstream_seek( fp, pos, PICO_SEEK_SET ) ) {
311                 flen = FLEN_ERROR;
312                 return NULL;
313         }
314         if ( 1 != _pico_memstream_read( fp, s, len ) ) {
315                 flen = FLEN_ERROR;
316                 return NULL;
317         }
318
319         flen += len;
320         return s;
321 }
322
323
324 int sgetI1( unsigned char **bp ){
325         int i;
326
327         if ( flen == FLEN_ERROR ) {
328                 return 0;
329         }
330         i = **bp;
331         if ( i > 127 ) {
332                 i -= 256;
333         }
334         flen += 1;
335         ( *bp )++;
336         return i;
337 }
338
339
340 short sgetI2( unsigned char **bp ){
341         short i;
342
343         if ( flen == FLEN_ERROR ) {
344                 return 0;
345         }
346         memcpy( &i, *bp, 2 );
347         revbytes( &i, 2, 1 );
348         flen += 2;
349         *bp += 2;
350         return i;
351 }
352
353
354 int sgetI4( unsigned char **bp ){
355         int i;
356
357         if ( flen == FLEN_ERROR ) {
358                 return 0;
359         }
360         memcpy( &i, *bp, 4 );
361         revbytes( &i, 4, 1 );
362         flen += 4;
363         *bp += 4;
364         return i;
365 }
366
367
368 unsigned char sgetU1( unsigned char **bp ){
369         unsigned char c;
370
371         if ( flen == FLEN_ERROR ) {
372                 return 0;
373         }
374         c = **bp;
375         flen += 1;
376         ( *bp )++;
377         return c;
378 }
379
380
381 unsigned short sgetU2( unsigned char **bp ){
382         unsigned char *buf = *bp;
383         unsigned short i;
384
385         if ( flen == FLEN_ERROR ) {
386                 return 0;
387         }
388         i = ( buf[ 0 ] << 8 ) | buf[ 1 ];
389         flen += 2;
390         *bp += 2;
391         return i;
392 }
393
394
395 unsigned int sgetU4( unsigned char **bp ){
396         unsigned int i;
397
398         if ( flen == FLEN_ERROR ) {
399                 return 0;
400         }
401         memcpy( &i, *bp, 4 );
402         revbytes( &i, 4, 1 );
403         flen += 4;
404         *bp += 4;
405         return i;
406 }
407
408
409 int sgetVX( unsigned char **bp ){
410         unsigned char *buf = *bp;
411         int i;
412
413         if ( flen == FLEN_ERROR ) {
414                 return 0;
415         }
416
417         if ( buf[ 0 ] != 0xFF ) {
418                 i = buf[ 0 ] << 8 | buf[ 1 ];
419                 flen += 2;
420                 *bp += 2;
421         }
422         else {
423                 i = ( buf[ 1 ] << 16 ) | ( buf[ 2 ] << 8 ) | buf[ 3 ];
424                 flen += 4;
425                 *bp += 4;
426         }
427         return i;
428 }
429
430
431 float sgetF4( unsigned char **bp ){
432         float f;
433
434         if ( flen == FLEN_ERROR ) {
435                 return 0.0f;
436         }
437         memcpy( &f, *bp, 4 );
438         revbytes( &f, 4, 1 );
439         flen += 4;
440         *bp += 4;
441         return f;
442 }
443
444
445 char *sgetS0( unsigned char **bp ){
446         char *s;
447         unsigned char *buf = *bp;
448         int len;
449
450         if ( flen == FLEN_ERROR ) {
451                 return NULL;
452         }
453
454         len = strlen( buf ) + 1;
455         if ( len == 1 ) {
456                 flen += 2;
457                 *bp += 2;
458                 return NULL;
459         }
460         len += len & 1;
461         s = _pico_alloc( len );
462         if ( !s ) {
463                 flen = FLEN_ERROR;
464                 return NULL;
465         }
466
467         memcpy( s, buf, len );
468         flen += len;
469         *bp += len;
470         return s;
471 }