00001 #include "SIO/LCSIO.h"
00002
00003 #include "SIO_functions.h"
00004 #include "SIO_stream.h"
00005 #include "SIO_recordManager.h"
00006 #include <cctype>
00007 #include <cerrno>
00008 #include "Exceptions.h"
00009
00010 #include <iostream>
00011 #include <sstream>
00012
00013 using namespace EVENT ;
00014
00015 namespace SIO {
00016
00017
00018 SIORecords::SIORecords(){
00019
00020 add( _records[ Event ] , LCSIO_EVENTRECORDNAME ) ;
00021 add( _records[ Header ] , LCSIO_HEADERRECORDNAME ) ;
00022 add( _records[ Run ] , LCSIO_RUNRECORDNAME ) ;
00023 add( _records[ Access ] , LCSIO_ACCESSRECORDNAME ) ;
00024 add( _records[ Index ] , LCSIO_INDEXRECORDNAME ) ;
00025
00026 }
00027 SIO_record* SIORecords::operator[](size_t idx){
00028
00029 if( idx > NumberOfRecords )
00030 throw IO::IOException( " Out of range in SIORecords::operator[](size_t i)" ) ;
00031
00032 return _records[ idx ] ;
00033 }
00034
00035 void SIORecords::add(SIO_record*& rec , const char* name){
00036
00037 rec = SIO_recordManager::add( name ) ;
00038
00039 if( rec == 0 ) {
00040 std::string err("[LCSIO::SIORecords]: Could not add SIO record: ") ;
00041 err+=name ;
00042 throw IO::IOException( err ) ;
00043 }
00044 }
00045
00046 void SIORecords::setCompress( bool flag) {
00047
00048 for( unsigned i=0; i < NumberOfRecords ; ++i ){
00049
00050 if( i != Access )
00051 _records[i]->setCompress( flag ) ;
00052 else
00053 _records[i]->setCompress( false ) ;
00054
00055 }
00056 }
00057
00058 SIORecords::Unpack::Unpack( unsigned recordFlag ) {
00059
00060 for( unsigned i=0; i < NumberOfRecords ; ++i ){
00061
00062 _flags[i] = LCSIO::records()[i]->getUnpack() ;
00063
00064 LCSIO::records()[ i ]->setUnpack( recordFlag & ( 0x0001 << i ) ) ;
00065 }
00066 }
00067 SIORecords::Unpack::~Unpack() {
00068
00069 for( unsigned i=0; i < NumberOfRecords ; ++i ){
00070
00071 LCSIO::records()[ i ]->setUnpack( _flags ) ;
00072 }
00073
00074 }
00075
00076
00077
00078
00079 int LCSIO::uid = 0 ;
00080 int LCSIO::dummy_size = LCSIO::dummy_initial_size ;
00081 char* LCSIO::dummy = new char[ LCSIO::dummy_initial_size ] ;
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091 const char* LCSIO::FILE_EXTENSION=".slcio" ;
00092
00093
00094 void LCSIO::seekStream( SIO_stream* stream , long64 pos) {
00095
00096 if( stream->getState() != SIO_STATE_OPEN ){
00097
00098 throw IO::IOException( std::string(" stream not open: ")+ *stream->getName() ) ;
00099 }
00100
00101 int status ;
00102
00103 if( pos < 0 )
00104 status = stream->seek( pos , SEEK_END ) ;
00105 else
00106 status = stream->seek( pos ) ;
00107
00108 if( status != SIO_STREAM_SUCCESS ) {
00109 std::stringstream s ; s << "[LCSIO::seekStream] Can't seek stream to " << pos << " errno : " << errno ;
00110 throw IO::IOException( s.str() ) ;
00111 }
00112
00113 }
00114
00115
00116 void LCSIO::checkVersion(int versionID){
00117 if ( SIO_VERSION_MAJOR( versionID ) < 1 && SIO_VERSION_MINOR(versionID) < 8)
00118 throw IO::IOException(" Old file versions ( < v00-08 ) no longer supported !") ;
00119 }
00120
00121
00122 SIORecords& LCSIO::records() {
00123 static SIORecords recs ;
00124 return recs ;
00125 }
00126
00127 unsigned int LCSIO::read( SIO_stream* stream ,char** c, int* len){
00128
00129 int status ;
00130 int strLen ;
00131 status = SIO_functions::data( stream , &strLen , 1 ) ;
00132
00133 if( !( status & 1 ) ) return status ;
00134
00135
00136 while( strLen + 1 > dummy_size ){
00137 dummy_size += dummy_size ;
00138 delete[] dummy ;
00139 dummy = new char[ dummy_size ] ;
00140
00141
00142 }
00143
00144 SIO_functions::data( stream , dummy , strLen ) ;
00145 dummy[ strLen ] = '\0' ;
00146
00147 *c = dummy ;
00148 if(len!=0)
00149 *len = strLen ;
00150
00151 return status ;
00152 }
00153
00154 unsigned int LCSIO::write( SIO_stream* stream , int i){
00155
00156 int local = i ;
00157 return SIO_functions::data( stream , &local , 1 ) ;
00158
00159 }
00160 unsigned int LCSIO::write( SIO_stream* stream , unsigned int i){
00161
00162 unsigned int local = i ;
00163 return SIO_functions::data( stream , &local , 1 ) ;
00164
00165 }
00166
00167
00168 #if defined(_LP64) || defined(__APPLE_CC__)
00169 unsigned int LCSIO::write( SIO_stream* stream , size_t i){
00170
00171 unsigned int local = i ;
00172 return SIO_functions::data( stream , &local , 1 ) ;
00173
00174 }
00175 #endif
00176
00177 unsigned int LCSIO::write( SIO_stream* stream , long64 i){
00178
00179 long64 local = i ;
00180 return SIO_functions::data( stream , &local , 1 ) ;
00181
00182 }
00183
00184 unsigned int LCSIO::write( SIO_stream* stream , float f){
00185
00186 float local = f ;
00187 return SIO_functions::data( stream , &local , 1 ) ;
00188 }
00189
00190
00191 unsigned int LCSIO::write(SIO_stream* stream , const std::string& s){
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213 int strLen = s.length() ;
00214 int status = SIO_functions::data( stream , & strLen , 1 ) ;
00215 if( !( status & 1 ) ) return status ;
00216 return SIO_functions::data( stream , const_cast<char*>( s.c_str() ), strLen );
00217 }
00218
00219
00220
00221
00222
00223 std::string LCSIO::getValidSIOName(const std::string& aName ) {
00224
00225 const char* name = aName.c_str() ;
00226
00227 char* newName = new char[ aName.length() + 1 ];
00228 const char * returnStrP = newName ;
00229 std::stringstream returnStr ;
00230
00231 if( *name == '\\' || *name == '/' || *name=='.' )
00232 *newName++ = '_' ;
00233
00234 else if ( (*name < 0 ) || ( !isalpha( (int)*name ) && *name != '_' ) )
00235 *newName++ = 'A' ;
00236 else
00237 *newName++ = *name ;
00238
00239
00240 for( name += 1; *name != '\0'; name++ ){
00241
00242 if( *name == '\\' || *name == '/' || *name=='.' )
00243 *newName++ = '_' ;
00244
00245 else if( (*name>=0) && ( isalnum( (int)*name ) || *name == '_' ) )
00246 *newName++ = *name ;
00247 else
00248 ;
00249 }
00250
00251 *newName = '\0' ;
00252
00253
00254 returnStr << returnStrP << uid++;
00255 delete[] returnStrP ;
00256
00257 return returnStr.str() ;
00258 }
00259
00260
00261 }
00262