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., 675 Mass Ave, Cambridge, MA 02139, 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 if ( gzread ( fd, var, sizeof(float) ) != sizeof(float) ) {
61 if ( sgIsBigEndian() ) {
62 sgEndianSwap( (unsigned int*)var);
67 void sgWriteFloat ( gzFile fd, const float var )
69 if ( sgIsBigEndian() ) {
70 sgEndianSwap( (unsigned int*)&var);
72 if ( gzwrite ( fd, (void *)(&var), sizeof(float) ) != sizeof(float) ) {
78 void sgReadDouble ( gzFile fd, double *var )
80 if ( gzread ( fd, var, sizeof(double) ) != sizeof(double) ) {
83 if ( sgIsBigEndian() ) {
84 sgEndianSwap( (uint64*)var);
89 void sgWriteDouble ( gzFile fd, const double var )
91 if ( sgIsBigEndian() ) {
92 sgEndianSwap( (uint64*)&var);
94 if ( gzwrite ( fd, (void *)(&var), sizeof(double) ) != sizeof(double) ) {
100 void sgReadUInt ( gzFile fd, unsigned int *var )
102 if ( gzread ( fd, var, sizeof(unsigned int) ) != sizeof(unsigned int) ) {
105 if ( sgIsBigEndian() ) {
106 sgEndianSwap( (unsigned int*)var);
111 void sgWriteUInt ( gzFile fd, const unsigned int var )
113 if ( sgIsBigEndian() ) {
114 sgEndianSwap( (unsigned int*)&var);
116 if ( gzwrite ( fd, (void *)(&var), sizeof(unsigned int) )
117 != sizeof(unsigned int) )
124 void sgReadInt ( gzFile fd, int *var )
126 if ( gzread ( fd, var, sizeof(int) ) != sizeof(int) ) {
129 if ( sgIsBigEndian() ) {
130 sgEndianSwap( (unsigned int*)var);
135 void sgWriteInt ( gzFile fd, const int var )
137 if ( sgIsBigEndian() ) {
138 sgEndianSwap( (unsigned int*)&var);
140 if ( gzwrite ( fd, (void *)(&var), sizeof(int) ) != sizeof(int) ) {
146 void sgReadLong ( gzFile fd, long int *var )
148 if ( gzread ( fd, var, sizeof(long int) ) != sizeof(long int) ) {
151 if ( sgIsBigEndian() ) {
152 sgEndianSwap( (unsigned int*)var);
157 void sgWriteLong ( gzFile fd, const long int var )
159 if ( sgIsBigEndian() ) {
160 sgEndianSwap( (unsigned int*)&var);
162 if ( gzwrite ( fd, (void *)(&var), sizeof(long int) )
163 != sizeof(long int) )
170 void sgReadLongLong ( gzFile fd, int64 *var )
172 if ( gzread ( fd, var, sizeof(int64) ) != sizeof(int64) ) {
175 if ( sgIsBigEndian() ) {
176 sgEndianSwap( (uint64*)var);
181 void sgWriteLongLong ( gzFile fd, const int64 var )
183 if ( sgIsBigEndian() ) {
184 sgEndianSwap( (uint64*)&var);
186 if ( gzwrite ( fd, (void *)(&var), sizeof(int64) )
194 void sgReadUShort ( gzFile fd, unsigned short *var )
196 if ( gzread ( fd, var, sizeof(unsigned short) ) != sizeof(unsigned short) ){
199 if ( sgIsBigEndian() ) {
200 sgEndianSwap( (unsigned short int*)var);
205 void sgWriteUShort ( gzFile fd, const unsigned short var )
207 if ( sgIsBigEndian() ) {
208 sgEndianSwap( (unsigned short*)&var);
210 if ( gzwrite ( fd, (void *)(&var), sizeof(unsigned short) )
211 != sizeof(unsigned short) )
218 void sgReadShort ( gzFile fd, short *var )
220 if ( gzread ( fd, var, sizeof(short) ) != sizeof(short) ) {
223 if ( sgIsBigEndian() ) {
224 sgEndianSwap( (unsigned short int*)var);
229 void sgWriteShort ( gzFile fd, const short var )
231 if ( sgIsBigEndian() ) {
232 sgEndianSwap( (unsigned short*)&var);
234 if ( gzwrite ( fd, (void *)(&var), sizeof(short) ) != sizeof(short) ) {
240 void sgReadFloat ( gzFile fd, const unsigned int n, float *var )
242 if ( gzread ( fd, var, sizeof(float) * n ) != (int)(sizeof(float) * n) ) {
245 if ( sgIsBigEndian() ) {
246 for ( unsigned int i = 0; i < n; ++i ) {
247 sgEndianSwap( (unsigned int*)var++);
253 void sgWriteFloat ( gzFile fd, const unsigned int n, const float *var )
255 if ( sgIsBigEndian() ) {
256 float *swab = new float[n];
258 memcpy( swab, var, sizeof(float) * n );
259 for ( unsigned int i = 0; i < n; ++i ) {
260 sgEndianSwap( (unsigned int*)ptr++);
264 if ( gzwrite ( fd, (void *)var, sizeof(float) * n )
265 != (int)(sizeof(float) * n) )
271 void sgReadDouble ( gzFile fd, const unsigned int n, double *var )
273 if ( gzread ( fd, var, sizeof(double) * n ) != (int)(sizeof(double) * n) ) {
276 if ( sgIsBigEndian() ) {
277 for ( unsigned int i = 0; i < n; ++i ) {
278 sgEndianSwap( (uint64*)var++);
284 void sgWriteDouble ( gzFile fd, const unsigned int n, const double *var )
286 if ( sgIsBigEndian() ) {
287 double *swab = new double[n];
289 memcpy( swab, var, sizeof(double) * n );
290 for ( unsigned int i = 0; i < n; ++i ) {
291 sgEndianSwap( (uint64*)ptr++);
295 if ( gzwrite ( fd, (void *)var, sizeof(double) * n )
296 != (int)(sizeof(double) * n) )
302 void sgReadBytes ( gzFile fd, const unsigned int n, void *var )
305 if ( gzread ( fd, var, n ) != (int)n ) {
310 void sgWriteBytes ( gzFile fd, const unsigned int n, const void *var )
313 if ( gzwrite ( fd, (void *)var, n ) != (int)n ) {
319 void sgReadUShort ( gzFile fd, const unsigned int n, unsigned short *var )
321 if ( gzread ( fd, var, sizeof(unsigned short) * n )
322 != (int)(sizeof(unsigned short) * n) )
326 if ( sgIsBigEndian() ) {
327 for ( unsigned int i = 0; i < n; ++i ) {
328 sgEndianSwap( (unsigned short int*)var++);
334 void sgWriteUShort ( gzFile fd, const unsigned int n, const unsigned short *var )
336 if ( sgIsBigEndian() ) {
337 unsigned short *swab = new unsigned short[n];
338 unsigned short *ptr = swab;
339 memcpy( swab, var, sizeof(unsigned short) * n );
340 for ( unsigned int i = 0; i < n; ++i ) {
341 sgEndianSwap( (unsigned short*)ptr++);
345 if ( gzwrite ( fd, (void *)var, sizeof(unsigned short) * n )
346 != (int)(sizeof(unsigned short) * n) )
354 void sgReadShort ( gzFile fd, const unsigned int n, short *var )
356 if ( gzread ( fd, var, sizeof(short) * n )
357 != (int)(sizeof(short) * n) )
361 if ( sgIsBigEndian() ) {
362 for ( unsigned int i = 0; i < n; ++i ) {
363 sgEndianSwap( (unsigned short int*)var++);
369 void sgWriteShort ( gzFile fd, const unsigned int n, const short *var )
371 if ( sgIsBigEndian() ) {
372 short *swab = new short[n];
374 memcpy( swab, var, sizeof(short) * n );
375 for ( unsigned int i = 0; i < n; ++i ) {
376 sgEndianSwap( (unsigned short*)ptr++);
380 if ( gzwrite ( fd, (void *)var, sizeof(short) * n )
381 != (int)(sizeof(short) * n) )
388 void sgReadUInt ( gzFile fd, const unsigned int n, unsigned int *var )
390 if ( gzread ( fd, var, sizeof(unsigned int) * n )
391 != (int)(sizeof(unsigned int) * n) )
395 if ( sgIsBigEndian() ) {
396 for ( unsigned int i = 0; i < n; ++i ) {
397 sgEndianSwap( (unsigned int*)var++);
403 void sgWriteUInt ( gzFile fd, const unsigned int n, const unsigned int *var )
405 if ( sgIsBigEndian() ) {
406 unsigned int *swab = new unsigned int[n];
407 unsigned int *ptr = swab;
408 memcpy( swab, var, sizeof(unsigned int) * n );
409 for ( unsigned int i = 0; i < n; ++i ) {
410 sgEndianSwap( (unsigned int*)ptr++);
414 if ( gzwrite ( fd, (void *)var, sizeof(unsigned int) * n )
415 != (int)(sizeof(unsigned int) * n) )
423 void sgReadInt ( gzFile fd, const unsigned int n, int *var )
425 if ( gzread ( fd, var, sizeof(int) * n )
426 != (int)(sizeof(int) * n) )
430 if ( sgIsBigEndian() ) {
431 for ( unsigned int i = 0; i < n; ++i ) {
432 sgEndianSwap( (unsigned int*)var++);
438 void sgWriteInt ( gzFile fd, const unsigned int n, const int *var )
440 if ( sgIsBigEndian() ) {
441 int *swab = new int[n];
443 memcpy( swab, var, sizeof(int) * n );
444 for ( unsigned int i = 0; i < n; ++i ) {
445 sgEndianSwap( (unsigned int*)ptr++);
449 if ( gzwrite ( fd, (void *)var, sizeof(int) * n )
450 != (int)(sizeof(int) * n) )
458 #define MAX_ENTITY_NAME_LENGTH 1024
460 void sgReadString ( gzFile fd, char **var )
463 char s [ MAX_ENTITY_NAME_LENGTH ] ;
465 for ( i = 0 ; i < MAX_ENTITY_NAME_LENGTH ; i++ ) {
466 int c = gzgetc ( fd ) ;
473 if ( i >= MAX_ENTITY_NAME_LENGTH-1 )
474 s [ MAX_ENTITY_NAME_LENGTH-1 ] = '\0' ;
480 *var = new char [ strlen(s)+1 ] ;
486 void sgWriteString ( gzFile fd, const char *var )
489 if ( gzwrite ( fd, (void *)var, strlen(var) + 1 ) ==
490 (int)(strlen(var) + 1) )