1 // lowlevel.cxx -- 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 - http://www.flightgear.org/~curt
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
26 #include <string.h> // for memcpy()
28 #include "lowlevel.hxx"
31 static int read_error = false ;
32 static int write_error = false ;
34 void sgClearReadError() { read_error = false; }
35 void sgClearWriteError() { write_error = false; }
36 int sgReadError() { return read_error ; }
37 int sgWriteError() { return write_error ; }
40 void sgReadChar ( gzFile fd, char *var )
42 if ( gzread ( fd, var, sizeof(char) ) != sizeof(char) ) {
48 void sgWriteChar ( gzFile fd, const char var )
50 if ( gzwrite ( fd, (void *)(&var), sizeof(char) ) != sizeof(char) ) {
56 void sgReadFloat ( gzFile fd, float *var )
58 union { float v; uint32_t u; } buf;
59 if ( gzread ( fd, &buf.u, sizeof(float) ) != sizeof(float) ) {
62 if ( sgIsBigEndian() ) {
63 sgEndianSwap( &buf.u );
69 void sgWriteFloat ( gzFile fd, const float var )
71 union { float v; uint32_t u; } buf;
73 if ( sgIsBigEndian() ) {
74 sgEndianSwap( &buf.u );
76 if ( gzwrite ( fd, (void *)(&buf.u), sizeof(float) ) != sizeof(float) ) {
82 void sgReadDouble ( gzFile fd, double *var )
84 union { double v; uint64_t u; } buf;
85 if ( gzread ( fd, &buf.u, sizeof(double) ) != sizeof(double) ) {
88 if ( sgIsBigEndian() ) {
89 sgEndianSwap( &buf.u );
95 void sgWriteDouble ( gzFile fd, const double var )
97 union { double v; uint64_t u; } buf;
99 if ( sgIsBigEndian() ) {
100 sgEndianSwap( &buf.u );
102 if ( gzwrite ( fd, (void *)(&buf.u), sizeof(double) ) != sizeof(double) ) {
108 void sgReadUInt ( gzFile fd, unsigned int *var )
110 if ( gzread ( fd, var, sizeof(unsigned int) ) != sizeof(unsigned int) ) {
113 if ( sgIsBigEndian() ) {
114 sgEndianSwap( (uint32_t *)var);
119 void sgWriteUInt ( gzFile fd, const unsigned int var )
121 if ( sgIsBigEndian() ) {
122 sgEndianSwap( (uint32_t *)&var);
124 if ( gzwrite ( fd, (void *)(&var), sizeof(unsigned int) )
125 != sizeof(unsigned int) )
132 void sgReadInt ( gzFile fd, int *var )
134 if ( gzread ( fd, var, sizeof(int) ) != sizeof(int) ) {
137 if ( sgIsBigEndian() ) {
138 sgEndianSwap( (uint32_t *)var);
143 void sgWriteInt ( gzFile fd, const int var )
145 if ( sgIsBigEndian() ) {
146 sgEndianSwap( (uint32_t *)&var);
148 if ( gzwrite ( fd, (void *)(&var), sizeof(int) ) != sizeof(int) ) {
154 void sgReadLong ( gzFile fd, int32_t *var )
156 if ( gzread ( fd, var, sizeof(int32_t) ) != sizeof(int32_t) ) {
159 if ( sgIsBigEndian() ) {
160 sgEndianSwap( (uint32_t *)var);
165 void sgWriteLong ( gzFile fd, const int32_t var )
167 if ( sgIsBigEndian() ) {
168 sgEndianSwap( (uint32_t *)&var);
170 if ( gzwrite ( fd, (void *)(&var), sizeof(int32_t) )
178 void sgReadLongLong ( gzFile fd, int64_t *var )
180 if ( gzread ( fd, var, sizeof(int64_t) ) != sizeof(int64_t) ) {
183 if ( sgIsBigEndian() ) {
184 sgEndianSwap( (uint64_t *)var);
189 void sgWriteLongLong ( gzFile fd, const int64_t var )
191 if ( sgIsBigEndian() ) {
192 sgEndianSwap( (uint64_t *)&var);
194 if ( gzwrite ( fd, (void *)(&var), sizeof(int64_t) )
202 void sgReadUShort ( gzFile fd, unsigned short *var )
204 if ( gzread ( fd, var, sizeof(unsigned short) ) != sizeof(unsigned short) ){
207 if ( sgIsBigEndian() ) {
208 sgEndianSwap( (uint16_t *)var);
213 void sgWriteUShort ( gzFile fd, const unsigned short var )
215 if ( sgIsBigEndian() ) {
216 sgEndianSwap( (uint16_t *)&var);
218 if ( gzwrite ( fd, (void *)(&var), sizeof(unsigned short) )
219 != sizeof(unsigned short) )
226 void sgReadShort ( gzFile fd, short *var )
228 if ( gzread ( fd, var, sizeof(short) ) != sizeof(short) ) {
231 if ( sgIsBigEndian() ) {
232 sgEndianSwap( (uint16_t *)var);
237 void sgWriteShort ( gzFile fd, const short var )
239 if ( sgIsBigEndian() ) {
240 sgEndianSwap( (uint16_t *)&var);
242 if ( gzwrite ( fd, (void *)(&var), sizeof(short) ) != sizeof(short) ) {
248 void sgReadFloat ( gzFile fd, const unsigned int n, float *var )
250 if ( gzread ( fd, var, sizeof(float) * n ) != (int)(sizeof(float) * n) ) {
253 if ( sgIsBigEndian() ) {
254 for ( unsigned int i = 0; i < n; ++i ) {
255 sgEndianSwap( (uint32_t *)var++);
261 void sgWriteFloat ( gzFile fd, const unsigned int n, const float *var )
263 if ( sgIsBigEndian() ) {
264 float *swab = new float[n];
266 memcpy( swab, var, sizeof(float) * n );
267 for ( unsigned int i = 0; i < n; ++i ) {
268 sgEndianSwap( (uint32_t *)ptr++);
272 if ( gzwrite ( fd, (void *)var, sizeof(float) * n )
273 != (int)(sizeof(float) * n) )
279 void sgReadDouble ( gzFile fd, const unsigned int n, double *var )
281 if ( gzread ( fd, var, sizeof(double) * n ) != (int)(sizeof(double) * n) ) {
284 if ( sgIsBigEndian() ) {
285 for ( unsigned int i = 0; i < n; ++i ) {
286 sgEndianSwap( (uint64_t *)var++);
292 void sgWriteDouble ( gzFile fd, const unsigned int n, const double *var )
294 if ( sgIsBigEndian() ) {
295 double *swab = new double[n];
297 memcpy( swab, var, sizeof(double) * n );
298 for ( unsigned int i = 0; i < n; ++i ) {
299 sgEndianSwap( (uint64_t *)ptr++);
303 if ( gzwrite ( fd, (void *)var, sizeof(double) * n )
304 != (int)(sizeof(double) * n) )
310 void sgReadBytes ( gzFile fd, const unsigned int n, void *var )
313 if ( gzread ( fd, var, n ) != (int)n ) {
318 void sgWriteBytes ( gzFile fd, const unsigned int n, const void *var )
321 if ( gzwrite ( fd, (void *)var, n ) != (int)n ) {
327 void sgReadUShort ( gzFile fd, const unsigned int n, unsigned short *var )
329 if ( gzread ( fd, var, sizeof(unsigned short) * n )
330 != (int)(sizeof(unsigned short) * n) )
334 if ( sgIsBigEndian() ) {
335 for ( unsigned int i = 0; i < n; ++i ) {
336 sgEndianSwap( (uint16_t *)var++);
342 void sgWriteUShort ( gzFile fd, const unsigned int n, const unsigned short *var )
344 if ( sgIsBigEndian() ) {
345 unsigned short *swab = new unsigned short[n];
346 unsigned short *ptr = swab;
347 memcpy( swab, var, sizeof(unsigned short) * n );
348 for ( unsigned int i = 0; i < n; ++i ) {
349 sgEndianSwap( (uint16_t *)ptr++);
353 if ( gzwrite ( fd, (void *)var, sizeof(unsigned short) * n )
354 != (int)(sizeof(unsigned short) * n) )
362 void sgReadShort ( gzFile fd, const unsigned int n, short *var )
364 if ( gzread ( fd, var, sizeof(short) * n )
365 != (int)(sizeof(short) * n) )
369 if ( sgIsBigEndian() ) {
370 for ( unsigned int i = 0; i < n; ++i ) {
371 sgEndianSwap( (uint16_t *)var++);
377 void sgWriteShort ( gzFile fd, const unsigned int n, const short *var )
379 if ( sgIsBigEndian() ) {
380 short *swab = new short[n];
382 memcpy( swab, var, sizeof(short) * n );
383 for ( unsigned int i = 0; i < n; ++i ) {
384 sgEndianSwap( (uint16_t *)ptr++);
388 if ( gzwrite ( fd, (void *)var, sizeof(short) * n )
389 != (int)(sizeof(short) * n) )
396 void sgReadUInt ( gzFile fd, const unsigned int n, unsigned int *var )
398 if ( gzread ( fd, var, sizeof(unsigned int) * n )
399 != (int)(sizeof(unsigned int) * n) )
403 if ( sgIsBigEndian() ) {
404 for ( unsigned int i = 0; i < n; ++i ) {
405 sgEndianSwap( (uint32_t *)var++);
411 void sgWriteUInt ( gzFile fd, const unsigned int n, const unsigned int *var )
413 if ( sgIsBigEndian() ) {
414 unsigned int *swab = new unsigned int[n];
415 unsigned int *ptr = swab;
416 memcpy( swab, var, sizeof(unsigned int) * n );
417 for ( unsigned int i = 0; i < n; ++i ) {
418 sgEndianSwap( (uint32_t *)ptr++);
422 if ( gzwrite ( fd, (void *)var, sizeof(unsigned int) * n )
423 != (int)(sizeof(unsigned int) * n) )
431 void sgReadInt ( gzFile fd, const unsigned int n, int *var )
433 if ( gzread ( fd, var, sizeof(int) * n )
434 != (int)(sizeof(int) * n) )
438 if ( sgIsBigEndian() ) {
439 for ( unsigned int i = 0; i < n; ++i ) {
440 sgEndianSwap( (uint32_t *)var++);
446 void sgWriteInt ( gzFile fd, const unsigned int n, const int *var )
448 if ( sgIsBigEndian() ) {
449 int *swab = new int[n];
451 memcpy( swab, var, sizeof(int) * n );
452 for ( unsigned int i = 0; i < n; ++i ) {
453 sgEndianSwap( (uint32_t *)ptr++);
457 if ( gzwrite ( fd, (void *)var, sizeof(int) * n )
458 != (int)(sizeof(int) * n) )
466 #define MAX_ENTITY_NAME_LENGTH 1024
468 void sgReadString ( gzFile fd, char **var )
471 char s [ MAX_ENTITY_NAME_LENGTH ] ;
473 for ( i = 0 ; i < MAX_ENTITY_NAME_LENGTH ; i++ ) {
474 int c = gzgetc ( fd ) ;
481 if ( i >= MAX_ENTITY_NAME_LENGTH-1 )
482 s [ MAX_ENTITY_NAME_LENGTH-1 ] = '\0' ;
488 *var = new char [ strlen(s)+1 ] ;
494 void sgWriteString ( gzFile fd, const char *var )
497 if ( gzwrite ( fd, (void *)var, strlen(var) + 1 ) ==
498 (int)(strlen(var) + 1) )