SSM

include/ssm-log.hpp

00001 #ifndef SSM_LOG_HPP__
00002 #define SSM_LOG_HPP__
00003 
00004 #include <fstream>
00005 #include <string>
00006 #include <sstream>
00007 
00008 #include <ssm.hpp>
00009 
00010 class SSMLogBase
00011 {
00012 protected:
00013     std::fstream *mLogFile;
00014     ssmTimeT mTime; 
00015     void *mData;                                
00016     size_t mDataSize;                           
00017     void *mProperty;                            
00018     size_t mPropertySize;                       
00019     std::string mStreamName;
00020     int mStreamId;
00021     int mBufferNum; // ssmのリングバッファの個数
00022     double mCycle; // streamへの書き込みサイクル
00023     ssmTimeT mStartTime; // logを書き込み始めた時間
00024     std::ios::pos_type mStartPos; // logの開始位置
00025     std::ios::pos_type mEndPos; // logの終了位置
00026     std::ios::pos_type mPropertyPos; // propertyの書き込み位置
00027     
00028     void init()
00029     {
00030         mData = NULL;
00031         mDataSize = 0;
00032         mProperty = NULL;
00033         mPropertySize = 0;
00034         mStreamId = 0;
00035         mBufferNum = 0;
00036         mCycle = 0.0;
00037         mStartTime = 0.0;
00038     }
00039 
00040     bool writeProperty()
00041     {
00042         mLogFile->seekp( mPropertyPos );
00043         mLogFile->write( (char *)mProperty, mPropertySize );
00044         return true;
00045     }
00046 
00047     bool getLogInfo()
00048     {
00049         std::string line;
00050         mLogFile->seekg( 0, std::ios::beg );
00051         if( !getline( *mLogFile, line ) )
00052             return false;
00053         std::istringstream data( line.c_str(  ) );
00054 
00055         data
00056             >> mStreamName
00057             >> mStreamId
00058             >> mDataSize
00059             >> mBufferNum
00060             >> mCycle
00061             >> mStartTime
00062             >> mPropertySize
00063             ;
00064         if( data.fail() )
00065             return false;
00066 #if 0       
00067         std::cout
00068             << mStreamName << ' '
00069             << mStreamId << ' '
00070             << mDataSize << ' '
00071             << mBufferNum << ' '
00072             << mCycle << ' '
00073             << mStartTime << ' '
00074             << mPropertySize
00075             << std::endl;
00076 #endif
00077         // プロパティの読み込み
00078         mPropertyPos = mLogFile->tellg();
00079         if( mProperty )
00080             readProperty();
00081         else
00082             mLogFile->seekg( mPropertySize, std::ios::cur );
00083         
00084         // ログ位置の保存
00085         mStartPos = mLogFile->tellg();
00086         mLogFile->seekg(0, std::ios::end );
00087         mEndPos = mLogFile->tellg();
00088         mLogFile->seekg( mStartPos );
00089         
00090         mTime = mStartTime;
00091                 
00092         return true;
00093     }
00094 
00095     bool setLogInfo()
00096     {
00097         mLogFile->setf(std::ios::fixed);
00098         mLogFile->seekp( 0, std::ios::beg );
00099         mStartTime = gettimeSSM();
00100         *mLogFile
00101             << mStreamName << ' '
00102             << mStreamId << ' '
00103             << mDataSize << ' '
00104             << mBufferNum << ' '
00105             << mCycle << ' '
00106             << mStartTime << ' '
00107             << mPropertySize
00108             << std::endl;
00109 
00110         // プロパティの書き込み
00111         mPropertyPos = mLogFile->tellp();
00112         writeProperty();
00113         
00114         // ログ開始位置の保存
00115         mStartPos = mLogFile->tellp();
00116         return true;        
00117     }
00118     
00119 public:
00120     SSMLogBase()
00121     {
00122         init();
00123     }
00124 
00125     virtual ~SSMLogBase()
00126     {
00127     }
00128     void setBuffer(void *data, size_t dataSize, void *property, size_t propertySize )
00129     {
00130         mData = data;
00131         mDataSize = dataSize;
00132         mProperty = property;
00133         mPropertySize = propertySize;
00134     }
00135 
00136     bool readProperty()
00137     {
00138         int curPos;
00139         curPos = mLogFile->tellg();
00140 
00141         mLogFile->seekg( mPropertyPos, std::ios::beg );
00142         mLogFile->read( (char *)mProperty, mPropertySize );
00143 
00144         mLogFile->seekg( curPos, std::ios::beg );
00145         return true;
00146     }
00147     
00148     bool open( const char *fileName )
00149     {
00150         mLogFile = new std::fstream(  );
00151         mLogFile->open( fileName, std::ios::in );
00152         if( !mLogFile->is_open(  ) )
00153         {
00154             delete mLogFile;
00155             std::cerr << "SSMLogBase::open : cannot open log file '" << fileName << "'." << std::endl;
00156             return false;
00157         }
00158         if( !getLogInfo(  ) )
00159         {
00160             std::cerr << "SSMLogBase::open : '" << fileName << "' is NOT ssm-log file." << std::endl;
00161             return false;
00162         }
00163         return true;
00164     }
00165     
00166     bool create( const char *streamName, int streamId, int bufferNum, double cycle, const char *fileName )
00167     {
00168         mLogFile = new std::fstream(  );
00169         mLogFile->open( fileName, std::ios::out | std::ios::trunc );
00170         mStreamName = streamName;
00171         mStreamId = streamId;
00172         mBufferNum = bufferNum;
00173         mCycle = cycle;
00174         if( !mLogFile->is_open(  ) )
00175             return false;
00176         if( !setLogInfo(  ) )
00177             return false;
00178         return true;
00179     }
00180     
00181     bool close(  )
00182     {
00183         delete mLogFile;
00184         return true;
00185     }
00186     
00187     virtual bool write( ssmTimeT time = gettimeSSM(  ) )
00188     {
00189         mTime = time;
00190         mLogFile->write( (char *)&mTime, sizeof( ssmTimeT ) );
00191         mLogFile->write( (char *)mData, mDataSize );
00192         return true;
00193     }
00194     
00195     virtual bool read(  )
00196     {
00197         mLogFile->read( (char *)&mTime, sizeof( ssmTimeT ) );
00198         mLogFile->read( (char *)mData, mDataSize );
00199         return mLogFile->good(  );
00200     }
00201     
00202     bool readNext(  )
00203     {
00204         return read(  );
00205     }
00206     
00207     bool readBack(  )
00208     {
00209         return seek( -2 ) && read();
00210     }
00211     
00212     // read時専用
00213     bool seek( int diff )
00214     {
00215         mLogFile->clear(  ); // eofになっているとseekできないので
00216         std::fstream::pos_type pos,curPos = mLogFile->tellg();
00217         // シーク
00218         mLogFile->seekg( static_cast<int>( sizeof( ssmTimeT ) + mDataSize ) * diff, std::ios::cur );
00219         // シークに成功したかをチェック
00220         pos = mLogFile->tellg( );
00221         if( pos < mStartPos || pos > mEndPos )
00222         {
00223             // シーク失敗なら終了
00224             mLogFile->seekg( curPos );
00225             return false;
00226         }
00227         return true;
00228     }
00229     
00230     // @brief 時間指定読み込み
00231     //        指定した時間より前で最も近いデータを読み込む
00232     bool readTime( ssmTimeT time )
00233     {
00234         std::ios::pos_type curPos = mLogFile->tellg();
00235         // cycleを使って予測ジャンプ
00236         seek( ( time - mTime ) / mCycle );
00237         // 現在位置を読み込み
00238         readNext() || readBack(); // 一番最後だと読み込めないので1つ戻って読み込む
00239         
00240         // 条件を満たすまで探索
00241         mLogFile->clear(  );
00242         while( mTime < time && readNext(  ) );
00243         mLogFile->clear(  );
00244         while( mTime >= time && readBack(  ) );
00245         
00246         return true;
00247     }
00248     
00249     const ssmTimeT &getStartTime( ) const
00250     {
00251         return mStartTime;
00252     }
00253 
00254     ssmTimeT &time(  )
00255     {
00256         return mTime;
00257     }
00258     void *data(  )
00259     {
00260         return mData;
00261     }
00262     size_t &dataSize(  )
00263     {
00264         return mDataSize;
00265     }
00266     
00267     void *property(  )
00268     {
00269         return mProperty;
00270     }
00271     size_t &propertySize()
00272     {
00273         return mPropertySize;
00274     }
00275     
00276     const char *getStreamName( ) const
00277     {
00278         return mStreamName.c_str();
00279     }
00280     
00281     const int &getStreamId(  ) const { return mStreamId; }
00282     
00283     const double &getCycle(  ) const { return mCycle; }
00284     
00285     const int &getBufferNum(  ) const { return mBufferNum; }
00286 
00287 };
00288 
00289 template < typename D, typename P = SSMDummy > class SSMLog : public SSMLogBase
00290 {
00291     void setBuffer(void *data, size_t dataSize, void *property, size_t propertySize );
00292     void initLog()
00293     {
00294         SSMLogBase::setBuffer( &dataBuf, sizeof( D ), &propertyBuf, sizeof( P ) );
00295     }
00296     D dataBuf;                                      // @brief SSM Data.
00297     P propertyBuf;                                  // @brief Property of SSM Data.
00298 public:
00299 
00300     SSMLog(  )
00301     {
00302         initLog();
00303     }
00304     
00305     virtual ~SSMLog(  ){}
00306     
00307     D &data(  )
00308     {
00309         return dataBuf;
00310     }
00311     
00312     P &property(  )
00313     {
00314         return propertyBuf;
00315     }
00316 };
00317 #endif // SSM_LOG_H__
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines