00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
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
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
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
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
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
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
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
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
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
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
00251 *( (Tint*)ptr ) = GetRecordSize();
00252 datasize += Tsizeof( Tint );
00253 ( (Tint*)ptr ) ++;
00254
00255
00256
00257 *( (Tobject_t*)ptr ) = theObjectType;
00258 datasize += Tsizeof( Tobject_t );
00259 ( (Tobject_t*)ptr ) ++;
00260
00261
00262
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
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
00457 *( (Tint*)p ) = GetRecordSize();
00458 ( (Tint*)p ) ++;
00459 datasize += Tsizeof( Tint );
00460
00461
00462
00463 *( (Tobject_t*)p ) = theObjectType;
00464 ( (Tobject_t*)p ) ++;
00465 datasize += Tsizeof( Tobject_t );
00466
00467
00468
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
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
00506
00507 ( (Tint*)p ) ++;
00508 datasize += Tsizeof( Tint );
00509
00510
00511
00512 theObjectType = *( (Tobject_t*)p );
00513 ( (Tobject_t*)p ) ++;
00514 datasize += Tsizeof( Tobject_t );
00515
00516
00517
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
00532 Tsize_t nentry = *( (Tsize_t*)p );
00533 ( (Tsize_t*)p ) ++;
00534 datasize += Tsizeof( Tsize_t );
00535
00536
00537
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