00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #ifdef _MSC_VER
00014 # pragma warning(disable:4786) // >255 characters in debug information
00015 #endif
00016
00017 #include <iostream>
00018 #include <cstdlib>
00019 #include <cstring>
00020
00021 #include "zlib.h"
00022
00023 #include "SIO_block.h"
00024 #include "SIO_definitions.h"
00025 #include "SIO_functions.h"
00026 #include "SIO_record.h"
00027 #include "SIO_recordManager.h"
00028 #include "SIO_stream.h"
00029
00030
00031
00032 static unsigned int
00033 SIO_align = 0x00000003,
00034 SIO_mark_record = 0xabadcafe;
00035
00036
00037
00038
00039 SIO_stream::SIO_stream
00040 (
00041 const char* i_name,
00042 unsigned int i_reserve,
00043 SIO_verbosity i_verbosity
00044 )
00045 {
00046
00047 bufloc = NULL;
00048 buffer = NULL;
00049 bufmax = NULL;
00050 recmax = NULL;
00051 blkmax = NULL;
00052
00053 cmploc = NULL;
00054 cmpmax = NULL;
00055 z_strm = NULL;
00056
00057 name = i_name;
00058 handle = NULL;
00059
00060 mode = SIO_MODE_UNDEFINED;
00061 reserve = i_reserve;
00062 state = SIO_STATE_CLOSED;
00063 verbosity = i_verbosity;
00064
00065 compLevel = Z_DEFAULT_COMPRESSION ;
00066 }
00067
00068
00069
00070
00071 SIO_stream::~SIO_stream()
00072 {
00073
00074
00075
00076
00077 if( state != SIO_STATE_CLOSED )
00078 close();
00079
00080
00081
00082
00083 return;
00084 }
00085
00086
00087
00088
00089 unsigned int SIO_stream::flush()
00090 {
00091
00092
00093
00094 if( state == SIO_STATE_CLOSED )
00095 {
00096 if( verbosity >= SIO_ERRORS )
00097 {
00098 std::cout << "SIO: [" << name << "//] "
00099 << "Not open"
00100 << std::endl;
00101 }
00102 return( SIO_STREAM_NOTOPEN );
00103 }
00104 int rc = FFLUSH( handle );
00105 return (rc == 0) ? SIO_STREAM_SUCCESS : SIO_STREAM_BADWRITE;
00106 }
00107
00108
00109
00110
00111 unsigned int SIO_stream::close()
00112 {
00113
00114
00115
00116
00117 int
00118 z_stat;
00119
00120 unsigned int
00121 status;
00122
00123
00124
00125
00126 if( state == SIO_STATE_CLOSED )
00127 {
00128 if( verbosity >= SIO_ERRORS )
00129 {
00130 std::cout << "SIO: [" << name << "//] "
00131 << "Not open"
00132 << std::endl;
00133 }
00134 return( SIO_STREAM_NOTOPEN );
00135 }
00136
00137
00138
00139
00140 status = SIO_STREAM_SUCCESS;
00141
00142
00143
00144
00145 delete pointedAt;
00146 delete pointerTo;
00147
00148
00149
00150
00151 if( z_strm != NULL )
00152 {
00153 z_stat = (mode == SIO_MODE_READ) ? inflateEnd( z_strm )
00154 : deflateEnd( z_strm );
00155
00156 if( z_stat != Z_OK )
00157 {
00158 status = SIO_STREAM_BADCOMPRESS;
00159 if( verbosity >= SIO_ERRORS )
00160 {
00161 std::cout << "SIO: [" << name << "//] "
00162 << "ZLIB error number " << z_stat
00163 << std::endl;
00164
00165 std::cout << "SIO: [" << name << "//] "
00166 << "Compression de-initialization failed"
00167 << std::endl;
00168 }
00169 }
00170 free( z_strm );
00171 z_strm = NULL;
00172 }
00173
00174
00175
00176
00177 if( cmploc != NULL )
00178 {
00179 free( cmploc );
00180 cmploc = NULL;
00181 cmpmax = NULL;
00182 }
00183
00184
00185
00186
00187 if( bufloc != NULL )
00188 {
00189 free( bufloc );
00190 bufloc = NULL;
00191 buffer = NULL;
00192 bufmax = NULL;
00193 recmax = NULL;
00194 blkmax = NULL;
00195 }
00196
00197
00198
00199
00200 if( FCLOSE( handle ) == EOF )
00201 {
00202 status = SIO_STREAM_GOTEOF;
00203 if( verbosity >= SIO_ERRORS )
00204 {
00205 std::cout << "SIO: [" << name << "//] "
00206 << "EOF on close"
00207 << std::endl;
00208 }
00209 }
00210 else
00211 {
00212 }
00213 filename.erase( filename.begin(), filename.end() );
00214 handle = NULL;
00215
00216
00217
00218
00219 mode = SIO_MODE_UNDEFINED;
00220 state = SIO_STATE_CLOSED;
00221
00222
00223
00224
00225 if( status == SIO_STREAM_SUCCESS )
00226 {
00227 if( verbosity >= SIO_ALL )
00228 {
00229 std::cout << "SIO: [" << name << "//] "
00230 << "Closed"
00231 << std::endl;
00232 }
00233 }
00234
00235
00236
00237
00238 return( status );
00239 }
00240
00241
00242
00243
00244 void SIO_stream::dump
00245 (
00246 unsigned int offset,
00247 unsigned int length
00248 )
00249 {
00250
00251
00252
00253
00254 unsigned int
00255 count;
00256
00257 char
00258 *ascpnt,
00259 *hexpnt,
00260 outbuf[77];
00261
00262 unsigned char
00263 *dmpbeg,
00264 *dmpend;
00265
00266 static char
00267 hex[16] = { '0', '1', '2', '3', '4', '5', '6', '7',
00268 '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
00269
00270
00271
00272
00273 printf( "\nDump buffer of stream %s\n\n", name.c_str() );
00274
00275 if( buffer == NULL )
00276 {
00277 printf( "No buffer associated with stream %s\n", name.c_str() );
00278 return;
00279 }
00280
00281
00282
00283
00284 dmpbeg = bufloc + offset;
00285 if( dmpbeg >= bufmax )
00286 {
00287 printf( "Offset beyond end of buffer\n");
00288 return;
00289 }
00290
00291
00292
00293
00294 dmpend = dmpbeg + length;
00295 if( dmpend > bufmax )
00296 dmpend = bufmax;
00297
00298
00299
00300
00301 printf(" Start address: %8d (0x%08x)\n", bufloc, bufloc );
00302 count = buffer - bufloc;
00303 printf(" Current address: %8d (0x%08x) Offset: %8d (0x%08x)\n",
00304 buffer, buffer, count, count );
00305 count = bufmax - bufloc;
00306 printf(" End address: %8d (0x%08x) Offset: %8d (0x%08x)\n",
00307 bufmax, bufmax, count, count );
00308
00309
00310
00311
00312 printf("\n --Offset:Address-");
00313 printf( " -Hex------------------------------");
00314 printf( " -ASCII----------\n");
00315
00316
00317
00318
00319
00320
00321
00322 memset( &outbuf[ 0], ' ', sizeof( outbuf ) );
00323 sprintf( &outbuf[ 1], "%8d", offset );
00324 sprintf( &outbuf[10], "%08x", dmpbeg );
00325 outbuf[ 9] = ':';
00326 outbuf[18] = ' ';
00327 outbuf[76] = '\0';
00328 hexpnt = &outbuf[22];
00329 ascpnt = &outbuf[60];
00330 count = 0;
00331
00332 while( dmpbeg < dmpend )
00333 {
00334
00335 *hexpnt++ = hex[ ((*dmpbeg >> 4) & 15) ];
00336 *hexpnt++ = hex[ ( *dmpbeg & 15) ];
00337 if( (count & 0x3) == 3 ) hexpnt++;
00338
00339 if( isprint( *dmpbeg ) ) *ascpnt++ = *dmpbeg;
00340 else *ascpnt++ = '.';
00341
00342 count++;
00343 offset++;
00344 dmpbeg++;
00345
00346 if( count == 16 )
00347 {
00348 printf( "%s\n", outbuf );
00349
00350 memset( &outbuf[ 0], ' ', sizeof( outbuf ) );
00351 sprintf( &outbuf[ 1], "%8d", offset );
00352 sprintf( &outbuf[10], "%08x", dmpbeg );
00353 outbuf[ 9] = ':';
00354 outbuf[18] = ' ';
00355 outbuf[76] = '\0';
00356 hexpnt = &outbuf[22];
00357 ascpnt = &outbuf[60];
00358 count = 0;
00359 }
00360 }
00361
00362 if( count != 0 )
00363 printf( "%s\n", outbuf );
00364
00365
00366
00367
00368 return;
00369 }
00370
00371
00372
00373
00374 std::string* SIO_stream::getName() { return( &name ); }
00375
00376
00377
00378
00379 std::string* SIO_stream::getFilename() { return( &filename ); }
00380
00381
00382
00383
00384 SIO_stream_mode SIO_stream::getMode() { return( mode ); }
00385
00386
00387
00388
00389 SIO_stream_state SIO_stream::getState() { return( state ); }
00390
00391
00392
00393
00394 SIO_verbosity SIO_stream::getVerbosity() { return( verbosity ); }
00395
00396
00397
00398
00399
00400 void SIO_stream::setCompressionLevel(int level) {
00401
00402
00403 if( level < 0 )
00404
00405 compLevel = Z_DEFAULT_COMPRESSION ;
00406
00407 else if( level > 9 )
00408
00409 compLevel = 9 ;
00410
00411 else
00412
00413 compLevel = level ;
00414
00415 }
00416
00417
00418
00419
00420
00421
00422 unsigned int SIO_stream::open
00423 (
00424 const char* i_filename,
00425 SIO_stream_mode i_mode
00426 )
00427 {
00428
00429
00430
00431
00432 int
00433 z_stat;
00434
00435 static char
00436 SIO_filemode[4][3] = { "rb", "wb", "ab","r+" };
00437
00438
00439
00440
00441 if( state == SIO_STATE_OPEN || state == SIO_STATE_ERROR )
00442 {
00443 if( verbosity >= SIO_ERRORS )
00444 {
00445 std::cout << "SIO: [" << name << "//] "
00446 << "Already open"
00447 << std::endl;
00448 }
00449 return( SIO_STREAM_ALREADYOPEN );
00450 }
00451
00452
00453
00454
00455 if( i_mode == SIO_MODE_UNDEFINED )
00456 {
00457 if( verbosity >= SIO_ERRORS )
00458 {
00459 std::cout << "SIO: [" << name << "//] "
00460 << "Cannot open in mode SIO_MODE_UNDEFINED"
00461 << std::endl;
00462 }
00463 return( SIO_STREAM_BADMODE );
00464 }
00465
00466
00467
00468
00469 if( (handle = FOPEN( i_filename, SIO_filemode[i_mode] )) == NULL )
00470 {
00471 if( verbosity >= SIO_ERRORS )
00472 {
00473 std::cout << "SIO: [" << name << "//] "
00474 << "Cannot open file "
00475 << i_filename
00476 << std::endl;
00477 }
00478 return( SIO_STREAM_OPENFAIL );
00479 }
00480
00481
00482
00483
00484 filename = i_filename;
00485 mode = i_mode;
00486 state = SIO_STATE_OPEN;
00487
00488 if( verbosity >= SIO_ALL )
00489 {
00490 std::cout << "SIO: [" << name << "//] "
00491 << "Opened file "
00492 << i_filename
00493 << std::endl;
00494 }
00495
00496
00497
00498
00499 buffer = NULL;
00500 bufmax = NULL;
00501 bufloc = static_cast<unsigned char*>(malloc( reserve ));
00502 if( bufloc == NULL )
00503 {
00504 state = SIO_STATE_ERROR;
00505 if( verbosity >= SIO_ERRORS )
00506 {
00507 std::cout << "SIO: [" << name << "//] "
00508 << "Buffer allocation failed"
00509 << std::endl;
00510 }
00511 return( SIO_STREAM_NOALLOC );
00512 }
00513 buffer = bufloc;
00514 bufmax = bufloc + reserve;
00515
00516
00517
00518
00519 cmploc = NULL;
00520 cmpmax = NULL;
00521 cmploc = static_cast<unsigned char*>(malloc( reserve >> 2 ));
00522 if( cmploc == NULL )
00523 {
00524 state = SIO_STATE_ERROR;
00525 if( verbosity >= SIO_ERRORS )
00526 {
00527 std::cout << "SIO: [" << name << "//] "
00528 << "Compression buffer allocation failed"
00529 << std::endl;
00530 }
00531 return( SIO_STREAM_BADCOMPRESS );
00532 }
00533 cmpmax = cmploc + (reserve >> 2);
00534
00535
00536
00537
00538 z_strm = static_cast<z_stream*>( malloc( sizeof( z_stream ) ));
00539
00540 z_strm->zalloc = Z_NULL;
00541 z_strm->zfree = Z_NULL;
00542 z_strm->opaque = 0;
00543
00544 z_stat = (mode == SIO_MODE_READ) ? inflateInit( z_strm )
00545 : deflateInit( z_strm, compLevel );
00546
00547 if( z_stat != Z_OK )
00548 {
00549 state = SIO_STATE_ERROR;
00550 if( verbosity >= SIO_ERRORS )
00551 {
00552 std::cout << "SIO: [" << name << "//] "
00553 << "ZLIB error number " << z_stat
00554 << std::endl;
00555
00556 std::cout << "SIO: [" << name << "//] "
00557 << "Compression initialization failed"
00558 << std::endl;
00559 }
00560 return( SIO_STREAM_BADCOMPRESS );
00561 }
00562
00563
00564
00565
00566 pointedAt = new pointedAtMap_c;
00567 pointerTo = new pointerToMap_c;
00568
00569
00570
00571
00572 return( SIO_STREAM_SUCCESS );
00573 }
00574
00575
00576
00577 SIO_64BITINT SIO_stream::currentPosition() {
00578
00579 return FTELL( handle ) ;
00580 }
00581
00582
00583
00584
00585 unsigned int SIO_stream::seek(SIO_64BITINT pos, int whence) {
00586
00587 unsigned int status;
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605 status = FSEEK( handle, pos , whence ) ;
00606
00607 if( status != 0 ) {
00608
00609 state = SIO_STATE_ERROR;
00610
00611 if( verbosity >= SIO_ERRORS ) {
00612
00613 std::cout << "SIO: [" << name << "/] "
00614 << "Failed seeking position" << pos
00615 << std::endl;
00616 }
00617 return( SIO_STREAM_EOF );
00618 }
00619
00620
00621
00622
00623
00624 return( SIO_STREAM_SUCCESS );
00625 }
00626
00627 unsigned int SIO_stream::reset(SIO_64BITINT pos){
00628
00629 unsigned int status;
00630
00631 status = seek( pos ) ;
00632
00633 if( status == SIO_STREAM_SUCCESS ){
00634
00635
00636 state = SIO_STATE_OPEN ;
00637 }
00638
00639 return status ;
00640 }
00641
00642
00643
00644
00645
00646 unsigned int SIO_stream::read
00647 (
00648 SIO_record** record
00649 )
00650 {
00651
00652 int
00653 z_stat;
00654
00655 unsigned int
00656 data_length,
00657 head_length,
00658 name_length,
00659 ucmp_length,
00660 buftyp,
00661 compress,
00662 padlen,
00663 options,
00664 status;
00665
00666 char
00667 *tmploc;
00668
00669 bool
00670 requested;
00671
00672
00673
00674
00675 *record = NULL;
00676
00677 recPos = -1 ;
00678 SIO_64BITINT recStart = -1 ;
00679
00680
00681
00682
00683 if( state != SIO_STATE_OPEN )
00684 {
00685 if( verbosity >= SIO_ERRORS )
00686 {
00687 std::cout << "SIO: [" << name << "//] "
00688 << "Cannot read (stream is not open)"
00689 << std::endl;
00690 }
00691 return( SIO_STREAM_NOTOPEN );
00692 }
00693
00694
00695
00696
00697 if( mode != SIO_MODE_READ )
00698 {
00699 if( verbosity >= SIO_ERRORS )
00700 {
00701 std::cout << "SIO: [" << name << "//] "
00702 << "Cannot read (stream is write only)"
00703 << std::endl;
00704 }
00705 return( SIO_STREAM_WRITEONLY );
00706 }
00707
00708
00709
00710
00711 requested = false;
00712 while( requested == false )
00713 {
00714
00715 recStart = FTELL( handle ) ;
00716
00717
00718
00719
00720
00721
00722 buffer = bufloc;
00723 status = FREAD( buffer, SIO_LEN_SB, 8, handle );
00724 if( status < 8 )
00725 return( SIO_STREAM_EOF );
00726
00727
00728
00729
00730
00731 blkmax = bufloc + 8;
00732 SIO_DATA( this, &head_length, 1 );
00733 SIO_DATA( this, &buftyp, 1 );
00734 if( buftyp != SIO_mark_record )
00735 {
00736 state = SIO_STATE_ERROR;
00737 if( verbosity >= SIO_ERRORS )
00738 {
00739 std::cout << "SIO: [" << name << "//] "
00740 << "Expected record marker not found"
00741 << std::endl;
00742 }
00743 return( SIO_STREAM_NORECMARKER );
00744 }
00745
00746
00747
00748
00749
00750
00751
00752
00753 status = FREAD( buffer, SIO_LEN_SB, (head_length - 8), handle );
00754 if( status < (head_length - 8) )
00755 {
00756 if( verbosity >= SIO_ERRORS )
00757 {
00758 std::cout << "SIO: [" << name << "//] "
00759 << "Unexpected EOF reading record header"
00760 << std::endl;
00761 }
00762 return( SIO_STREAM_EOF );
00763 }
00764
00765 blkmax = bufloc + head_length;
00766 SIO_DATA( this, &options, 1 );
00767 SIO_DATA( this, &data_length, 1 );
00768 SIO_DATA( this, &ucmp_length, 1 );
00769 SIO_DATA( this, &name_length, 1 );
00770
00771 tmploc = static_cast<char*>(malloc( name_length + 1 ));
00772 if( tmploc == NULL )
00773 {
00774 if( verbosity >= SIO_ERRORS )
00775 {
00776 std::cout << "SIO: [" << name << "//] "
00777 << "Buffer allocation failed"
00778 << std::endl;
00779 }
00780 return( SIO_STREAM_NOALLOC );
00781 }
00782
00783 SIO_DATA( this, tmploc, name_length );
00784 tmploc[name_length] = '\0';
00785 *record = SIO_recordManager::get( tmploc );
00786 rec_name = tmploc;
00787 free( tmploc );
00788
00789 if( verbosity >= SIO_ALL )
00790 {
00791 std::cout << "SIO: [" << name << "/" << rec_name << "/] "
00792 << "Record header read"
00793 << std::endl;
00794 }
00795
00796
00797
00798
00799 if( *record == NULL )
00800 {
00801 if( verbosity >= SIO_ALL )
00802 {
00803 std::cout << "SIO: [" << name << "/" << rec_name << "/] "
00804 << "Ignored (name not recognized)"
00805 << std::endl;
00806 }
00807 }
00808
00809 else if( !(*record)->getUnpack() )
00810 {
00811 if( verbosity >= SIO_ALL )
00812 {
00813 std::cout << "SIO: [" << name << "/" << rec_name << "/] "
00814 << "Ignored (unpacking not requested)"
00815 << std::endl;
00816 }
00817 }
00818
00819 else
00820 {
00821 requested = true;
00822 }
00823
00824
00825
00826
00827
00828
00829 if( requested == false )
00830 {
00831 data_length += (4 - (data_length & SIO_align)) & SIO_align;
00832 status = FSEEK( handle, data_length, 1 );
00833 if( status != 0 )
00834 {
00835 state = SIO_STATE_ERROR;
00836 if( verbosity >= SIO_ERRORS )
00837 {
00838 std::cout << "SIO: [" << name << "/" << rec_name << "/] "
00839 << "Failed skipping record"
00840 << std::endl;
00841 }
00842 return( SIO_STREAM_EOF );
00843 }
00844 continue;
00845 }
00846
00847
00848
00849
00850 if( (head_length + ucmp_length) >= (bufmax - bufloc) )
00851 {
00852 unsigned int
00853 newlen;
00854
00855 unsigned char
00856 *newbuf;
00857
00858 newlen = head_length + ucmp_length;
00859 newbuf = static_cast<unsigned char*>(malloc( newlen ));
00860 if( newbuf == NULL )
00861 {
00862 if( verbosity >= SIO_ERRORS )
00863 {
00864 std::cout << "SIO: [" << name << "/" << rec_name << "/] "
00865 << "Uncompressed buffer allocation failed"
00866 << std::endl;
00867 }
00868 return( SIO_STREAM_NOALLOC );
00869 }
00870
00871 memcpy( newbuf, bufloc, head_length );
00872 free( bufloc );
00873 bufloc = newbuf;
00874 buffer = newbuf + head_length;
00875 bufmax = bufloc + newlen;
00876 }
00877
00878
00879
00880
00881 compress = options & SIO_OPT_COMPRESS;
00882
00883 if( !compress )
00884 {
00885
00886
00887
00888
00889
00890 status = FREAD( buffer, SIO_LEN_SB, data_length, handle );
00891 if( status < data_length )
00892 {
00893 state = SIO_STATE_ERROR;
00894 if( verbosity >= SIO_ERRORS )
00895 {
00896 std::cout << "SIO: [" << name << "/" << rec_name << "/] "
00897 << "Failed reading uncompressed record data"
00898 << std::endl;
00899 }
00900 return( SIO_STREAM_EOF );
00901 }
00902 }
00903
00904 else
00905 {
00906
00907
00908
00909 if( data_length >= (cmpmax - cmploc) )
00910 {
00911 unsigned char
00912 *newbuf;
00913
00914 newbuf = static_cast<unsigned char*>(malloc( data_length ));
00915 if( newbuf == NULL )
00916 {
00917 if( verbosity >= SIO_ERRORS )
00918 {
00919 std::cout << "SIO: [" << name << "/" << rec_name << "/] "
00920 << "Compressed buffer allocation failed"
00921 << std::endl;
00922 }
00923 return( SIO_STREAM_NOALLOC );
00924 }
00925
00926 free( cmploc );
00927 cmploc = newbuf;
00928 cmpmax = cmploc + data_length;
00929 }
00930
00931
00932
00933
00934 status = FREAD( cmploc, SIO_LEN_SB, data_length, handle );
00935 if( status < data_length )
00936 {
00937 state = SIO_STATE_ERROR;
00938 if( verbosity >= SIO_ERRORS )
00939 {
00940 std::cout << "SIO: [" << name << "/" << rec_name << "/] "
00941 << "Failed reading compressed record data"
00942 << std::endl;
00943 }
00944 return( SIO_STREAM_EOF );
00945 }
00946
00947
00948
00949
00950
00951
00952 padlen = (4 - (data_length & SIO_align)) & SIO_align;
00953 if( padlen > 0 )
00954 {
00955 status = FSEEK( handle, padlen, 1 );
00956 if( status != 0 )
00957 {
00958 state = SIO_STATE_ERROR;
00959 if( verbosity >= SIO_ERRORS )
00960 {
00961 std::cout << "SIO: [" << name << "/" << rec_name << "/] "
00962 << "Failed reading end-of-record pad data"
00963 << std::endl;
00964 }
00965 return( SIO_STREAM_EOF );
00966 }
00967 }
00968
00969
00970
00971
00972 z_strm->next_in = cmploc;
00973 z_strm->avail_in = data_length;
00974 z_strm->total_in = 0;
00975
00976 z_strm->next_out = buffer;
00977 z_strm->avail_out = bufmax-buffer;
00978 z_strm->total_out = 0;
00979
00980 z_stat = inflate( z_strm, Z_FINISH );
00981 if( z_stat != Z_STREAM_END )
00982 {
00983 state = SIO_STATE_ERROR;
00984 if( verbosity >= SIO_ERRORS )
00985 {
00986 std::cout << "SIO: [" << name << "/" << rec_name << "/] "
00987 << "ZLIB error number " << z_stat
00988 << std::endl;
00989
00990 std::cout << "SIO: [" << name << "/" << rec_name << "/] "
00991 << "Decompression failed"
00992 << std::endl;
00993 }
00994 return( SIO_STREAM_BADCOMPRESS );
00995 }
00996
00997 z_stat = inflateReset( z_strm );
00998 if( z_stat != Z_OK )
00999 {
01000 state = SIO_STATE_ERROR;
01001 if( verbosity >= SIO_ERRORS )
01002 {
01003 std::cout << "SIO: [" << name << "/" << rec_name << "/] "
01004 << "ZLIB error number " << z_stat
01005 << std::endl;
01006
01007 std::cout << "SIO: [" << name << "/" << rec_name << "/] "
01008 << "Decompression de-initialization failed"
01009 << std::endl;
01010 }
01011 return( SIO_STREAM_BADCOMPRESS );
01012 }
01013
01014 }
01015
01016
01017
01018
01019 recmax = bufloc + head_length + ucmp_length;
01020 status = (*record)->read( this, options );
01021
01022
01023
01024
01025
01026
01027 pointerTo->erase( pointerTo->begin(), pointerTo->end() );
01028 pointedAt->erase( pointedAt->begin(), pointedAt->end() );
01029
01030 if( !( status & 1 ) )
01031 {
01032 if( verbosity >= SIO_ERRORS )
01033 {
01034 std::cout << "SIO: [" << name << "/" << rec_name << "/] "
01035 << "Unpacking error"
01036 << std::endl;
01037 }
01038 } else {
01039
01040 recPos = recStart ;
01041 }
01042
01043 }
01044
01045
01046
01047
01048 return( status );
01049 }
01050
01051
01052
01053
01054 SIO_verbosity SIO_stream::setVerbosity
01055 (
01056 SIO_verbosity i_verb
01057 )
01058 { SIO_verbosity o_verb = verbosity; verbosity = i_verb; return( o_verb ); }
01059
01060
01061
01062
01063 unsigned int SIO_stream::write
01064 (
01065 const char* i_name
01066 )
01067 {
01068
01069
01070
01071
01072 SIO_record
01073 *record;
01074
01075
01076
01077
01078 record = SIO_recordManager::get( i_name );
01079 if( record == NULL )
01080 {
01081 if( verbosity >= SIO_ERRORS )
01082 {
01083 std::cout << "SIO: [" << name << "/" << i_name << "//] "
01084 << "Record name not recognized"
01085 << std::endl;
01086 }
01087 return( SIO_STREAM_NOSUCHRECORD );
01088 }
01089
01090
01091
01092
01093 return( write( record, i_name ) );
01094 }
01095
01096
01097
01098
01099 unsigned int SIO_stream::write
01100 (
01101 SIO_record* record
01102 )
01103 {
01104
01105
01106
01107
01108 return( write( record, record->getName()->c_str() ) );
01109 }
01110
01111
01112
01113
01114 unsigned int SIO_stream::write
01115 (
01116 SIO_record* record,
01117 const char* i_name
01118 )
01119 {
01120
01121
01122
01123
01124 int
01125 z_stat;
01126
01127 unsigned int
01128 data_length,
01129 data_length_off,
01130 head_length,
01131 head_length_off,
01132 name_length,
01133 ucmp_length,
01134 ucmp_length_off,
01135 bufout,
01136 compress,
01137 newlen,
01138 oldlen,
01139 options,
01140 status;
01141
01142 unsigned char
01143 *newbuf;
01144
01145 static unsigned char
01146 pad[4] = { 0, 0, 0, 0 };
01147
01148
01149
01150
01151 if( state != SIO_STATE_OPEN )
01152 {
01153 if( verbosity >= SIO_ERRORS )
01154 {
01155 std::cout << "SIO: [" << name << "//] "
01156 << "Cannot write (stream is not open)"
01157 << std::endl;
01158 }
01159 return( SIO_STREAM_NOTOPEN );
01160 }
01161
01162
01163
01164
01165 if( mode == SIO_MODE_READ )
01166 {
01167 if( verbosity >= SIO_ERRORS )
01168 {
01169 std::cout << "SIO: [" << name << "//] "
01170 << "Cannot write (stream is read only)"
01171 << std::endl;
01172 }
01173 return( SIO_STREAM_READONLY );
01174 }
01175
01176
01177
01178
01179 rec_name = i_name;
01180
01181
01182
01183
01184 buffer = bufloc;
01185
01186
01187
01188
01189 recPos = FTELL( handle ) ;
01190
01191
01192
01193
01194
01195
01196
01197
01198
01199
01200 compress = record->getCompress();
01201 options = record->getOptions();
01202
01203 head_length_off = buffer - bufloc;
01204 SIO_DATA( this, &SIO_mark_record, 1 );
01205 SIO_DATA( this, &SIO_mark_record, 1 );
01206 SIO_DATA( this, &options, 1 );
01207
01208 data_length_off = buffer - bufloc;
01209 SIO_DATA( this, &SIO_mark_record, 1 );
01210
01211 ucmp_length_off = buffer - bufloc;
01212 SIO_DATA( this, &SIO_mark_record, 1 );
01213
01214 name_length = strlen( i_name );
01215 SIO_DATA( this, &name_length, 1 );
01216 SIO_DATA( this, const_cast<char *>(i_name), name_length );
01217
01218
01219
01220
01221 head_length = buffer - bufloc;
01222 SIO_functions::copy( UCHR_CAST(&head_length), (bufloc + head_length_off),
01223 SIO_LEN_QB, 1 );
01224
01225
01226
01227
01228
01229 status = record->write( this );
01230 if( !(status & 1) )
01231 {
01232 if( verbosity >= SIO_ERRORS )
01233 {
01234 std::cout << "SIO: [" << name << "/" << rec_name << "/] "
01235 << "Packing error"
01236 << std::endl;
01237 }
01238 return( status );
01239 }
01240
01241
01242
01243
01244 ucmp_length = (buffer - bufloc) - head_length;
01245 SIO_functions::copy( UCHR_CAST(&ucmp_length), (bufloc + ucmp_length_off),
01246 SIO_LEN_QB, 1 );
01247
01248
01249
01250
01251
01252
01253
01254
01255
01256
01257 if( !compress )
01258 {
01259
01260
01261
01262
01263 data_length = ucmp_length;
01264 SIO_functions::copy( UCHR_CAST(&data_length), (bufloc + data_length_off),
01265 SIO_LEN_QB, 1 );
01266
01267
01268
01269
01270
01271
01272
01273 data_length += head_length;
01274 bufout = FWRITE( bufloc, sizeof(char), data_length, handle );
01275 if( bufout != data_length && ! FFLUSH( handle ) )
01276 {
01277 state = SIO_STATE_ERROR;
01278 if( verbosity >= SIO_ERRORS )
01279 {
01280 std::cout << "SIO: [" << name << "/" << rec_name << "/] "
01281 << "File error writing record"
01282 << std::endl;
01283 }
01284 return( SIO_STREAM_BADWRITE );
01285 }
01286 }
01287 else
01288 {
01289
01290
01291
01292 z_strm->next_in = bufloc + head_length;
01293 z_strm->avail_in = ucmp_length;
01294 z_strm->total_in = 0;
01295
01296 z_strm->next_out = cmploc;
01297 z_strm->avail_out = cmpmax - cmploc;
01298 z_strm->total_out = 0;
01299
01300
01301
01302
01303 for(;;)
01304 {
01305 z_stat = deflate( z_strm, Z_FINISH );
01306 if( z_strm->avail_out > 0 )
01307 break;
01308
01309 newlen = (cmpmax - cmploc) << 1;
01310 newbuf = static_cast<unsigned char*>(malloc( newlen ));
01311 if( newbuf == NULL )
01312 {
01313 if( verbosity >= SIO_ERRORS )
01314 {
01315 std::cout << "SIO: ["
01316 << name << "/"
01317 << rec_name << "//] "
01318 << "Compression buffer allocation failed"
01319 << std::endl;
01320 }
01321
01322 state = SIO_STATE_ERROR;
01323 return( SIO_STREAM_NOALLOC );
01324 }
01325
01326 oldlen = z_strm->next_out - cmploc;
01327 memcpy( newbuf, cmploc, oldlen );
01328 free( cmploc );
01329 cmploc = newbuf;
01330 cmpmax = cmploc + newlen;
01331
01332 z_strm->next_out = cmploc + oldlen;
01333 z_strm->avail_out = cmpmax - z_strm->next_out;
01334
01335 if( verbosity >= SIO_ALL )
01336 {
01337 std::cout << "SIO: ["
01338 << name << "/"
01339 << rec_name << "//] "
01340 << "Allocated a "
01341 << newlen
01342 << "(0x" << std::hex << newlen << std::dec << ")"
01343 << " byte compression buffer"
01344 << std::endl;
01345 }
01346 }
01347
01348 z_stat = deflateReset( z_strm );
01349 if( z_stat != Z_OK )
01350 {
01351 state = SIO_STATE_ERROR;
01352 if( verbosity >= SIO_ERRORS )
01353 {
01354 std::cout << "SIO: [" << name << "//] "
01355 << "ZLIB error number " << z_stat
01356 << std::endl;
01357
01358 std::cout << "SIO: [" << name << "//] "
01359 << "Compression de-initialization failed"
01360 << std::endl;
01361 }
01362 return( SIO_STREAM_BADCOMPRESS );
01363 }
01364
01365
01366
01367
01368 data_length = z_strm->next_out - cmploc;
01369 SIO_functions::copy( UCHR_CAST(&data_length), (bufloc + data_length_off),
01370 SIO_LEN_QB, 1 );
01371
01372
01373
01374
01375 bufout = FWRITE( bufloc, sizeof(char), head_length, handle );
01376 if( bufout != head_length )
01377 {
01378 state = SIO_STATE_ERROR;
01379 if( verbosity >= SIO_ERRORS )
01380 {
01381 std::cout << "SIO: [" << name << "/" << rec_name << "/] "
01382 << "File error writing record header"
01383 << std::endl;
01384 }
01385 return( SIO_STREAM_BADWRITE );
01386 }
01387
01388
01389
01390
01391 bufout = FWRITE( cmploc, sizeof(char), data_length, handle );
01392 if( bufout != data_length && ! FFLUSH(handle) )
01393 {
01394 state = SIO_STATE_ERROR;
01395 if( verbosity >= SIO_ERRORS )
01396 {
01397 std::cout << "SIO: [" << name << "/" << rec_name << "/] "
01398 << "File error writing record content"
01399 << std::endl;
01400 }
01401 return( SIO_STREAM_BADWRITE );
01402 }
01403
01404
01405
01406
01407
01408
01409 newlen = (4 - (data_length & SIO_align)) & SIO_align;
01410 if( newlen > 0 )
01411 {
01412 bufout = FWRITE( pad, sizeof(char), newlen, handle );
01413 if( bufout != newlen && ! FFLUSH(handle))
01414 {
01415 state = SIO_STATE_ERROR;
01416 if( verbosity >= SIO_ERRORS )
01417 {
01418 std::cout << "SIO: [" << name << "/" << rec_name << "/] "
01419 << "File error writing end-of-record pad"
01420 << std::endl;
01421 }
01422 return( SIO_STREAM_BADWRITE );
01423 }
01424 }
01425 }
01426
01427
01428
01429
01430 pointerTo->erase( pointerTo->begin(), pointerTo->end() );
01431 pointedAt->erase( pointedAt->begin(), pointedAt->end() );
01432
01433
01434
01435
01436 return( SIO_STREAM_SUCCESS );
01437 }
01438