1 // lowlevel.hxx -- routines to handle lowlevel compressed binary IO of
4 // Shamelessly adapted from plib (plib.sourceforge.net) January 2001
6 // Original version Copyright (C) 2000 the plib team
7 // Local changes Copyright (C) 2000 Curtis L. Olson - curt@flightgear.org
9 // This program is free software; you can redistribute it and/or modify
10 // it under the terms of the GNU General Public License as published by
11 // the Free Software Foundation; either version 2 of the License, or
12 // (at your option) any later version.
14 // This program is distributed in the hope that it will be useful,
15 // but WITHOUT ANY WARRANTY; without even the implied warranty of
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 // GNU General Public License for more details.
19 // You should have received a copy of the GNU General Public License
20 // along with this program; if not, write to the Free Software
21 // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 #include "lowlevel.hxx"
28 static int read_error = false ;
29 static int write_error = false ;
31 void sgClearReadError() { read_error = false; }
32 void sgClearWriteError() { write_error = false; }
33 int sgReadError() { return read_error ; }
34 int sgWriteError() { return write_error ; }
36 static const int sgEndianTest = 1;
37 #define sgIsLittleEndian (*((char *) &sgEndianTest ) != 0)
38 #define sgIsBigEndian (*((char *) &sgEndianTest ) == 0)
40 static inline void sgEndianSwap(unsigned short *x) {
42 (( *x >> 8 ) & 0x00FF ) |
43 (( *x << 8 ) & 0xFF00 ) ;
46 static inline void sgEndianSwap(unsigned int *x) {
48 (( *x >> 24 ) & 0x000000FF ) |
49 (( *x >> 8 ) & 0x0000FF00 ) |
50 (( *x << 8 ) & 0x00FF0000 ) |
51 (( *x << 24 ) & 0xFF000000 ) ;
54 static inline void sgEndianSwap(unsigned long long *x) {
56 (( *x >> 56 ) & 0x00000000000000FFULL ) |
57 (( *x >> 40 ) & 0x000000000000FF00ULL ) |
58 (( *x >> 24 ) & 0x0000000000FF0000ULL ) |
59 (( *x >> 8 ) & 0x00000000FF000000ULL ) |
60 (( *x << 8 ) & 0x000000FF00000000ULL ) |
61 (( *x << 24 ) & 0x0000FF0000000000ULL ) |
62 (( *x << 40 ) & 0x00FF000000000000ULL ) |
63 (( *x << 56 ) & 0xFF00000000000000ULL ) ;
66 void sgReadChar ( gzFile fd, char *var )
68 if ( gzread ( fd, var, sizeof(char) ) != sizeof(char) ) {
74 void sgWriteChar ( gzFile fd, const char var )
76 if ( gzwrite ( fd, (void *)(&var), sizeof(char) ) != sizeof(char) ) {
82 void sgReadFloat ( gzFile fd, float *var )
84 if ( gzread ( fd, var, sizeof(float) ) != sizeof(float) ) {
87 if ( sgIsBigEndian ) {
88 sgEndianSwap( (unsigned int*)var);
93 void sgWriteFloat ( gzFile fd, const float var )
95 if ( sgIsBigEndian ) {
96 sgEndianSwap( (unsigned int*)&var);
98 if ( gzwrite ( fd, (void *)(&var), sizeof(float) ) != sizeof(float) ) {
104 void sgReadDouble ( gzFile fd, double *var )
106 if ( gzread ( fd, var, sizeof(double) ) != sizeof(double) ) {
109 if ( sgIsBigEndian ) {
110 sgEndianSwap( (unsigned long long*)var);
115 void sgWriteDouble ( gzFile fd, const double var )
117 if ( sgIsBigEndian ) {
118 sgEndianSwap( (unsigned long long*)&var);
120 if ( gzwrite ( fd, (void *)(&var), sizeof(double) ) != sizeof(double) ) {
126 void sgReadUInt ( gzFile fd, unsigned int *var )
128 if ( gzread ( fd, var, sizeof(unsigned int) ) != sizeof(unsigned int) ) {
131 if ( sgIsBigEndian ) {
132 sgEndianSwap( (unsigned int*)var);
137 void sgWriteUInt ( gzFile fd, const unsigned int var )
139 if ( sgIsBigEndian ) {
140 sgEndianSwap( (unsigned int*)&var);
142 if ( gzwrite ( fd, (void *)(&var), sizeof(unsigned int) )
143 != sizeof(unsigned int) )
150 void sgReadInt ( gzFile fd, int *var )
152 if ( gzread ( fd, var, sizeof(int) ) != sizeof(int) ) {
155 if ( sgIsBigEndian ) {
156 sgEndianSwap( (unsigned int*)var);
161 void sgWriteInt ( gzFile fd, const int var )
163 if ( sgIsBigEndian ) {
164 sgEndianSwap( (unsigned int*)&var);
166 if ( gzwrite ( fd, (void *)(&var), sizeof(int) ) != sizeof(int) ) {
172 void sgReadLong ( gzFile fd, long int *var )
174 if ( gzread ( fd, var, sizeof(long int) ) != sizeof(long int) ) {
177 if ( sgIsBigEndian ) {
178 sgEndianSwap( (unsigned int*)var);
183 void sgWriteLong ( gzFile fd, const long int var )
185 if ( sgIsBigEndian ) {
186 sgEndianSwap( (unsigned int*)&var);
188 if ( gzwrite ( fd, (void *)(&var), sizeof(long int) )
189 != sizeof(long int) )
196 void sgReadLongLong ( gzFile fd, long long int *var )
198 if ( gzread ( fd, var, sizeof(long long int) ) != sizeof(long long int) ) {
201 if ( sgIsBigEndian ) {
202 sgEndianSwap( (unsigned long long int*)var);
207 void sgWriteLongLong ( gzFile fd, const long long int var )
209 if ( sgIsBigEndian ) {
210 sgEndianSwap( (unsigned long long*)&var);
212 if ( gzwrite ( fd, (void *)(&var), sizeof(long long int) )
213 != sizeof(long long int) )
220 void sgReadUShort ( gzFile fd, unsigned short *var )
222 if ( gzread ( fd, var, sizeof(unsigned short) ) != sizeof(unsigned short) ){
225 if ( sgIsBigEndian ) {
226 sgEndianSwap( (unsigned short int*)var);
231 void sgWriteUShort ( gzFile fd, const unsigned short var )
233 if ( sgIsBigEndian ) {
234 sgEndianSwap( (unsigned short*)&var);
236 if ( gzwrite ( fd, (void *)(&var), sizeof(unsigned short) )
237 != sizeof(unsigned short) )
244 void sgReadShort ( gzFile fd, short *var )
246 if ( gzread ( fd, var, sizeof(short) ) != sizeof(short) ) {
249 if ( sgIsBigEndian ) {
250 sgEndianSwap( (unsigned short int*)var);
255 void sgWriteShort ( gzFile fd, const short var )
257 if ( sgIsBigEndian ) {
258 sgEndianSwap( (unsigned short*)&var);
260 if ( gzwrite ( fd, (void *)(&var), sizeof(short) ) != sizeof(short) ) {
266 void sgReadFloat ( gzFile fd, const unsigned int n, float *var )
268 if ( gzread ( fd, var, sizeof(float) * n ) != (int)(sizeof(float) * n) ) {
271 if ( sgIsBigEndian ) {
272 for ( unsigned int i = 0; i < n; ++i ) {
273 sgEndianSwap( (unsigned int*)var++);
279 void sgWriteFloat ( gzFile fd, const unsigned int n, const float *var )
281 if ( sgIsBigEndian ) {
282 float *swab = new float[n];
284 memcpy( swab, var, sizeof(float) * n );
285 for ( unsigned int i = 0; i < n; ++i ) {
286 sgEndianSwap( (unsigned int*)ptr++);
290 if ( gzwrite ( fd, (void *)var, sizeof(float) * n )
291 != (int)(sizeof(float) * n) )
297 void sgReadDouble ( gzFile fd, const unsigned int n, double *var )
299 if ( gzread ( fd, var, sizeof(double) * n ) != (int)(sizeof(double) * n) ) {
302 if ( sgIsBigEndian ) {
303 for ( unsigned int i = 0; i < n; ++i ) {
304 sgEndianSwap( (unsigned long long*)var++);
310 void sgWriteDouble ( gzFile fd, const unsigned int n, const double *var )
312 if ( sgIsBigEndian ) {
313 double *swab = new double[n];
315 memcpy( swab, var, sizeof(double) * n );
316 for ( unsigned int i = 0; i < n; ++i ) {
317 sgEndianSwap( (unsigned long long*)ptr++);
321 if ( gzwrite ( fd, (void *)var, sizeof(double) * n )
322 != (int)(sizeof(double) * n) )
328 void sgReadBytes ( gzFile fd, const unsigned int n, void *var )
331 if ( gzread ( fd, var, n ) != (int)n ) {
336 void sgWriteBytes ( gzFile fd, const unsigned int n, const void *var )
339 if ( gzwrite ( fd, (void *)var, n ) != (int)n ) {
345 void sgReadUShort ( gzFile fd, const unsigned int n, unsigned short *var )
347 if ( gzread ( fd, var, sizeof(unsigned short) * n )
348 != (int)(sizeof(unsigned short) * n) )
352 if ( sgIsBigEndian ) {
353 for ( unsigned int i = 0; i < n; ++i ) {
354 sgEndianSwap( (unsigned short int*)var++);
360 void sgWriteUShort ( gzFile fd, const unsigned int n, const unsigned short *var )
362 if ( sgIsBigEndian ) {
363 unsigned short *swab = new unsigned short[n];
364 unsigned short *ptr = swab;
365 memcpy( swab, var, sizeof(unsigned short) * n );
366 for ( unsigned int i = 0; i < n; ++i ) {
367 sgEndianSwap( (unsigned short*)ptr++);
371 if ( gzwrite ( fd, (void *)var, sizeof(unsigned short) * n )
372 != (int)(sizeof(unsigned short) * n) )
380 void sgReadShort ( gzFile fd, const unsigned int n, short *var )
382 if ( gzread ( fd, var, sizeof(short) * n )
383 != (int)(sizeof(short) * n) )
387 if ( sgIsBigEndian ) {
388 for ( unsigned int i = 0; i < n; ++i ) {
389 sgEndianSwap( (unsigned short int*)var++);
395 void sgWriteShort ( gzFile fd, const unsigned int n, const short *var )
397 if ( sgIsBigEndian ) {
398 short *swab = new short[n];
400 memcpy( swab, var, sizeof(short) * n );
401 for ( unsigned int i = 0; i < n; ++i ) {
402 sgEndianSwap( (unsigned short*)ptr++);
406 if ( gzwrite ( fd, (void *)var, sizeof(short) * n )
407 != (int)(sizeof(short) * n) )
414 void sgReadUInt ( gzFile fd, const unsigned int n, unsigned int *var )
416 if ( gzread ( fd, var, sizeof(unsigned int) * n )
417 != (int)(sizeof(unsigned int) * n) )
421 if ( sgIsBigEndian ) {
422 for ( unsigned int i = 0; i < n; ++i ) {
423 sgEndianSwap( (unsigned int*)var++);
429 void sgWriteUInt ( gzFile fd, const unsigned int n, const unsigned int *var )
431 if ( sgIsBigEndian ) {
432 unsigned int *swab = new unsigned int[n];
433 unsigned int *ptr = swab;
434 memcpy( swab, var, sizeof(unsigned int) * n );
435 for ( unsigned int i = 0; i < n; ++i ) {
436 sgEndianSwap( (unsigned int*)ptr++);
440 if ( gzwrite ( fd, (void *)var, sizeof(unsigned int) * n )
441 != (int)(sizeof(unsigned int) * n) )
449 void sgReadInt ( gzFile fd, const unsigned int n, int *var )
451 if ( gzread ( fd, var, sizeof(int) * n )
452 != (int)(sizeof(int) * n) )
456 if ( sgIsBigEndian ) {
457 for ( unsigned int i = 0; i < n; ++i ) {
458 sgEndianSwap( (unsigned int*)var++);
464 void sgWriteInt ( gzFile fd, const unsigned int n, const int *var )
466 if ( sgIsBigEndian ) {
467 int *swab = new int[n];
469 memcpy( swab, var, sizeof(int) * n );
470 for ( unsigned int i = 0; i < n; ++i ) {
471 sgEndianSwap( (unsigned int*)ptr++);
475 if ( gzwrite ( fd, (void *)var, sizeof(int) * n )
476 != (int)(sizeof(int) * n) )
484 #define MAX_ENTITY_NAME_LENGTH 1024
486 void sgReadString ( gzFile fd, char **var )
489 char s [ MAX_ENTITY_NAME_LENGTH ] ;
491 for ( i = 0 ; i < MAX_ENTITY_NAME_LENGTH ; i++ ) {
492 int c = gzgetc ( fd ) ;
499 if ( i >= MAX_ENTITY_NAME_LENGTH-1 )
500 s [ MAX_ENTITY_NAME_LENGTH-1 ] = '\0' ;
506 *var = new char [ strlen(s)+1 ] ;
512 void sgWriteString ( gzFile fd, const char *var )
515 if ( gzwrite ( fd, (void *)var, strlen(var) + 1 ) ==
516 (int)(strlen(var) + 1) )