メインページ   モジュール   名前空間一覧   クラス階層   アルファベット順一覧   構成   ファイル一覧   構成メンバ   ファイルメンバ   関連ページ    

TObjectFile.cc

解説を見る。
00001 // =====================================================================
00002 //  $Id: TObjectFile.cc,v 1.8 2004/03/07 10:30:32 goiwai Exp $
00003 //  $Name: CLDAQ-1-14-03 $
00004 //  $Log: TObjectFile.cc,v $
00005 //  Revision 1.8  2004/03/07 10:30:32  goiwai
00006 //  ROOTに組みこむためのおまじないマクロを埋めこみました。
00007 //  全てにおいて完全に動作するわけではありません。
00008 //
00009 //  Revision 1.7  2003/11/27 07:34:54  goiwai
00010 //  TInputObjectFile::operator[](index)の挙動がおかしかったので直しました.
00011 //  そしてちょっとだけ高速化しました.
00012 //  これであらかたバグはつぶしたと思うんですけど...
00013 //
00014 //  Revision 1.6  2003/11/24 22:38:50  goiwai
00015 //  Size(),operator[int]を使ったときに異常に遅くなる問題を解消しました.
00016 //  ストリームからの読みだしサイズが実際のファイルサイズと一致しない問題を
00017 //  解決しました.
00018 //
00019 //  Revision 1.5  2003/11/24 07:04:37  goiwai
00020 //  以下のメンバ関数を追加しました.
00021 //  このへんはオフラインむけの関数と考えて下さい.
00022 //  ソケットやメモリに対してこのへんを実装するのは骨が折れそうなので,ファ
00023 //  イルのみへの実装とします.
00024 //
00025 //  Tint GetStreamSize() const;
00026 //  ストリームの全長をバイト単位で返します.
00027 //
00028 //  Tint Size() const;
00029 //  ストリームに含まれるレコードの数を返します.
00030 //
00031 //  Tint FindDataRecord( const Tstring& id, Tint offset = 0 ) const;
00032 //  Tint Find( const Tstring& id, Tint offset = 0 ) const;
00033 //  IDに一致するレコード位置を返します.そのときオフセットもその位置になります.
00034 //
00035 //  Tint FindDataRecord( Tint index, Tint offset = 0 ) const;
00036 //  Tint Find( Tint index, Tint offset = 0 ) const;
00037 //  index番目のレコード位置を返します.そのときオフセットもその位置になります.
00038 //
00039 //  Revision 1.4  2003/10/12 13:03:43  goiwai
00040 //  最近できた FileProperty を持たせています.またEOFとエラーの検知のために
00041 //  IsEnd()とIsError()を追加しました.
00042 //
00043 //  Revision 1.3  2003/10/06 17:02:42  goiwai
00044 //  *** empty log message ***
00045 //
00046 //  Revision 1.2  2003/07/30 16:19:30  goiwai
00047 //  ファイルにコミットログをつけることにしました.
00048 //
00049 // =====================================================================
00050 #include "TObjectFile.hh"
00051 #include "TFileProperty.hh"
00052 
00053 TObjectFile::TObjectFile( const Tstring& filename, const Tstring& mode )
00054   : theFileName( filename ), 
00055     theMode( mode ),
00056     theFileStream( 0 ),
00057     theFileProperty()
00058 {
00059   theFileStream = fopen( theFileName.c_str(), theMode.c_str() );
00060   theFileProperty.SetPathName( theFileName );
00061 }
00062 
00063 TObjectFile::~TObjectFile()
00064 {
00065   fclose( theFileStream );
00066 }
00067 
00068 Tint TObjectFile::GetStreamSize() const
00069 {
00070   if ( !isexist( theFileName ) ) {
00071     return ERROR;
00072   }
00073 
00074   TFileProperty p( theFileName );
00075   if ( !p.IsReadable() ) {
00076     return ERROR;
00077   }
00078 
00079   TFileStream* fs = fopen( theFileName.c_str(), "r" );
00080   if ( !fs ) {
00081     return ERROR;
00082   }
00083 
00084   Tint retval = 0;
00085   Tlong posbuf = 0;
00086   Tint recsizebuf = -1;
00087   static const Tsize_t nread = 1;
00088 
00089   while ( !feof(fs) ) {
00090     // record size を取得
00091     // DataRecordが入ってるものだと決め打ちでいきましょう
00092     posbuf = ftell( fs );
00093     if ( posbuf == -1 ) {
00094       break;
00095     }
00096     Tsize_t result = fread( &recsizebuf, Tsizeof( Tint ), nread, fs );
00097     if ( result != nread || ferror( fs ) != 0 ) {
00098       break;
00099     } else {
00100       if ( fseek( fs, posbuf+recsizebuf, SEEK_SET ) != 0 ) {
00101         break;
00102       }
00103       retval += recsizebuf;
00104     }
00105   }
00106   fclose( fs );
00107 
00108   return retval;
00109 }
00110 
00111 Tint TObjectFile::Size() const
00112 {
00113   static Tint lastmod = -1;
00114   static Tint lastresult = 0;
00115 
00116   if ( !isexist( theFileName ) ) {
00117     return ERROR;
00118   }
00119 
00120   TFileProperty p( theFileName );
00121   if ( !p.IsReadable() ) {
00122     return ERROR;
00123   }
00124 
00125   if ( lastmod == theFileProperty.GetLastModification() ) {
00126     return lastresult;
00127   }
00128 
00129   TFileStream* fs = fopen( theFileName.c_str(), "r" );
00130   if ( !fs ) {
00131     return ERROR;
00132   }
00133 
00134   Tint retval = 0;
00135   Tlong posbuf = 0;
00136   Tint recsizebuf = -1;
00137   static const Tsize_t nread = 1;
00138 
00139   while ( !feof(fs) ) {
00140     // record size を取得
00141     // DataRecordが入ってるものだと決め打ちでいきましょう
00142     posbuf = ftell( fs );
00143     if ( posbuf == -1 ) {
00144       break;
00145     }
00146     Tsize_t result = fread( &recsizebuf, Tsizeof( Tint ), nread, fs );
00147     if ( result != nread || ferror( fs ) != 0 ) {
00148       break;
00149     } else {
00150       if ( fseek( fs, posbuf+recsizebuf, SEEK_SET ) != 0 ) {
00151         break;
00152       }
00153       retval ++;
00154     }
00155   }
00156   fclose( fs );
00157 
00158   if ( retval > 0 ) {
00159     lastmod = theFileProperty.GetLastModification();
00160     lastresult = retval;
00161   }
00162   return retval;
00163 }
00164 
00165 Tint TObjectFile::FindDataRecord( const Tstring& id, Tint offset ) const
00166 {
00167   if ( !isexist( theFileName ) ) {
00168     return ERROR;
00169   }
00170 
00171   TFileProperty p( theFileName );
00172   if ( !p.IsReadable() ) {
00173     return ERROR;
00174   }
00175 
00176   TFileStream* fs = fopen( theFileName.c_str(), "r" );  
00177   if ( !fs ) {
00178     return ERROR;
00179   }
00180 
00181   if ( fseek( fs, offset, SEEK_SET ) != 0 ) {
00182     fclose( fs );
00183     return ERROR;
00184   }
00185 
00186   Tint retval = ERROR;
00187   Tlong posbuf = 0;
00188   Tint recsizebuf = -1;
00189   Tobject_t typebuf = tObjectUnknown;
00190   Tsize_t ncharbuf = 0;
00191   static const Tsize_t nread = 1;
00192 
00193   while ( !feof(fs) ) {
00194     // 現在位置設定
00195     posbuf = ftell( fs );
00196     if ( posbuf == -1 ) {
00197       break;
00198     }
00199 
00200     // record size
00201     Tsize_t result = fread( &recsizebuf, Tsizeof( Tint ), nread, fs );
00202     if ( result != nread || ferror( fs ) != 0 ) {
00203       break;
00204     }
00205 
00206     // object type
00207     result = fread( &typebuf, Tsizeof( Tobject_t ), nread, fs );
00208     if ( result != nread || ferror( fs ) != 0 || typebuf != tObjectDataRecord ) {
00209       break;
00210     }
00211 
00212     // read number of ID string
00213     result = fread( &ncharbuf, Tsizeof( Tsize_t ), nread, fs );
00214     if ( result != nread || ferror( fs ) != 0 ) {
00215       break;
00216     }
00217 
00218     Tchar* charbuf = new Tchar[ ncharbuf ];
00219     result = fread( charbuf, Tsizeof(Tchar) * ncharbuf, nread, fs );
00220 
00221     if ( id == charbuf ) {
00222       retval = posbuf;
00223       delete [] charbuf;
00224       break;
00225     } else {
00226       if ( fseek( fs, posbuf+recsizebuf, SEEK_SET ) != 0 ) {
00227         break;
00228       }
00229       delete [] charbuf;
00230     }
00231   }
00232   fclose( fs );
00233 
00234   return retval;
00235 }
00236 
00237 Tint TObjectFile::FindDataRecord( Tint index, Tint offset ) const
00238 {
00239   static Tint lastindex = -1;
00240   static Tint lastresult = -1;
00241 
00242   if ( index < 0 ) {
00243     return ERROR;
00244   }
00245 
00246   Tint maxsize = Size();
00247   if ( index >= maxsize ) {
00248     return ERROR;
00249   }
00250 
00251   if ( !isexist( theFileName ) ) {
00252     return ERROR;
00253   }
00254 
00255   TFileProperty p( theFileName );
00256   if ( !p.IsReadable() ) {
00257     return ERROR;
00258   }
00259 
00260   TFileStream* fs = fopen( theFileName.c_str(), "r" );
00261   if ( !fs ) {
00262     return ERROR;
00263   }
00264 
00265   if ( fseek( fs, offset, SEEK_SET ) != 0 ) {
00266     fclose( fs );
00267     return ERROR;
00268   }
00269 
00270 
00271   Tint start = 0;
00272   if ( lastindex >= 0 && lastresult >= 0 ) {
00273     if ( index > lastindex ) {
00274       if ( fseek( fs, lastresult, SEEK_SET ) != 0 ) {
00275         fclose( fs );
00276         return ERROR;
00277       }
00278       start = lastindex;
00279     } else if ( lastindex == index ) {
00280       // 前回と同じindexを呼び出したときも高速化
00281       return lastresult;
00282     } else {
00283       ;
00284     }
00285   }
00286 
00287   Tint retval = 0;
00288   Tlong posbuf = 0;
00289   Tint recsizebuf = -1;
00290   static const Tsize_t nread = 1;
00291 
00292   for ( Tint i = start; i <= index; i ++ ) {
00293     // record size を取得
00294     // DataRecordが入ってるものだと決め打ちでいきましょう
00295     posbuf = ftell( fs );
00296     if ( posbuf == -1 ) {
00297       return ERROR;
00298     } else if ( i == index ) {
00299       retval = posbuf;
00300       break;
00301     }
00302 
00303     Tsize_t result = fread( &recsizebuf, Tsizeof( Tint ), nread, fs );
00304     if ( result != nread || ferror( fs ) != 0 ) {
00305       return ERROR;
00306     } else if ( fseek( fs, posbuf+recsizebuf, SEEK_SET ) != 0 ) {
00307       return ERROR;
00308     }
00309   }
00310   fclose( fs );
00311 
00312   if ( retval >= 0 ) {
00313     lastindex = index;
00314     lastresult = retval;
00315   }
00316 
00317   return retval;
00318 }
00319 
00320 #ifdef __CLDAQ_ROOT_DLL
00321     ClassImp(TObjectFile)
00322 #endif


CLDAQ - a Class Library for DataAcQuisition (Version 1.14.3)
Go IWAI -- goiwai at users.sourceforge.jp