Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Class Members | File Members

SIO_stream Class Reference

#include <SIO_stream.h>

Collaboration diagram for SIO_stream:

Collaboration graph
[legend]
List of all members.

Public Member Functions

unsigned int close ()
void dump (unsigned int, unsigned int)
std::string * getName ()
std::string * getFilename ()
SIO_stream_mode getMode ()
SIO_stream_state getState ()
SIO_verbosity getVerbosity ()
unsigned int open (const char *, SIO_stream_mode)
unsigned int read (SIO_record **)
SIO_verbosity setVerbosity (SIO_verbosity)
unsigned int write (const char *)
unsigned int write (SIO_record *)

Private Member Functions

 SIO_stream (const char *, unsigned int, SIO_verbosity)
 ~SIO_stream ()
unsigned int write (SIO_record *, const char *)

Private Attributes

unsigned char * bufloc
unsigned char * buffer
unsigned char * bufmax
unsigned char * recmax
unsigned char * blkmax
unsigned char * cmploc
unsigned char * cmpmax
z_stream_s * z_strm
std::string name
std::string filename
FILE * handle
std::string rec_name
std::string blk_name
pointedAtMap_cpointedAt
pointerToMap_cpointerTo
SIO_stream_mode mode
unsigned int reserve
SIO_stream_state state
SIO_verbosity verbosity

Friends

class SIO_streamManager
class SIO_record
class SIO_functions

Constructor & Destructor Documentation

SIO_stream::SIO_stream const char *  ,
unsigned  int,
SIO_verbosity 
[private]
 

Definition at line 36 of file SIO_stream.cc.

References SIO_MODE_UNDEFINED, SIO_STATE_CLOSED, and SIO_verbosity.

00041 {
00042 
00043   bufloc    = NULL;
00044   buffer    = NULL;
00045   bufmax    = NULL;
00046   recmax    = NULL;
00047   blkmax    = NULL;
00048 
00049   cmploc    = NULL;
00050   cmpmax    = NULL;
00051   z_strm    = NULL;
00052 
00053   name      = i_name;
00054   handle    = NULL;
00055 
00056   mode      = SIO_MODE_UNDEFINED;
00057   reserve   = i_reserve;
00058   state     = SIO_STATE_CLOSED;
00059   verbosity = i_verbosity;
00060 
00061 }

SIO_stream::~SIO_stream  )  [private]
 

Definition at line 66 of file SIO_stream.cc.

References close(), SIO_STATE_CLOSED, and state.

00067 {
00068 
00069   //
00070   // Always try to close the stream.
00071   //
00072   if( state != SIO_STATE_CLOSED )
00073     close();
00074 
00075   //
00076   // That's all folks!
00077   //
00078   return;
00079 }


Member Function Documentation

unsigned int SIO_stream::close  ) 
 

Definition at line 84 of file SIO_stream.cc.

References blkmax, buffer, bufloc, bufmax, cmploc, cmpmax, filename, handle, mode, name, pointedAt, pointerTo, recmax, SIO_ALL, SIO_ERRORS, SIO_MODE_READ, SIO_MODE_UNDEFINED, SIO_STATE_CLOSED, SIO_STREAM_BADCOMPRESS, SIO_STREAM_GOTEOF, SIO_STREAM_NOTOPEN, SIO_STREAM_SUCCESS, state, verbosity, and z_strm.

Referenced by main(), LCDG4_SIOglobal::~LCDG4_SIOglobal(), and ~SIO_stream().

00085 {
00086 
00087   //
00088   // Local variables.
00089   //
00090   int
00091     z_stat;
00092 
00093   unsigned int
00094     status;
00095 
00096   //
00097   // Can't close what ain't open!
00098   //
00099   if( state == SIO_STATE_CLOSED )
00100     {
00101       if( verbosity >= SIO_ERRORS )
00102         {
00103           std::cout << "SIO: ["  << name << "//] "
00104                     << "Not open"
00105                     << std::endl;
00106         }
00107       return( SIO_STREAM_NOTOPEN );
00108     }
00109 
00110   //
00111   // Assume all will go well.
00112   //
00113   status = SIO_STREAM_SUCCESS;
00114 
00115   //
00116   // Dispose of the pointer relocation tables.
00117   //
00118   delete pointedAt;
00119   delete pointerTo;
00120 
00121   //
00122   // Dispose of compression control structure.
00123   //
00124   if( z_strm != NULL )
00125     {
00126       z_stat = (mode == SIO_MODE_READ) ? inflateEnd( z_strm )
00127         : deflateEnd( z_strm );
00128 
00129       if( z_stat != Z_OK )
00130         {
00131           status = SIO_STREAM_BADCOMPRESS;
00132           if( verbosity >= SIO_ERRORS )
00133             {
00134               std::cout << "SIO: ["  << name << "//] "
00135                         << "ZLIB error number " << z_stat
00136                         << std::endl;
00137 
00138               std::cout << "SIO: ["  << name << "//] "
00139                         << "Compression de-initialization failed"
00140                         << std::endl;
00141             }
00142         }
00143       free( z_strm );
00144       z_strm = NULL;
00145     }
00146 
00147   //
00148   // Dispose of any compression/decompression buffer.
00149   //
00150   if( cmploc != NULL )
00151     {
00152       free( cmploc );
00153       cmploc = NULL;
00154       cmpmax = NULL;
00155     }
00156 
00157   //
00158   // Dispose of any associated raw data buffer.
00159   //
00160   if( bufloc != NULL )
00161     {
00162       free( bufloc );
00163       bufloc = NULL;
00164       buffer = NULL;
00165       bufmax = NULL;
00166       recmax = NULL;
00167       blkmax = NULL;
00168     }
00169 
00170   //
00171   // Close the stream and destroy associated information.
00172   //
00173   if( fclose( handle ) == EOF )
00174     {
00175       status = SIO_STREAM_GOTEOF;
00176       if( verbosity >= SIO_ERRORS )
00177         {
00178           std::cout << "SIO: ["  << name << "//] "
00179                     << "EOF on close"
00180                     << std::endl;
00181         }
00182     }
00183   else
00184     {
00185     }
00186   filename.erase( filename.begin(), filename.end() );
00187   handle = NULL;
00188 
00189   //
00190   // Miscellany.
00191   //
00192   mode   = SIO_MODE_UNDEFINED;
00193   state  = SIO_STATE_CLOSED;
00194 
00195   //
00196   // Summarize.
00197   //
00198   if( status == SIO_STREAM_SUCCESS )
00199     {
00200       if( verbosity >= SIO_ALL )
00201         {
00202           std::cout << "SIO: ["  << name << "//] "
00203                     << "Closed"
00204                     << std::endl;
00205         }
00206     }
00207 
00208   //
00209   // That's all folks!
00210   //
00211   return( status );
00212 }

void SIO_stream::dump unsigned  int,
unsigned  int
 

Definition at line 218 of file SIO_stream.cc.

00222 {
00223 
00224   //
00225   // Local variables.
00226   //
00227   unsigned int
00228     count;
00229 
00230   char
00231     *ascpnt,
00232     *hexpnt,
00233     outbuf[77];
00234 
00235   unsigned char
00236     *dmpbeg,
00237     *dmpend;
00238 
00239   static char
00240     hex[16] = { '0', '1', '2', '3', '4', '5', '6', '7',
00241                 '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
00242 
00243   //
00244   // Header.
00245   //
00246   printf( "\nDump buffer of stream %s\n\n", name.c_str() );
00247 
00248   if( buffer == NULL )
00249     {
00250       printf( "No buffer associated with stream %s\n", name.c_str() );
00251       return;
00252     }
00253 
00254   //
00255   // Offset must be in bounds.
00256   //
00257   dmpbeg = bufloc + offset;
00258   if( dmpbeg >= bufmax )
00259     {
00260       printf( "Offset beyond end of buffer\n");
00261       return;
00262     }
00263 
00264   //
00265   // Length must not run off end of buffer.
00266   //
00267   dmpend = dmpbeg + length;
00268   if( dmpend > bufmax )
00269     dmpend = bufmax;
00270 
00271   //
00272   // Buffer characteristics.
00273   //
00274   printf("   Start address: %8d  (0x%08x)\n", (int)bufloc, (int)bufloc );
00275   count = buffer - bufloc;
00276   printf(" Current address: %8d  (0x%08x)    Offset: %8d  (0x%08x)\n",
00277          (int)buffer, (int)buffer, count, count );
00278   count = bufmax - bufloc;
00279   printf("     End address: %8d  (0x%08x)    Offset: %8d  (0x%08x)\n",
00280          (int)bufmax, (int)bufmax, count, count );
00281 
00282   //
00283   // Put out a header.
00284   //
00285   printf("\n --Offset:Address-");
00286   printf(  "    -Hex------------------------------");
00287   printf(  "    -ASCII----------\n");
00288 
00289   // dddddddd:xxxxxxxx    xxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx    aaaaaaaaaaaaaaaa
00290   //-123456789-123456789-123456789-123456789-123456789-123456789-123456789-123456
00291 
00292   //
00293   // Scan down the buffer, printing a dump record every 16 bytes.
00294   //
00295   memset(  &outbuf[ 0], ' ', sizeof( outbuf ) );
00296   sprintf( &outbuf[ 1], "%8d",  offset );
00297   sprintf( &outbuf[10], "%08x", (int)dmpbeg );
00298   outbuf[ 9] = ':';
00299   outbuf[18] = ' ';
00300   outbuf[76] = '\0';
00301   hexpnt     = &outbuf[22];
00302   ascpnt     = &outbuf[60];
00303   count      = 0;
00304 
00305   while( dmpbeg < dmpend )
00306     {
00307 
00308       *hexpnt++ = hex[ ((*dmpbeg >>   4) & 15) ];
00309       *hexpnt++ = hex[ ( *dmpbeg         & 15) ];
00310       if( (count & 0x3) == 3 ) hexpnt++;
00311 
00312       if( isprint( *dmpbeg ) ) *ascpnt++ = *dmpbeg;
00313       else                     *ascpnt++ = '.';
00314 
00315       count++;
00316       offset++;
00317       dmpbeg++;
00318 
00319       if( count == 16 )
00320         {
00321           printf( "%s\n", outbuf );
00322 
00323           memset(  &outbuf[ 0], ' ', sizeof( outbuf ) );
00324           sprintf( &outbuf[ 1], "%8d",  offset );
00325           sprintf( &outbuf[10], "%08x", (int)dmpbeg );
00326           outbuf[ 9] = ':';
00327           outbuf[18] = ' ';
00328           outbuf[76] = '\0';
00329           hexpnt     = &outbuf[22];
00330           ascpnt     = &outbuf[60];
00331           count      = 0;
00332         }
00333     }
00334 
00335   if( count != 0 )
00336     printf( "%s\n", outbuf );
00337 
00338   //
00339   // That's all folks!
00340   //
00341   return;
00342 }

std::string * SIO_stream::getFilename  ) 
 

Definition at line 352 of file SIO_stream.cc.

References filename.

00352 { return( &filename ); }

SIO_stream_mode SIO_stream::getMode  ) 
 

Definition at line 357 of file SIO_stream.cc.

References mode, and SIO_stream_mode.

00357 { return( mode ); }

std::string * SIO_stream::getName  ) 
 

Definition at line 347 of file SIO_stream.cc.

References name.

00347 { return( &name ); }

SIO_stream_state SIO_stream::getState  ) 
 

Definition at line 362 of file SIO_stream.cc.

References SIO_stream_state, and state.

00362 { return( state ); }

SIO_verbosity SIO_stream::getVerbosity  ) 
 

Definition at line 367 of file SIO_stream.cc.

References SIO_verbosity, and verbosity.

00367 { return( verbosity ); }

unsigned int SIO_stream::open const char *  ,
SIO_stream_mode 
 

Definition at line 373 of file SIO_stream.cc.

References pointedAtMap_c, pointerToMap_c, SIO_ALL, SIO_ERRORS, SIO_MODE_READ, SIO_MODE_UNDEFINED, SIO_STATE_ERROR, SIO_STATE_OPEN, SIO_STREAM_ALREADYOPEN, SIO_STREAM_BADCOMPRESS, SIO_STREAM_BADMODE, SIO_stream_mode, SIO_STREAM_NOALLOC, SIO_STREAM_OPENFAIL, and SIO_STREAM_SUCCESS.

Referenced by LCDG4_SIOglobal::LCDG4_SIOglobal().

00377 {
00378 
00379   //
00380   // Local variables.
00381   //
00382   int
00383     z_stat;
00384 
00385   static char
00386     SIO_filemode[3][3] = { "rb", "wb", "ab" };
00387 
00388   //
00389   // Can't open what ain't closed!
00390   //
00391   if( state == SIO_STATE_OPEN || state == SIO_STATE_ERROR )
00392     {
00393       if( verbosity >= SIO_ERRORS )
00394         {
00395           std::cout << "SIO: ["  << name << "//] "
00396                     << "Already open"
00397                     << std::endl;
00398         }
00399       return( SIO_STREAM_ALREADYOPEN );
00400     }
00401 
00402   //
00403   // Can't open in mode undefined.
00404   //
00405   if( i_mode == SIO_MODE_UNDEFINED )
00406     {
00407       if( verbosity >= SIO_ERRORS )
00408         {
00409           std::cout << "SIO: ["  << name << "//] "
00410                     << "Cannot open in mode SIO_MODE_UNDEFINED"
00411                     << std::endl;
00412         }
00413       return( SIO_STREAM_BADMODE );
00414     }
00415 
00416   //
00417   // Open the file.
00418   //
00419   if( (handle = fopen( i_filename, SIO_filemode[i_mode] )) == NULL )
00420     {
00421       if( verbosity >= SIO_ERRORS )
00422         {
00423           std::cout << "SIO: ["  << name << "//] "
00424                     << "Cannot open file "
00425                     << i_filename
00426                     << std::endl;
00427         }
00428       return( SIO_STREAM_OPENFAIL );
00429     }
00430 
00431   //
00432   // Open succeeded.  Save the context.
00433   //
00434   filename = i_filename;
00435   mode     = i_mode;
00436   state    = SIO_STATE_OPEN;
00437 
00438   if( verbosity >= SIO_ALL )
00439     {
00440       std::cout << "SIO: ["  << name << "//] "
00441                 << "Opened file "
00442                 << i_filename
00443                 << std::endl;
00444     }
00445 
00446   //
00447   // Allocate a raw data buffer to go with the stream.
00448   //
00449   buffer = NULL;
00450   bufmax = NULL;
00451   bufloc = static_cast<unsigned char*>(malloc( reserve ));
00452   if( bufloc == NULL )
00453     {
00454       state = SIO_STATE_ERROR;
00455       if( verbosity >= SIO_ERRORS )
00456         {
00457           std::cout << "SIO: ["  << name << "//] "
00458                     << "Buffer allocation failed"
00459                     << std::endl;
00460         }
00461       return( SIO_STREAM_NOALLOC );
00462     }
00463   buffer = bufloc;
00464   bufmax = bufloc + reserve;
00465 
00466   //
00467   // Allocate a compression/decompression buffer and initialize it.
00468   //
00469   cmploc = NULL;
00470   cmpmax = NULL;
00471   cmploc = static_cast<unsigned char*>(malloc( reserve >> 2 ));
00472   if( cmploc == NULL )
00473     {
00474       state = SIO_STATE_ERROR;
00475       if( verbosity >= SIO_ERRORS )
00476         {
00477           std::cout << "SIO: ["  << name << "//] "
00478                     << "Compression buffer allocation failed"
00479                     << std::endl;
00480         }
00481       return( SIO_STREAM_BADCOMPRESS );
00482     }
00483   cmpmax = cmploc + (reserve >> 2);
00484 
00485   //
00486   // Allocate the z_stream structure and initialize it.
00487   //
00488   z_strm = static_cast<z_stream*>( malloc( sizeof( z_stream ) ));
00489 
00490   z_strm->zalloc = Z_NULL;
00491   z_strm->zfree  = Z_NULL;
00492   z_strm->opaque = 0;
00493 
00494   z_stat = (mode == SIO_MODE_READ) ? inflateInit( z_strm )
00495     : deflateInit( z_strm, Z_DEFAULT_COMPRESSION );
00496 
00497   if( z_stat != Z_OK )
00498     {
00499       state = SIO_STATE_ERROR;
00500       if( verbosity >= SIO_ERRORS )
00501         {
00502           std::cout << "SIO: ["  << name << "//] "
00503                     << "ZLIB error number " << z_stat
00504                     << std::endl;
00505 
00506           std::cout << "SIO: ["  << name << "//] "
00507                     << "Compression initialization failed"
00508                     << std::endl;
00509         }
00510       return( SIO_STREAM_BADCOMPRESS );
00511     }
00512 
00513   //
00514   // Allocate the pointer relocation tables.
00515   //
00516   pointedAt = new pointedAtMap_c;
00517   pointerTo = new pointerToMap_c;
00518 
00519   //
00520   // That's all folks!
00521   //
00522   return( SIO_STREAM_SUCCESS );
00523 }

unsigned int SIO_stream::read SIO_record **   ) 
 

Definition at line 529 of file SIO_stream.cc.

References SIO_recordManager::get(), SIO_align, SIO_ALL, SIO_DATA, SIO_ERRORS, SIO_LEN_SB, SIO_MODE_READ, SIO_OPT_COMPRESS, SIO_STATE_ERROR, SIO_STATE_OPEN, SIO_STREAM_BADCOMPRESS, SIO_STREAM_EOF, SIO_STREAM_NOALLOC, SIO_STREAM_NORECMARKER, SIO_STREAM_NOTOPEN, and SIO_STREAM_WRITEONLY.

00532 {
00533 
00534   int
00535     z_stat;
00536 
00537   unsigned int
00538     data_length,
00539     head_length,
00540     name_length,
00541     ucmp_length,
00542     buftyp,
00543     compress,
00544     padlen,
00545     options,
00546     status;
00547 
00548   char
00549     *tmploc;
00550 
00551   bool
00552     requested;
00553 
00554   //
00555   // Initialize the returned record pointer to something nasty.
00556   //
00557   *record = NULL;
00558 
00559   //
00560   // The stream must be open!
00561   //
00562   if( state != SIO_STATE_OPEN )
00563     {
00564       if( verbosity >= SIO_ERRORS )
00565         {
00566           std::cout << "SIO: ["  << name << "//] "
00567                     << "Cannot read (stream is not open)"
00568                     << std::endl;
00569         }
00570       return( SIO_STREAM_NOTOPEN );
00571     }
00572 
00573   //
00574   // This must be a readable stream!
00575   //
00576   if( mode != SIO_MODE_READ )
00577     {
00578       if( verbosity >= SIO_ERRORS )
00579         {
00580           std::cout << "SIO: ["  << name << "//] "
00581                     << "Cannot read (stream is write only)"
00582                     << std::endl;
00583         }
00584       return( SIO_STREAM_WRITEONLY );
00585     }
00586 
00587   //
00588   // Loop over records until a requested one turns up.
00589   //
00590   requested = false;
00591   while( requested == false )
00592     {
00593       //
00594       // Initialize the buffer and read the first eight bytes.  A read failure
00595       // at this point is treated as an end-of-file (even if there are a few
00596       // bytes dangling in the file).
00597       //
00598       buffer = bufloc;
00599       status = fread( buffer, SIO_LEN_SB, 8, handle );
00600       if( status < 8 )
00601         return( SIO_STREAM_EOF );
00602 
00603       //
00604       // Interpret: 1) The length of the record header.
00605       //            2) The record marker.
00606       //
00607       blkmax = bufloc + 8;
00608       SIO_DATA( this, &head_length,  1 );
00609       SIO_DATA( this, &buftyp,       1 );
00610       if( buftyp != SIO_mark_record )
00611         {
00612           state = SIO_STATE_ERROR;
00613           if( verbosity >= SIO_ERRORS )
00614             {
00615               std::cout << "SIO: ["  << name << "//] "
00616                         << "Expected record marker not found"
00617                         << std::endl;
00618             }
00619           return( SIO_STREAM_NORECMARKER );
00620         }
00621 
00622       //
00623       // Interpret: 3) The options word.
00624       //            4) The length of the record data (compressed).
00625       //            5) The length of the record name (uncompressed).
00626       //            6) The length of the record name.
00627       //            7) The record name.
00628       //
00629       status = fread( buffer, SIO_LEN_SB, (head_length - 8), handle );
00630       if( status < (head_length - 8) )
00631         {
00632           if( verbosity >= SIO_ERRORS )
00633             {
00634               std::cout << "SIO: ["  << name << "//] "
00635                         << "Unexpected EOF reading record header"
00636                         << std::endl;
00637             }
00638           return( SIO_STREAM_EOF );
00639         }
00640 
00641       blkmax = bufloc + head_length;
00642       SIO_DATA( this, &options,      1 );
00643       SIO_DATA( this, &data_length,  1 );
00644       SIO_DATA( this, &ucmp_length,  1 );
00645       SIO_DATA( this, &name_length,  1 );
00646 
00647       tmploc = static_cast<char*>(malloc( name_length + 1 ));
00648       if( tmploc == NULL )
00649         {
00650           if( verbosity >= SIO_ERRORS )
00651             {
00652               std::cout << "SIO: ["  << name << "//] "
00653                         << "Buffer allocation failed"
00654                         << std::endl;
00655             }
00656           return( SIO_STREAM_NOALLOC );
00657         }
00658 
00659       SIO_DATA( this, tmploc, name_length );
00660       tmploc[name_length]  = '\0';
00661       *record              = SIO_recordManager::get( tmploc );
00662       rec_name             = tmploc;
00663       free( tmploc );
00664 
00665       if( verbosity >= SIO_ALL )
00666         {
00667           std::cout << "SIO: ["  << name << "/" << rec_name << "/] "
00668                     << "Record header read"
00669                     << std::endl;
00670         }
00671 
00672       //
00673       // Unpack this record?
00674       //
00675       if( *record == NULL )
00676         {
00677           if( verbosity >= SIO_ALL )
00678             {
00679               std::cout << "SIO: ["  << name << "/" << rec_name << "/] "
00680                         << "Ignored (name not recognized)"
00681                         << std::endl;
00682             }
00683         }
00684 
00685       else if( !(*record)->getUnpack() )
00686         {
00687           if( verbosity >= SIO_ALL )
00688             {
00689               std::cout << "SIO: ["  << name << "/" << rec_name << "/] "
00690                         << "Ignored (unpacking not requested)"
00691                         << std::endl;
00692             }
00693         }
00694 
00695       else
00696         {
00697           requested = true;
00698         }
00699 
00700       //
00701       // If the record's not interesting, move on.  Remember to skip over any
00702       // padding bytes inserted to make the next record header start on a
00703       // four byte boundary in the file.
00704       //
00705       if( requested == false )
00706         {
00707           data_length += (4 - (data_length & SIO_align)) & SIO_align;
00708           status = fseek( handle, data_length, 1 );
00709           if( status != 0 )
00710             {
00711               state = SIO_STATE_ERROR;
00712               if( verbosity >= SIO_ERRORS )
00713                 {
00714                   std::cout << "SIO: ["  << name << "/" << rec_name << "/] "
00715                             << "Failed skipping record"
00716                             << std::endl;
00717                 }
00718               return( SIO_STREAM_EOF );
00719             }
00720           continue;
00721         }
00722 
00723       //
00724       // Ensure sufficient buffering for the uncompressed record.
00725       //
00726       if( (head_length + ucmp_length) >= ((unsigned int)(bufmax - bufloc)) )
00727         {
00728           unsigned int
00729             newlen;
00730 
00731           unsigned char
00732             *newbuf;
00733 
00734           newlen = head_length + ucmp_length;
00735           newbuf = static_cast<unsigned char*>(malloc( newlen ));
00736           if( newbuf == NULL )
00737             {
00738               if( verbosity >= SIO_ERRORS )
00739                 {
00740                   std::cout << "SIO: ["  << name << "/" << rec_name << "/] "
00741                             << "Uncompressed buffer allocation failed"
00742                             << std::endl;
00743                 }
00744               return( SIO_STREAM_NOALLOC );
00745             }
00746 
00747           memcpy( newbuf, bufloc, head_length );
00748           free( bufloc );
00749           bufloc = newbuf;
00750           buffer = newbuf + head_length;
00751           bufmax = bufloc + newlen;
00752         }
00753 
00754       //
00755       // Extract the compression bit from the options word.
00756       //
00757       compress = options & SIO_OPT_COMPRESS;
00758 
00759       if( !compress )
00760         {
00761           //
00762           // Read the rest of the record data.  Note that uncompressed data is
00763           // -always- aligned to a four byte boundary in the file, so no pad
00764           // skipping is necessary,
00765           //
00766           status = fread( buffer, SIO_LEN_SB, data_length, handle );
00767           if( status < data_length )
00768             {
00769               state = SIO_STATE_ERROR;
00770               if( verbosity >= SIO_ERRORS )
00771                 {
00772                   std::cout << "SIO: ["  << name << "/" << rec_name << "/] "
00773                             << "Failed reading uncompressed record data"
00774                             << std::endl;
00775                 }
00776               return( SIO_STREAM_EOF );
00777             }
00778         }
00779 
00780       else
00781         {
00782           //
00783           // Ensure sufficient buffering for the compressed record.
00784           //
00785           if( data_length >= (unsigned int)(cmpmax - cmploc) )
00786             {
00787               unsigned char
00788                 *newbuf;
00789 
00790               newbuf = static_cast<unsigned char*>(malloc( data_length ));
00791               if( newbuf == NULL )
00792                 {
00793                   if( verbosity >= SIO_ERRORS )
00794                     {
00795                       std::cout << "SIO: ["  << name << "/" << rec_name << "/] "
00796                                 << "Compressed buffer allocation failed"
00797                                 << std::endl;
00798                     }
00799                   return( SIO_STREAM_NOALLOC );
00800                 }
00801 
00802               free( cmploc );
00803               cmploc = newbuf;
00804               cmpmax = cmploc + data_length;
00805             }
00806 
00807           //
00808           // Read the compressed record data.
00809           //
00810           status = fread( cmploc, SIO_LEN_SB, data_length, handle );
00811           if( status < data_length )
00812             {
00813               state = SIO_STATE_ERROR;
00814               if( verbosity >= SIO_ERRORS )
00815                 {
00816                   std::cout << "SIO: ["  << name << "/" << rec_name << "/] "
00817                             << "Failed reading compressed record data"
00818                             << std::endl;
00819                 }
00820               return( SIO_STREAM_EOF );
00821             }
00822 
00823           //
00824           // Skip the read pointer over any padding bytes that may have been
00825           // inserted to make the next record header start on a four byte
00826           // boundary in the file.
00827           //
00828           padlen = (4 - (data_length & SIO_align)) & SIO_align;
00829           if( padlen > 0 )
00830             {
00831               status = fseek( handle, padlen, 1 );
00832               if( status != 0 )
00833                 {
00834                   state = SIO_STATE_ERROR;
00835                   if( verbosity >= SIO_ERRORS )
00836                     {
00837                       std::cout << "SIO: ["  << name << "/" << rec_name << "/] "
00838                                 << "Failed reading end-of-record pad data"
00839                                 << std::endl;
00840                     }
00841                   return( SIO_STREAM_EOF );
00842                 }
00843             }
00844 
00845           //
00846           // Set up for the decompression.
00847           //
00848           z_strm->next_in   = cmploc;
00849           z_strm->avail_in  = data_length;
00850           z_strm->total_in  = 0;
00851 
00852           z_strm->next_out  = buffer;
00853           z_strm->avail_out = bufmax-buffer;
00854           z_strm->total_out = 0;
00855 
00856           z_stat = inflate( z_strm, Z_FINISH );
00857           if( z_stat != Z_STREAM_END )
00858             {
00859               state = SIO_STATE_ERROR;
00860               if( verbosity >= SIO_ERRORS )
00861                 {
00862                   std::cout << "SIO: ["  << name << "/" << rec_name << "/] "
00863                             << "ZLIB error number " << z_stat
00864                             << std::endl;
00865 
00866                   std::cout << "SIO: ["  << name << "/" << rec_name << "/] "
00867                             << "Decompression failed"
00868                             << std::endl;
00869                 }
00870               return( SIO_STREAM_BADCOMPRESS );
00871             }
00872 
00873           z_stat = inflateReset( z_strm );
00874           if( z_stat != Z_OK )
00875             {
00876               state = SIO_STATE_ERROR;
00877               if( verbosity >= SIO_ERRORS )
00878                 {
00879                   std::cout << "SIO: ["  << name << "/" << rec_name << "/] "
00880                             << "ZLIB error number " << z_stat
00881                             << std::endl;
00882 
00883                   std::cout << "SIO: ["  << name << "/" << rec_name << "/] "
00884                             << "Decompression de-initialization failed"
00885                             << std::endl;
00886                 }
00887               return( SIO_STREAM_BADCOMPRESS );
00888             }
00889 
00890         }
00891 
00892       //
00893       // Let the record manager sort out reading all the blocks.
00894       //
00895       recmax = bufloc + head_length + ucmp_length;
00896       status = (*record)->read( this, options );
00897 
00898       //
00899       // Clear the maps that may have accumulated during record unpacking.
00900       // This must be done unconditionally (otherwise tables from a busted
00901       // record may persist into the next record).
00902       //
00903       pointerTo->erase( pointerTo->begin(), pointerTo->end() );
00904       pointedAt->erase( pointedAt->begin(), pointedAt->end() );
00905 
00906       if( !( status & 1 ) )
00907         {
00908           if( verbosity >= SIO_ERRORS )
00909             {
00910               std::cout << "SIO: ["  << name << "/" << rec_name << "/] "
00911                         << "Unpacking error"
00912                         << std::endl;
00913             }
00914         }
00915     }
00916 
00917   //
00918   // That's all folks!
00919   //
00920   return( status );
00921 }

SIO_verbosity SIO_stream::setVerbosity SIO_verbosity   ) 
 

Definition at line 927 of file SIO_stream.cc.

References SIO_verbosity.

00930 { SIO_verbosity o_verb = verbosity; verbosity = i_verb; return( o_verb ); }

unsigned int SIO_stream::write SIO_record ,
const char * 
[private]
 

Definition at line 987 of file SIO_stream.cc.

References SIO_functions::copy(), SIO_align, SIO_ALL, SIO_DATA, SIO_ERRORS, SIO_LEN_QB, SIO_MODE_READ, SIO_STATE_ERROR, SIO_STATE_OPEN, SIO_STREAM_BADCOMPRESS, SIO_STREAM_BADWRITE, SIO_STREAM_NOALLOC, SIO_STREAM_NOTOPEN, SIO_STREAM_READONLY, SIO_STREAM_SUCCESS, and UCHR_CAST.

00991 {
00992 
00993   //
00994   // Local variables.
00995   //
00996   int
00997     z_stat;
00998 
00999   unsigned int
01000     data_length,
01001     data_length_off,
01002     head_length,
01003     head_length_off,
01004     name_length,
01005     ucmp_length,
01006     ucmp_length_off,
01007     bufout,
01008     compress,
01009     newlen,
01010     oldlen,
01011     options,
01012     status;
01013 
01014   unsigned char
01015     *newbuf;
01016 
01017   static unsigned char
01018     pad[4] = { 0, 0, 0, 0 };
01019 
01020   //
01021   // The stream must be open!
01022   //
01023   if( state != SIO_STATE_OPEN )
01024     {
01025       if( verbosity >= SIO_ERRORS )
01026         {
01027           std::cout << "SIO: ["  << name << "//] "
01028                     << "Cannot write (stream is not open)"
01029                     << std::endl;
01030         }
01031       return( SIO_STREAM_NOTOPEN );
01032     }
01033 
01034   //
01035   // This must be a writeable stream!
01036   //
01037   if( mode == SIO_MODE_READ )
01038     {
01039       if( verbosity >= SIO_ERRORS )
01040         {
01041           std::cout << "SIO: ["  << name << "//] "
01042                     << "Cannot write (stream is read only)"
01043                     << std::endl;
01044         }
01045       return( SIO_STREAM_READONLY );
01046     }
01047 
01048   //
01049   // Capture the record name for error reporting.
01050   //
01051   rec_name = i_name;
01052 
01053   //
01054   // Initialize the buffer.
01055   //
01056   buffer = bufloc;
01057 
01058   //
01059   // Output: 1) A placeholder for the record header length.
01060   //         2) A 'framing' marker (to help in debugging).
01061   //         3) An options word.
01062   //         4) A placeholder for the record data length (compressed).
01063   //         5) A placeholder for the record data length (uncompressed).
01064   //         6) The length of the record name.
01065   //         7) The record name.
01066   //
01067   compress = record->getCompress();
01068   options  = record->getOptions();
01069 
01070   head_length_off = buffer - bufloc;
01071   SIO_DATA( this, &SIO_mark_record,            1           );
01072   SIO_DATA( this, &SIO_mark_record,            1           );
01073   SIO_DATA( this, &options,                    1           );
01074 
01075   data_length_off = buffer - bufloc;
01076   SIO_DATA( this, &SIO_mark_record,            1           );
01077 
01078   ucmp_length_off = buffer - bufloc;
01079   SIO_DATA( this, &SIO_mark_record,            1           );
01080 
01081   name_length = strlen( i_name );
01082   SIO_DATA( this, &name_length,                1           );
01083   SIO_DATA( this,  const_cast<char *>(i_name), name_length );
01084 
01085   //
01086   // Back fill the length of the record header.
01087   //
01088   head_length = buffer - bufloc;
01089   SIO_functions::copy( UCHR_CAST(&head_length), (bufloc + head_length_off),
01090                        SIO_LEN_QB,              1                        );
01091 
01092   //
01093   // Ask the record object to fill the buffer with blocks. If an error is
01094   // reported, just print a complaint and skip writing this buffer.
01095   //
01096   status = record->write( this );
01097   if( !(status & 1) )
01098     {
01099       if( verbosity >= SIO_ERRORS )
01100         {
01101           std::cout << "SIO: ["  << name << "/" << rec_name << "/] "
01102                     << "Packing error"
01103                     << std::endl;
01104         }
01105       return( status );
01106     }
01107 
01108   //
01109   // Fill in the uncompressed record length.
01110   //
01111   ucmp_length = (buffer - bufloc) - head_length;
01112   SIO_functions::copy( UCHR_CAST(&ucmp_length), (bufloc + ucmp_length_off),
01113                        SIO_LEN_QB,              1                        );
01114 
01115   //
01116   // Write out the complete record.
01117   //
01118   if( !compress )
01119     {
01120       //
01121       // Fill in the written length of the record data (identical with the
01122       // uncompressed length when no compression is being performed).
01123       //
01124       data_length = ucmp_length;
01125       SIO_functions::copy( UCHR_CAST(&data_length), (bufloc + data_length_off),
01126                            SIO_LEN_QB,              1                        );
01127 
01128       //
01129       // When not compressing, both the record header and the record data
01130       // can be written in one swell foop.  Note that uncompressed data always
01131       // satisfies the requirement that it ends on a four byte boundary, so
01132       // no padding is required.
01133       //
01134       data_length += head_length;
01135       bufout = fwrite( bufloc, sizeof(char), data_length, handle );
01136       if( bufout != data_length )
01137         {
01138           state = SIO_STATE_ERROR;
01139           if( verbosity >= SIO_ERRORS )
01140             {
01141               std::cout << "SIO: ["  << name << "/" << rec_name << "/] "
01142                         << "File error writing record"
01143                         << std::endl;
01144             }
01145           return( SIO_STREAM_BADWRITE );
01146         }
01147     }
01148   else
01149     {
01150       //
01151       // Set up for the compression.
01152       //
01153       z_strm->next_in   = bufloc + head_length;
01154       z_strm->avail_in  = ucmp_length;
01155       z_strm->total_in  = 0;
01156 
01157       z_strm->next_out  = cmploc;
01158       z_strm->avail_out = cmpmax - cmploc;
01159       z_strm->total_out = 0;
01160 
01161       //
01162       // Loop the compression in case the compression buffer is not big enough.
01163       //
01164       for(;;)
01165         {
01166           z_stat = deflate( z_strm, Z_FINISH );
01167           if( z_strm->avail_out > 0 )
01168             break;
01169 
01170           newlen = (cmpmax - cmploc) << 1;
01171           newbuf = static_cast<unsigned char*>(malloc( newlen ));
01172           if( newbuf == NULL )
01173             {
01174               if( verbosity >= SIO_ERRORS )
01175                 {
01176                   std::cout << "SIO: ["
01177                             << name     << "/"
01178                             << rec_name << "//] "
01179                             << "Compression buffer allocation failed"
01180                             << std::endl;
01181                 }
01182 
01183               state = SIO_STATE_ERROR;
01184               return( SIO_STREAM_NOALLOC );
01185             }
01186 
01187           oldlen = z_strm->next_out - cmploc;
01188           memcpy( newbuf, cmploc, oldlen );
01189           free( cmploc );
01190           cmploc = newbuf;
01191           cmpmax = cmploc + newlen;
01192 
01193           z_strm->next_out  = cmploc + oldlen;
01194           z_strm->avail_out = cmpmax - z_strm->next_out;
01195 
01196           if( verbosity >= SIO_ALL )
01197             {
01198               std::cout << "SIO: ["
01199                         << name     << "/"
01200                         << rec_name << "/] "
01201                         << "Allocated a "
01202                         << newlen
01203                         << "(0x" << std::hex << newlen << std::dec << ")"
01204                         << " byte compression buffer"
01205                         << std::endl;
01206             }
01207         }
01208 
01209       z_stat = deflateReset( z_strm );
01210       if( z_stat != Z_OK )
01211         {
01212           state = SIO_STATE_ERROR;
01213           if( verbosity >= SIO_ERRORS )
01214             {
01215               std::cout << "SIO: ["  << name << "//] "
01216                         << "ZLIB error number " << z_stat
01217                         << std::endl;
01218 
01219               std::cout << "SIO: ["  << name << "//] "
01220                         << "Compression de-initialization failed"
01221                         << std::endl;
01222             }
01223           return( SIO_STREAM_BADCOMPRESS );
01224         }
01225 
01226       //
01227       // Fill in the length of the compressed buffer.
01228       //
01229       data_length = z_strm->next_out - cmploc;
01230       SIO_functions::copy( UCHR_CAST(&data_length), (bufloc + data_length_off),
01231                            SIO_LEN_QB,              1                        );
01232 
01233       //
01234       // Write the record header.
01235       //
01236       bufout = fwrite( bufloc, sizeof(char), head_length, handle );
01237       if( bufout != head_length )
01238         {
01239           state = SIO_STATE_ERROR;
01240           if( verbosity >= SIO_ERRORS )
01241             {
01242               std::cout << "SIO: ["  << name << "/" << rec_name << "/] "
01243                         << "File error writing record header"
01244                         << std::endl;
01245             }
01246           return( SIO_STREAM_BADWRITE );
01247         }
01248 
01249       //
01250       // Write the compressed record data.
01251       //
01252       bufout = fwrite( cmploc, sizeof(char), data_length, handle );
01253       if( bufout != data_length )
01254         {
01255           state = SIO_STATE_ERROR;
01256           if( verbosity >= SIO_ERRORS )
01257             {
01258               std::cout << "SIO: ["  << name << "/" << rec_name << "/] "
01259                         << "File error writing record content"
01260                         << std::endl;
01261             }
01262           return( SIO_STREAM_BADWRITE );
01263         }
01264 
01265       //
01266       // Insert any necessary padding to make the next record header start
01267       // on a four byte boundary in the file (to make it directly accessible
01268       // for xdr read).
01269       //
01270       newlen = (4 - (data_length & SIO_align)) & SIO_align;
01271       if( newlen > 0 )
01272         {
01273           bufout = fwrite( pad, sizeof(char), newlen, handle );
01274           if( bufout != newlen )
01275             {
01276               state = SIO_STATE_ERROR;
01277               if( verbosity >= SIO_ERRORS )
01278                 {
01279                   std::cout << "SIO: ["  << name << "/" << rec_name << "/] "
01280                             << "File error writing end-of-record pad"
01281                             << std::endl;
01282                 }
01283               return( SIO_STREAM_BADWRITE );
01284             }
01285         }
01286     }
01287 
01288   //
01289   // Clear the maps that may have accumulated during record writing.
01290   //
01291   pointerTo->erase( pointerTo->begin(), pointerTo->end() );
01292   pointedAt->erase( pointedAt->begin(), pointedAt->end() );
01293 
01294   //
01295   // That's all folks!
01296   //
01297   return( SIO_STREAM_SUCCESS );
01298 }

unsigned int SIO_stream::write SIO_record  ) 
 

Definition at line 972 of file SIO_stream.cc.

00975 {
00976 
00977   //
00978   // Call the workhorse.
00979   //
00980   return( write( record, record->getName()->c_str() ) );
00981 }

unsigned int SIO_stream::write const char *   ) 
 

Definition at line 936 of file SIO_stream.cc.

References SIO_recordManager::get(), SIO_ERRORS, and SIO_STREAM_NOSUCHRECORD.

Referenced by LCDG4EventAction::EndOfEventAction(), and LCDG4_SIOglobal::LCDG4_SIOglobal().

00939 {
00940 
00941   //
00942   // Local variables.
00943   //
00944   SIO_record
00945     *record;
00946 
00947   //
00948   // Validate the record name.
00949   //
00950   record = SIO_recordManager::get( i_name );
00951   if( record == NULL )
00952     {
00953       if( verbosity >= SIO_ERRORS )
00954         {
00955           std::cout << "SIO: ["  << name << "/" << i_name << "//] "
00956                     << "Record name not recognized"
00957                     << std::endl;
00958         }
00959       return( SIO_STREAM_NOSUCHRECORD );
00960     }
00961 
00962   //
00963   // Call the workhorse.
00964   //
00965   return( write( record, i_name ) );
00966 }


Friends And Related Function Documentation

friend class SIO_functions [friend]
 

Definition at line 84 of file SIO_stream.h.

friend class SIO_record [friend]
 

Definition at line 83 of file SIO_stream.h.

friend class SIO_streamManager [friend]
 

Definition at line 82 of file SIO_stream.h.


Member Data Documentation

std::string SIO_stream::blk_name [private]
 

Definition at line 72 of file SIO_stream.h.

unsigned char* SIO_stream::blkmax [private]
 

Definition at line 61 of file SIO_stream.h.

Referenced by close().

unsigned char* SIO_stream::buffer [private]
 

Definition at line 58 of file SIO_stream.h.

Referenced by close().

unsigned char* SIO_stream::bufloc [private]
 

Definition at line 57 of file SIO_stream.h.

Referenced by close().

unsigned char* SIO_stream::bufmax [private]
 

Definition at line 59 of file SIO_stream.h.

Referenced by close().

unsigned char* SIO_stream::cmploc [private]
 

Definition at line 63 of file SIO_stream.h.

Referenced by close().

unsigned char* SIO_stream::cmpmax [private]
 

Definition at line 64 of file SIO_stream.h.

Referenced by close().

std::string SIO_stream::filename [private]
 

Definition at line 68 of file SIO_stream.h.

Referenced by close(), and getFilename().

FILE* SIO_stream::handle [private]
 

Definition at line 69 of file SIO_stream.h.

Referenced by close().

SIO_stream_mode SIO_stream::mode [private]
 

Definition at line 77 of file SIO_stream.h.

Referenced by close(), and getMode().

std::string SIO_stream::name [private]
 

Definition at line 67 of file SIO_stream.h.

Referenced by close(), and getName().

pointedAtMap_c* SIO_stream::pointedAt [private]
 

Definition at line 74 of file SIO_stream.h.

Referenced by close().

pointerToMap_c* SIO_stream::pointerTo [private]
 

Definition at line 75 of file SIO_stream.h.

Referenced by close().

std::string SIO_stream::rec_name [private]
 

Definition at line 71 of file SIO_stream.h.

unsigned char* SIO_stream::recmax [private]
 

Definition at line 60 of file SIO_stream.h.

Referenced by close().

unsigned int SIO_stream::reserve [private]
 

Definition at line 78 of file SIO_stream.h.

SIO_stream_state SIO_stream::state [private]
 

Definition at line 79 of file SIO_stream.h.

Referenced by close(), getState(), and ~SIO_stream().

SIO_verbosity SIO_stream::verbosity [private]
 

Definition at line 80 of file SIO_stream.h.

Referenced by close(), and getVerbosity().

struct z_stream_s* SIO_stream::z_strm [private]
 

Definition at line 65 of file SIO_stream.h.

Referenced by close().


The documentation for this class was generated from the following files:
Generated on Thu Oct 7 18:45:10 2004 for LCDG4 by doxygen 1.3.4