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

TDataRecord.cc

解説を見る。
00001 // =====================================================================
00002 //  $Id: TDataRecord.cc,v 1.10 2004/03/07 10:30:30 goiwai Exp $
00003 //  $Name: CLDAQ-1-14-03 $
00004 //  $Log: TDataRecord.cc,v $
00005 //  Revision 1.10  2004/03/07 10:30:30  goiwai
00006 //  ROOTに組みこむためのおまじないマクロを埋めこみました。
00007 //  全てにおいて完全に動作するわけではありません。
00008 //
00009 //  Revision 1.9  2003/12/07 05:07:34  goiwai
00010 //  Test()が作るデータを4kBちょうどにしました.
00011 //
00012 //  Revision 1.8  2003/12/06 10:59:11  goiwai
00013 //  Serialize(Tvoid*) -> Serialize(const Tvoid*)に変更しました.
00014 //  Deserialize(const Tvoid*)を追加しました.
00015 //  手抜きの実装なので,バッファオーバーフローの可能性があります.
00016 //  Reallocate()とかするような仕組みが必要です.
00017 //
00018 //  Revision 1.7  2003/11/04 12:03:05  goiwai
00019 //  ==演算子と!=演算子を実装しました.具体的には
00020 //  if ( record == "String" ) {
00021 //    hoeghoge;
00022 //  }
00023 //  のような使い方が出来ます.単純に theID メンバとを比較して結果を返します.
00024 //
00025 //  Revision 1.6  2003/10/12 13:06:34  goiwai
00026 //  Update()を追加しました.
00027 //
00028 //  Revision 1.5  2003/10/06 16:42:08  goiwai
00029 //  テスト用の関数としてTest()を加えました.適当なデータレコードを発生しま
00030 //  す.
00031 //
00032 //  Revision 1.4  2003/08/25 09:19:37  goiwai
00033 //  operator[]( const Tstring& id ) を加えました.
00034 //  record[0] とか record["tag"] とかすれば,TDataSection を得ることが出来
00035 //  ます.
00036 //  size()を越えた範囲にも,チェックしないでアクセスします.
00037 //  マッチしなかった場合は落ちます.
00038 //  同じ名前でタグされた DataSection がある場合,最初にマッチしたものが返っ
00039 //  てきます.
00040 //
00041 //  Revision 1.3  2003/07/30 16:17:51  goiwai
00042 //  ファイルにコミットログをつけることにしました.
00043 //
00044 // =====================================================================
00045 #include "TDataRecord.hh"
00046 #include "TOutputObjectStream.hh"
00047 #include "TOutputObjectFile.hh"
00048 #include "TOutputObjectSocket.hh"
00049 #include "TOutputObjectSharedMemory.hh"
00050 #include "TSystemClock.hh"
00051 
00052 TDataRecord::TDataRecord( const Tstring& id )
00053   : TStreamableObject( tObjectDataRecord, id ), TDataSectionList()
00054 {;}
00055 
00056 TDataRecord::TDataRecord( const TDataRecord& right )
00057   : TStreamableObject( right ), TDataSectionList( right )
00058 {;}
00059 
00060 TDataRecord::~TDataRecord()
00061 {;}
00062 
00063 Tint TDataRecord::GetRecordSize()
00064 {
00065   Tsize_t nchar = theID.size() + 1;
00066   // record size + object type + object id + number of entries
00067   Tint total = Tsizeof( Tint ) + Tsizeof( Tobject_t ) + Tsizeof( Tsize_t ) + ( Tsizeof( Tchar ) * nchar ) + Tsizeof( Tsize_t );
00068 
00069   for ( Tsize_t i = 0; i < size(); i ++ ) {
00070     total += ( (*this)[ i ] ).GetRecordSize();
00071   }
00072   return total;
00073 }
00074 
00075 Tint TDataRecord::Record( TOutputObjectStream* output )
00076 {
00077   Tint datasize = 0;
00078   Tstream_t streamtype = output -> GetStreamType();
00079 
00080   switch ( streamtype ) {
00081     case tFileStream:
00082       datasize = record( (TOutputObjectFile*)output );
00083       break;
00084     case tSocketStream:
00085       datasize = record( (TOutputObjectSocket*)output );
00086       break;
00087     case tSharedMemoryStream:
00088       datasize = record( (TOutputObjectSharedMemory*)output );
00089       break;
00090     case tUnknownStream:
00091     default:
00092       Tcerr << "TDataRecord::Record: unknown stream type." << Tendl;
00093       return 0;
00094   }
00095 
00096   for ( Tsize_t i = 0; i < size(); i ++ ) {
00097     datasize += ( (*this)[ i ] ).Record( output );
00098   }
00099 
00100   return datasize;
00101 }
00102 
00103 Tostream& operator<<( Tostream& tos, const TDataRecord& right )
00104 {
00105   tos << "Data Record(" << right.theObjectType << "), "
00106       << "ID: " << right.theID
00107       << ", Capacity: " << right.capacity()
00108       << ", Entry: " << right.size();
00109 
00110   if ( right.empty() ) {
00111     return tos;
00112   }
00113 
00114   tos << Tendl;
00115 
00116   for ( Tsize_t i = 0; i < right.size(); i ++ ) {
00117     tos << Ttab << "[" << i << "] " << right[ i ];
00118     if ( i != right.size() - 1 ) {
00119       tos << Tendl;
00120     }
00121   }
00122 
00123   return tos;
00124 }
00125 
00126 Tint TDataRecord::record( TOutputObjectFile* ofile )
00127 {
00128   Tsize_t datasize = 0;
00129   static const Tsize_t nmemb = 1;
00130   Tsize_t ss = 0;
00131   static const Tstring head = "TDataRecord::record";
00132 
00133   // write object type
00134   Tint recsize = GetRecordSize();
00135   ss = fwrite( &recsize, Tsizeof( Tint ), nmemb, ofile -> GetFileStream() );
00136   if ( ss != nmemb ) {
00137     perror( head.c_str() );
00138   } else {
00139     datasize += ss * Tsizeof( Tint );
00140   }
00141 
00142 
00143   // write object type
00144   ss = fwrite( &theObjectType, Tsizeof( Tobject_t ), nmemb, ofile -> GetFileStream() );
00145   if ( ss != nmemb ) {
00146     perror( head.c_str() );
00147   } else {
00148     datasize += ss * Tsizeof( Tobject_t );
00149   }
00150 
00151 
00152   // write object ID
00153   Tchar charbuf;
00154   Tsize_t nchar = theID.size() + 1;
00155   ss = fwrite( &nchar, Tsizeof( Tsize_t ), nmemb, ofile -> GetFileStream() );
00156   if ( ss != nmemb ) {
00157     perror( head.c_str() );
00158   } else {
00159     datasize += ss * Tsizeof( Tsize_t );
00160   }
00161   for ( Tsize_t i = 0; i < nchar; i ++ ) {
00162     if ( i == ( nchar - 1 ) ) {
00163       charbuf = '\0';
00164     } else {
00165       charbuf = theID[ i ];
00166     }
00167     ss = fwrite( &charbuf, Tsizeof( Tchar ), nmemb, ofile -> GetFileStream() );
00168     if ( ss != nmemb ) {
00169       perror( head.c_str() );
00170     } else {
00171       datasize += ss * Tsizeof( Tchar );
00172     }
00173   }
00174 
00175    
00176   // write number of entries
00177   Tsize_t entry = size();
00178   ss = fwrite( &entry, Tsizeof( Tsize_t ), nmemb, ofile -> GetFileStream() );
00179   if ( ss != nmemb ) {
00180     perror( head.c_str() );
00181   } else {
00182     datasize += ss * Tsizeof( Tsize_t );
00183   }
00184 
00185   return (Tint)datasize;
00186 }
00187 
00188 Tint TDataRecord::record( TOutputObjectSocket* osocket )
00189 {
00190   Tsize_t datasize = 0;
00191   static const Tstring head = "TDataRecord::record";
00192 
00193   // send record size
00194   Tint recsize = GetRecordSize();
00195   if ( send( osocket -> GetServerDescriptor(), &recsize, Tsizeof( Tint ), 0 ) != Tsizeof( Tint ) ) {
00196     perror( head.c_str() );
00197   } else {
00198     datasize += Tsizeof( Tint );
00199   }
00200 
00201 
00202   // send object type
00203   if ( send( osocket -> GetServerDescriptor(), &theObjectType, Tsizeof( Tobject_t ), 0 ) != Tsizeof( Tobject_t ) ) {
00204     perror( head.c_str() );
00205   } else {
00206     datasize += Tsizeof( Tobject_t );
00207   }
00208 
00209 
00210   // send object ID
00211   Tchar charbuf;
00212   Tsize_t nchar = theID.size() + 1;
00213   if ( send( osocket -> GetServerDescriptor(), &nchar, Tsizeof( Tsize_t ), 0 ) != Tsizeof( Tsize_t ) ) {
00214     perror( head.c_str() );
00215   } else {
00216     datasize += Tsizeof( Tsize_t );
00217   }
00218   for ( Tsize_t i = 0; i < nchar; i ++ ) {
00219     if ( i == ( nchar - 1 ) ) {
00220       charbuf = '\0';
00221     } else {
00222       charbuf = theID[ i ];
00223     }
00224     if ( send( osocket -> GetServerDescriptor(), &charbuf, Tsizeof( Tchar ), 0 ) != Tsizeof( Tchar ) ) {
00225       perror( head.c_str() );
00226     } else {
00227       datasize += Tsizeof( Tchar );
00228     }
00229   }
00230 
00231 
00232   // send number of entries
00233   Tsize_t entry = size();
00234   if ( send( osocket -> GetServerDescriptor(), &entry, Tsizeof( Tsize_t ), 0 ) != Tsizeof( Tsize_t ) ) {
00235     perror( head.c_str() );
00236   } else {
00237     datasize += Tsizeof( Tsize_t );
00238   }
00239 
00240 
00241   return (Tint)datasize;
00242 }
00243 
00244 Tint TDataRecord::record( TOutputObjectSharedMemory* omemory )
00245 {
00246   Tsize_t datasize = 0;
00247   Tvoid* ptr = omemory -> GetAddress();
00248 
00249 
00250   // write record size
00251   *( (Tint*)ptr ) = GetRecordSize();
00252   datasize += Tsizeof( Tint );
00253   ( (Tint*)ptr ) ++;
00254 
00255 
00256   // write object type
00257   *( (Tobject_t*)ptr ) = theObjectType;
00258   datasize += Tsizeof( Tobject_t );
00259   ( (Tobject_t*)ptr ) ++;
00260 
00261 
00262   // write object ID
00263   Tchar charbuf;
00264   Tsize_t nchar = theID.size() + 1;
00265   *( (Tsize_t*)ptr ) = nchar;
00266   datasize += Tsizeof( Tsize_t );
00267   ( (Tsize_t*)ptr ) ++;
00268   for ( Tsize_t i = 0; i < nchar; i ++ ) {
00269     if ( i == ( nchar - 1 ) ) {
00270       charbuf = '\0';
00271     } else {
00272       charbuf = theID[ i ];
00273     }
00274     *( (Tchar*)ptr ) = charbuf;
00275     datasize += Tsizeof( Tchar );
00276     ( (Tchar*)ptr ) ++;
00277   }
00278 
00279 
00280   // write number of entries
00281   Tsize_t entry = size();
00282   *( (Tsize_t*)ptr ) = entry;
00283   datasize += Tsizeof( Tsize_t );
00284   ( (Tsize_t*)ptr ) ++;
00285 
00286 
00287   omemory -> SetAddress( ptr );
00288 
00289   return (Tint)datasize;
00290 }
00291 
00292 const TDataRecord& TDataRecord::operator=( const TDataRecord& right )
00293 {
00294   *( (TStreamableObject*)this ) = *( (TStreamableObject*)(&right) );
00295   *( (TDataSectionList*)this ) = *( (TDataSectionList*)(&right) );
00296   return *this;
00297 }
00298 
00299 Tbool TDataRecord::operator==( const TDataRecord& right ) const
00300 {
00301   Tbool retval = Ttrue;
00302   retval &= ( *((TStreamableObject*)this) == *((TStreamableObject*)(&right)) );
00303   retval &= ( *((TDataSectionList*)this ) == *((TDataSectionList*)(&right)) );
00304   return retval;
00305 }
00306 
00307 Tbool TDataRecord::operator!=( const TDataRecord& right ) const
00308 {
00309   Tbool retval = Tfalse;
00310   retval |= ( *((TStreamableObject*)this) != *((TStreamableObject*)(&right)) );
00311   retval |= ( *((TDataSectionList*)this) != *((TDataSectionList*)(&right)) );
00312   return retval;
00313 }
00314 
00315 Tbool TDataRecord::operator==( const Tstring& right ) const
00316 {
00317   if ( theID == right ) {
00318     return Ttrue;
00319   } else {
00320     return Tfalse;
00321   }
00322 }
00323 
00324 Tbool TDataRecord::operator!=( const Tstring& right ) const
00325 {
00326   if ( theID != right ) {
00327     return Ttrue;
00328   } else {
00329     return Tfalse;
00330   }
00331 }
00332 
00333 Tvoid TDataRecord::Clear()
00334 {
00335   theID = TunknownID;
00336   for ( Tsize_t i = 0; i < size(); i ++ )
00337     ( (*this)[ i ] ).Clear();
00338   clear();
00339   return;
00340 }
00341 
00342 Tbool TDataRecord::FindDataSection( const Tstring& id, TDataSection& section ) const
00343 {
00344   for ( Tsize_t i = 0; i < size(); i ++ ) {
00345     if ( ( (*this)[ i ] ).GetID() == id ) {
00346       section = (*this)[ i ];
00347       return Ttrue;
00348     }
00349   }
00350   return Tfalse;
00351 }
00352 
00353 Tint TDataRecord::FindDataSection( const Tstring& id ) const
00354 {
00355   Tint retval = -EFAULT;
00356   for ( Tsize_t i = 0; i < size(); i ++ ) {
00357     if ( ( (*this)[ i ] ).GetID() == id ) {
00358       retval = i;
00359       break;
00360     }
00361   }
00362   return retval;
00363 }
00364 
00365 Tbool TDataRecord::FindDataSegment( const Tstring& secid, const Tstring& segid, TDataSegment& segment ) const
00366 {
00367   TDataSection section;
00368   if ( FindDataSection( secid, section ) ) {
00369     return section.FindDataSegment( segid, segment );
00370   } else {
00371     return Tfalse;
00372   }
00373 }
00374 
00375 Tint TDataRecord::FindDataSegment( const Tstring& secid, const Tstring& segid ) const
00376 {
00377   Tint secpos = FindDataSection( secid );
00378   if ( secpos >= 0 ) {
00379     return ( (*this)[ secpos ] ).FindDataSegment( segid );
00380   } else {
00381     return secpos;
00382   }
00383 }
00384 
00385 Tbool TDataRecord::FindDataSegment( Tstring idset[ 2 ], TDataSegment& segment ) const
00386 {
00387   return FindDataSegment( idset[ 0 ], idset[ 1 ], segment );
00388 }
00389 
00390 Tint TDataRecord::FindDataSegment( Tstring idset[ 2 ] ) const
00391 {
00392   return FindDataSegment( idset[ 0 ], idset[ 1 ] );
00393 }
00394 
00395 Tbool TDataRecord::FindDataSegment( const TstringList& idset, TDataSegment& segment ) const
00396 {
00397   return FindDataSegment( idset[ 0 ], idset[ 1 ], segment );
00398 }
00399 
00400 Tint TDataRecord::FindDataSegment( const TstringList& idset ) const
00401 {
00402   return FindDataSegment( idset[ 0 ], idset[ 1 ] );
00403 }
00404 
00405 Tbool TDataRecord::FindDataElement( const Tstring& secid, const Tstring& segid, const Tstring& eleid, TDataElement& element ) const
00406 {
00407   TDataSection section;
00408   TDataSegment segment;
00409   if ( FindDataSection( secid, section ) && section.FindDataSegment( segid, segment ) ) {
00410     return segment.FindDataElement( eleid, element );
00411   } else {
00412     return Tfalse;
00413   }
00414 }
00415 
00416 Tint TDataRecord::FindDataElement( const Tstring& secid, const Tstring& segid, const Tstring& eleid ) const
00417 {
00418   Tint secpos = FindDataSection( secid );
00419   if ( secpos >= 0 ) {
00420     Tint segpos = ( (*this)[ secpos ] ).FindDataSegment( segid );
00421     if ( segpos >= 0 ) {
00422       return ( ( (*this)[ secpos ] )[ segpos ] ).FindDataElement( eleid );
00423     } else {
00424       return segpos;
00425     }
00426   } else {
00427     return secpos;
00428   }
00429 }
00430 
00431 Tbool TDataRecord::FindDataElement( Tstring idset[ 3 ], TDataElement& element ) const
00432 {
00433   return FindDataElement( idset[ 0 ], idset[ 1 ], idset[ 2 ], element );
00434 }
00435 
00436 Tint TDataRecord::FindDataElement( Tstring idset[ 3 ] ) const
00437 {
00438   return FindDataElement( idset[ 0 ], idset[ 1 ], idset[ 2 ] );
00439 }
00440 
00441 Tbool TDataRecord::FindDataElement( const TstringList& idset, TDataElement& element ) const
00442 {
00443   return FindDataElement( idset[ 0 ], idset[ 1 ], idset[ 2 ], element );
00444 }
00445 
00446 Tint TDataRecord::FindDataElement( const TstringList& idset ) const
00447 {
00448   return FindDataElement( idset[ 0 ], idset[ 1 ], idset[ 2 ] );
00449 }
00450 
00451 Tint TDataRecord::Serialize( const Tvoid* buffer )
00452 {
00453   Tvoid* p = const_cast<Tvoid*>(buffer);
00454   Tsize_t datasize = 0;
00455 
00456   // write record size
00457   *( (Tint*)p ) = GetRecordSize();
00458   ( (Tint*)p ) ++;
00459   datasize += Tsizeof( Tint );
00460 
00461 
00462   // write object type
00463   *( (Tobject_t*)p ) = theObjectType;
00464   ( (Tobject_t*)p ) ++;
00465   datasize += Tsizeof( Tobject_t );
00466 
00467 
00468   // write object ID
00469   Tchar charbuf;
00470   Tsize_t nchar = theID.size() + 1;
00471   *( (Tsize_t*)p ) = nchar;
00472   ( (Tsize_t*)p ) ++;
00473   datasize += Tsizeof( Tsize_t );
00474   for ( Tsize_t i = 0; i < nchar; i ++ ) {
00475     if ( i == ( nchar - 1 ) ) {
00476       charbuf = '\0';
00477     } else {
00478       charbuf = theID[ i ];
00479     }
00480     *( (Tchar*)p ) = charbuf;
00481     ( (Tchar*)p ) ++;
00482     datasize += Tsizeof( Tchar );
00483   }
00484 
00485    
00486   // write number of entries
00487   *( (Tsize_t*)p ) = size();
00488   ( (Tsize_t*)p ) ++;
00489   datasize += Tsizeof( Tsize_t );
00490 
00491   for ( Tsize_t i = 0; i < size(); i ++ ) {
00492     Tint d = ( (*this)[ i ] ).Serialize( p );
00493     datasize += d;
00494     (Tbyte*)p += d;
00495   }
00496 
00497   return (Tint)datasize;
00498 }
00499 
00500 Tint TDataRecord::Deserialize( const Tvoid* buffer )
00501 {
00502   Tvoid* p = const_cast<Tvoid*>(buffer);  
00503   Tsize_t datasize = 0;
00504 
00505   // read record size
00506   //SetRecordSize( *( (Tint*)p ) );
00507   ( (Tint*)p ) ++;
00508   datasize += Tsizeof( Tint );
00509 
00510 
00511   // read object type
00512   theObjectType = *( (Tobject_t*)p );
00513   ( (Tobject_t*)p ) ++;
00514   datasize += Tsizeof( Tobject_t );
00515 
00516 
00517   // read object ID
00518   Tsize_t nchar = *( (Tsize_t*)p );
00519   ( (Tsize_t*)p ) ++;
00520   datasize += Tsizeof( Tsize_t );
00521 
00522   Tchar* cc = new Tchar[ nchar ];
00523   for ( Tsize_t i = 0; i < nchar; i ++ ) {
00524     cc[i] = *( (Tchar*)p );
00525     datasize += Tsizeof( Tchar );
00526     ( (Tchar*)p ) ++;
00527   }
00528   theID = cc;
00529   delete [] cc;
00530 
00531   // read number of entries
00532   Tsize_t nentry = *( (Tsize_t*)p );
00533   ( (Tsize_t*)p ) ++;
00534   datasize += Tsizeof( Tsize_t );
00535 
00536 
00537   // push datasection
00538   for ( Tsize_t i = 0; i < nentry; i ++ ) {
00539     TDataSection section;
00540     Tint d = section.Deserialize( p );
00541     push_back( section );
00542     datasize += d;
00543     (Tbyte*)p += d;
00544   }
00545 
00546   return (Tint)datasize;
00547 }
00548 
00549 const TDataSection& TDataRecord::operator[]( Tint n ) const
00550 {
00551   return *( begin() + n );
00552 }
00553 
00554 TDataSection& TDataRecord::operator[]( Tint n )
00555 {
00556   return *( begin() + n );
00557 }
00558 
00559 const TDataSection& TDataRecord::operator[]( const Tstring& id ) const
00560 {
00561   return (*this)[ FindDataSection( id ) ];
00562 }
00563 
00564 TDataSection& TDataRecord::operator[]( const Tstring& id )
00565 {
00566   return (*this)[ FindDataSection( id ) ];
00567 }
00568 
00569 TDataRecord TDataRecord::Test( Tint somevalue )
00570 {
00571   TDataRecord record( "This is a Data Record." );
00572   TDataSection section( "This is Data Section." );
00573   TDataSegment segment0( "This is a Data Segement identified 0." );
00574   TDataSegment segment1( "This is a Data Segement identified 1." );
00575   TDataSegment segment2( "This is a Data Segement identified 2." );
00576 
00577 
00578   TSystemClock clock;
00579   Tint pasttime = clock.GetTime();
00580   Tstring tstr = clock.WhatTimeIsItNow();
00581 
00582   const Tint nstrdata = 8;
00583   Tstring strdata[ nstrdata ] = { 
00584     "ABCDEF GHIJK LMN OPQR STU VWXYZ END", 
00585     "abcefghijklmnopqrstuvwxyz abcefghijklmnopqrstuvwxyz end",
00586     "ABCDEF GHIJK LMN OPQR STU VWXYZ END", 
00587     "abcefghijklmnopqrstuvwxyz abcefghijklmnopqrstuvwxyz end",
00588     "ABCDEFABCDEFABCDEFABCDEFABCDEFABCDEF",
00589     "GHIJKGHIJKGHIJK GHIJKGHIJKGHIJK",
00590     "LMNOPQRLMNOPQRLMNOPQR",
00591     "STU VWXYZ STU VWXYZ STU VWXYZ"
00592   };
00593   const Tint ndata = 0x500;
00594   TUshort array[ ndata ];
00595   for ( TUshort i = 0; i < ndata; i ++ ) {
00596     array[ i ] = i + i;
00597   }
00598   segment0.push_back( TDataElement( &pasttime, tTypeInt, "This is a integer data(TIME).", 1 ) );
00599   segment0.push_back( TDataElement( &tstr, tTypeString, "This is a string data(TIME).", 1 ) );
00600   segment0.push_back( TDataElement( strdata, tTypeString, "This is a string array.", nstrdata ) );
00601   segment0.push_back( TDataElement( array, tTypeUnsignedShort, "This is unsigned short data array.", ndata ) );
00602   for ( Tint i = 0; i < 8; i ++ ) {
00603     Tint data = i + i * i + 0x1234 * somevalue;
00604     segment1.push_back( TDataElement( &data, tTypeInt, itostr( i ) ) );
00605   }
00606   for ( Tdouble i = 0.0; i < 16.0; i ++ ) {
00607     Tdouble data = sin( i ) / exp( i );
00608     segment2.push_back( TDataElement( &data, tTypeDouble, dtostr( i ) ) );
00609   }
00610   section.push_back( segment0 );
00611   section.push_back( segment1 );
00612   section.push_back( segment2 );
00613   record.push_back( section );
00614 
00615   *this = record;
00616 
00617   return *this;
00618 }
00619 
00620 #ifdef __CLDAQ_ROOT_DLL
00621     ClassImp(TDataRecord)
00622 #endif


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