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.
27 # include <simgear_config.h>
30 #include <string.h> // for memcpy()
32 #include "lowlevel.hxx"
35 static int read_error = false ;
36 static int write_error = false ;
38 void sgClearReadError() { read_error = false; }
39 void sgClearWriteError() { write_error = false; }
40 int sgReadError() { return read_error ; }
41 int sgWriteError() { return write_error ; }
44 void sgReadChar ( gzFile fd, char *var )
46 if ( gzread ( fd, var, sizeof(char) ) != sizeof(char) ) {
52 void sgWriteChar ( gzFile fd, const char var )
54 if ( gzwrite ( fd, (void *)(&var), sizeof(char) ) != sizeof(char) ) {
60 void sgReadFloat ( gzFile fd, float *var )
62 union { float v; uint32_t u; } buf;
63 if ( gzread ( fd, &buf.u, sizeof(float) ) != sizeof(float) ) {
66 if ( sgIsBigEndian() ) {
67 sgEndianSwap( &buf.u );
73 void sgWriteFloat ( gzFile fd, const float var )
75 union { float v; uint32_t u; } buf;
77 if ( sgIsBigEndian() ) {
78 sgEndianSwap( &buf.u );
80 if ( gzwrite ( fd, (void *)(&buf.u), sizeof(float) ) != sizeof(float) ) {
86 void sgReadDouble ( gzFile fd, double *var )
88 union { double v; uint64_t u; } buf;
89 if ( gzread ( fd, &buf.u, sizeof(double) ) != sizeof(double) ) {
92 if ( sgIsBigEndian() ) {
93 sgEndianSwap( &buf.u );
99 void sgWriteDouble ( gzFile fd, const double var )
101 union { double v; uint64_t u; } buf;
103 if ( sgIsBigEndian() ) {
104 sgEndianSwap( &buf.u );
106 if ( gzwrite ( fd, (void *)(&buf.u), sizeof(double) ) != sizeof(double) ) {
112 void sgReadUInt ( gzFile fd, unsigned int *var )
114 if ( gzread ( fd, var, sizeof(unsigned int) ) != sizeof(unsigned int) ) {
117 if ( sgIsBigEndian() ) {
118 sgEndianSwap( (uint32_t *)var);
123 void sgWriteUInt ( gzFile fd, const unsigned int var )
125 if ( sgIsBigEndian() ) {
126 sgEndianSwap( (uint32_t *)&var);
128 if ( gzwrite ( fd, (void *)(&var), sizeof(unsigned int) )
129 != sizeof(unsigned int) )
136 void sgReadInt ( gzFile fd, int *var )
138 if ( gzread ( fd, var, sizeof(int) ) != sizeof(int) ) {
141 if ( sgIsBigEndian() ) {
142 sgEndianSwap( (uint32_t *)var);
147 void sgWriteInt ( gzFile fd, const int var )
149 if ( sgIsBigEndian() ) {
150 sgEndianSwap( (uint32_t *)&var);
152 if ( gzwrite ( fd, (void *)(&var), sizeof(int) ) != sizeof(int) ) {
158 void sgReadLong ( gzFile fd, int32_t *var )
160 if ( gzread ( fd, var, sizeof(int32_t) ) != sizeof(int32_t) ) {
163 if ( sgIsBigEndian() ) {
164 sgEndianSwap( (uint32_t *)var);
169 void sgWriteLong ( gzFile fd, const int32_t var )
171 if ( sgIsBigEndian() ) {
172 sgEndianSwap( (uint32_t *)&var);
174 if ( gzwrite ( fd, (void *)(&var), sizeof(int32_t) )
182 void sgReadLongLong ( gzFile fd, int64_t *var )
184 if ( gzread ( fd, var, sizeof(int64_t) ) != sizeof(int64_t) ) {
187 if ( sgIsBigEndian() ) {
188 sgEndianSwap( (uint64_t *)var);
193 void sgWriteLongLong ( gzFile fd, const int64_t var )
195 if ( sgIsBigEndian() ) {
196 sgEndianSwap( (uint64_t *)&var);
198 if ( gzwrite ( fd, (void *)(&var), sizeof(int64_t) )
206 void sgReadUShort ( gzFile fd, unsigned short *var )
208 if ( gzread ( fd, var, sizeof(unsigned short) ) != sizeof(unsigned short) ){
211 if ( sgIsBigEndian() ) {
212 sgEndianSwap( (uint16_t *)var);
217 void sgWriteUShort ( gzFile fd, const unsigned short var )
219 if ( sgIsBigEndian() ) {
220 sgEndianSwap( (uint16_t *)&var);
222 if ( gzwrite ( fd, (void *)(&var), sizeof(unsigned short) )
223 != sizeof(unsigned short) )
230 void sgReadShort ( gzFile fd, short *var )
232 if ( gzread ( fd, var, sizeof(short) ) != sizeof(short) ) {
235 if ( sgIsBigEndian() ) {
236 sgEndianSwap( (uint16_t *)var);
241 void sgWriteShort ( gzFile fd, const short var )
243 if ( sgIsBigEndian() ) {
244 sgEndianSwap( (uint16_t *)&var);
246 if ( gzwrite ( fd, (void *)(&var), sizeof(short) ) != sizeof(short) ) {
252 void sgReadFloat ( gzFile fd, const unsigned int n, float *var )
254 if ( gzread ( fd, var, sizeof(float) * n ) != (int)(sizeof(float) * n) ) {
257 if ( sgIsBigEndian() ) {
258 for ( unsigned int i = 0; i < n; ++i ) {
259 sgEndianSwap( (uint32_t *)var++);
265 void sgWriteFloat ( gzFile fd, const unsigned int n, const float *var )
267 if ( sgIsBigEndian() ) {
268 float *swab = new float[n];
270 memcpy( swab, var, sizeof(float) * n );
271 for ( unsigned int i = 0; i < n; ++i ) {
272 sgEndianSwap( (uint32_t *)ptr++);
276 if ( gzwrite ( fd, (void *)var, sizeof(float) * n )
277 != (int)(sizeof(float) * n) )
283 void sgReadDouble ( gzFile fd, const unsigned int n, double *var )
285 if ( gzread ( fd, var, sizeof(double) * n ) != (int)(sizeof(double) * n) ) {
288 if ( sgIsBigEndian() ) {
289 for ( unsigned int i = 0; i < n; ++i ) {
290 sgEndianSwap( (uint64_t *)var++);
296 void sgWriteDouble ( gzFile fd, const unsigned int n, const double *var )
298 if ( sgIsBigEndian() ) {
299 double *swab = new double[n];
301 memcpy( swab, var, sizeof(double) * n );
302 for ( unsigned int i = 0; i < n; ++i ) {
303 sgEndianSwap( (uint64_t *)ptr++);
307 if ( gzwrite ( fd, (void *)var, sizeof(double) * n )
308 != (int)(sizeof(double) * n) )
314 void sgReadBytes ( gzFile fd, const unsigned int n, void *var )
317 if ( gzread ( fd, var, n ) != (int)n ) {
322 void sgWriteBytes ( gzFile fd, const unsigned int n, const void *var )
325 if ( gzwrite ( fd, (void *)var, n ) != (int)n ) {
331 void sgReadUShort ( gzFile fd, const unsigned int n, unsigned short *var )
333 if ( gzread ( fd, var, sizeof(unsigned short) * n )
334 != (int)(sizeof(unsigned short) * n) )
338 if ( sgIsBigEndian() ) {
339 for ( unsigned int i = 0; i < n; ++i ) {
340 sgEndianSwap( (uint16_t *)var++);
346 void sgWriteUShort ( gzFile fd, const unsigned int n, const unsigned short *var )
348 if ( sgIsBigEndian() ) {
349 unsigned short *swab = new unsigned short[n];
350 unsigned short *ptr = swab;
351 memcpy( swab, var, sizeof(unsigned short) * n );
352 for ( unsigned int i = 0; i < n; ++i ) {
353 sgEndianSwap( (uint16_t *)ptr++);
357 if ( gzwrite ( fd, (void *)var, sizeof(unsigned short) * n )
358 != (int)(sizeof(unsigned short) * n) )
366 void sgReadShort ( gzFile fd, const unsigned int n, short *var )
368 if ( gzread ( fd, var, sizeof(short) * n )
369 != (int)(sizeof(short) * n) )
373 if ( sgIsBigEndian() ) {
374 for ( unsigned int i = 0; i < n; ++i ) {
375 sgEndianSwap( (uint16_t *)var++);
381 void sgWriteShort ( gzFile fd, const unsigned int n, const short *var )
383 if ( sgIsBigEndian() ) {
384 short *swab = new short[n];
386 memcpy( swab, var, sizeof(short) * n );
387 for ( unsigned int i = 0; i < n; ++i ) {
388 sgEndianSwap( (uint16_t *)ptr++);
392 if ( gzwrite ( fd, (void *)var, sizeof(short) * n )
393 != (int)(sizeof(short) * n) )
400 void sgReadUInt ( gzFile fd, const unsigned int n, unsigned int *var )
402 if ( gzread ( fd, var, sizeof(unsigned int) * n )
403 != (int)(sizeof(unsigned int) * n) )
407 if ( sgIsBigEndian() ) {
408 for ( unsigned int i = 0; i < n; ++i ) {
409 sgEndianSwap( (uint32_t *)var++);
415 void sgWriteUInt ( gzFile fd, const unsigned int n, const unsigned int *var )
417 if ( sgIsBigEndian() ) {
418 unsigned int *swab = new unsigned int[n];
419 unsigned int *ptr = swab;
420 memcpy( swab, var, sizeof(unsigned int) * n );
421 for ( unsigned int i = 0; i < n; ++i ) {
422 sgEndianSwap( (uint32_t *)ptr++);
426 if ( gzwrite ( fd, (void *)var, sizeof(unsigned int) * n )
427 != (int)(sizeof(unsigned int) * n) )
435 void sgReadInt ( gzFile fd, const unsigned int n, int *var )
437 if ( gzread ( fd, var, sizeof(int) * n )
438 != (int)(sizeof(int) * n) )
442 if ( sgIsBigEndian() ) {
443 for ( unsigned int i = 0; i < n; ++i ) {
444 sgEndianSwap( (uint32_t *)var++);
450 void sgWriteInt ( gzFile fd, const unsigned int n, const int *var )
452 if ( sgIsBigEndian() ) {
453 int *swab = new int[n];
455 memcpy( swab, var, sizeof(int) * n );
456 for ( unsigned int i = 0; i < n; ++i ) {
457 sgEndianSwap( (uint32_t *)ptr++);
461 if ( gzwrite ( fd, (void *)var, sizeof(int) * n )
462 != (int)(sizeof(int) * n) )
470 #define MAX_ENTITY_NAME_LENGTH 1024
472 void sgReadString ( gzFile fd, char **var )
475 char s [ MAX_ENTITY_NAME_LENGTH ] ;
477 for ( i = 0 ; i < MAX_ENTITY_NAME_LENGTH ; i++ ) {
478 int c = gzgetc ( fd ) ;
485 if ( i >= MAX_ENTITY_NAME_LENGTH-1 )
486 s [ MAX_ENTITY_NAME_LENGTH-1 ] = '\0' ;
492 *var = new char [ strlen(s)+1 ] ;
498 void sgWriteString ( gzFile fd, const char *var )
501 if ( gzwrite ( fd, (void *)var, strlen(var) + 1 ) ==
502 (int)(strlen(var) + 1) )