00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "TInputObjectSocket.hh"
00025 #include "TStreamableObject.hh"
00026 #include "TDataRecord.hh"
00027 #include "TDataSection.hh"
00028 #include "TDataSegment.hh"
00029 #include "TDataElement.hh"
00030 #include "TInputObjectFilter.hh"
00031
00032 TInputObjectSocket::TInputObjectSocket( Tint port )
00033 : TObjectSocket( port ), TInputObjectStream( tSocketStream ),
00034 theClientDescriptor( -1 )
00035 {
00036 initialize();
00037 OpenServer();
00038 OpenClient();
00039 }
00040
00041 TInputObjectSocket::TInputObjectSocket( TInputObjectFilter* filter, Tint port )
00042 : TObjectSocket( port ), TInputObjectStream( filter, tSocketStream ),
00043 theClientDescriptor( -1 )
00044 {
00045 initialize();
00046 OpenServer();
00047 OpenClient();
00048 }
00049
00050 TInputObjectSocket::~TInputObjectSocket()
00051 {
00052 CloseClient();
00053 CloseServer();
00054 }
00055
00056 Tint TInputObjectSocket::Read( TStreamableObject& object )
00057 {
00058 if ( HasFilter() ) {
00059 return theObjectFilter -> Filtering( object, this );
00060 }
00061
00062
00063 theLastDataSize = theDataSize;
00064 theDataSize = 0;
00065
00066 static Tobject_t objecttype = object.GetObjectType();
00067
00068 switch ( objecttype ) {
00069 case tObjectDataRecord:
00070 *( (TDataRecord*)(&object) ) = getDataRecord();
00071 break;
00072 case tObjectDataSection:
00073 *( (TDataSection*)(&object) ) = getDataSection();
00074 break;
00075 case tObjectDataSegment:
00076 *( (TDataSegment*)(&object) ) = getDataSegment();
00077 break;
00078 case tObjectDataElement:
00079 *( (TDataElement*)(&object) ) = getDataElement();
00080 break;
00081 default:
00082 break;
00083 }
00084
00085 theTotalDataSize += theDataSize;
00086 return theDataSize;
00087 }
00088
00089 TDataRecord TInputObjectSocket::getDataRecord()
00090 {
00091 Tint recsize;
00092 Tobject_t type;
00093 Tstring id;
00094 Tsize_t entries;
00095 readProperties( recsize, type, id, entries );
00096
00097 TDataRecord record( id );
00098 record.SetObjectType( type );
00099 if ( theDataSize == 0 ) {
00100 return record;
00101 }
00102
00103 for ( Tsize_t i = 0; i < entries; i ++ ) {
00104 record.push_back( getDataSection() );
00105 }
00106
00107 return record;
00108 }
00109
00110 TDataSection TInputObjectSocket::getDataSection()
00111 {
00112 Tint recsize;
00113 Tobject_t type;
00114 Tstring id;
00115 Tsize_t entries;
00116 readProperties( recsize, type, id, entries );
00117
00118 TDataSection section( id );
00119 section.SetObjectType( type );
00120 if ( theDataSize == 0 ) {
00121 return section;
00122 }
00123
00124 for ( Tsize_t i = 0; i < entries; i ++ ) {
00125 section.push_back( getDataSegment() );
00126 }
00127
00128 return section;
00129 }
00130
00131 TDataSegment TInputObjectSocket::getDataSegment()
00132 {
00133 Tint recsize;
00134 Tobject_t type;
00135 Tstring id;
00136 Tsize_t entries;
00137 readProperties( recsize, type, id, entries );
00138
00139 TDataSegment segment( id );
00140 segment.SetObjectType( type );
00141 if ( theDataSize == 0 )
00142 return segment;
00143
00144 for ( Tsize_t i = 0; i < entries; i ++ )
00145 segment.push_back( getDataElement() );
00146
00147 return segment;
00148 }
00149
00150 TDataElement TInputObjectSocket::getDataElement()
00151 {
00152 static const Tstring head = "TInputObjectSocket::getDataElement";
00153 Tint recsize;
00154 Tobject_t otype;
00155 Tstring id;
00156 Telement_t etype;
00157 Tint nprvs;
00158 TDataElement element;
00159
00160
00161
00162 if ( recv( theClientDescriptor, &recsize, Tsizeof( Tint ), 0 ) != (Tint)Tsizeof( Tint ) ) {
00163 theDataSize = 0;
00164 perror( head.c_str() );
00165 return element;
00166 } else {
00167 theDataSize += Tsizeof( Tint );
00168 }
00169
00170
00171
00172 if ( recv( theClientDescriptor, &otype, Tsizeof( Tobject_t ), 0 ) != (Tint)Tsizeof( Tobject_t ) ) {
00173 theDataSize = 0;
00174 perror( head.c_str() );
00175 return element;
00176 } else {
00177 theDataSize += Tsizeof( Tobject_t );
00178 element.SetObjectType( otype );
00179 }
00180
00181
00182 Tsize_t nchar;
00183 Tchar* charbuf = 0;
00184 if ( recv( theClientDescriptor, &nchar, Tsizeof( Tsize_t ), 0 ) != (Tint)Tsizeof( Tsize_t ) ) {
00185 theDataSize = 0;
00186 perror( head.c_str() );
00187 return element;
00188 } else {
00189 theDataSize += Tsizeof( Tsize_t );
00190 charbuf = new Tchar[ nchar ];
00191 }
00192 for ( Tsize_t i = 0; i < nchar; i ++ ) {
00193 if ( recv( theClientDescriptor, &charbuf[ i ], Tsizeof( Tchar ), 0 ) != (Tint)Tsizeof( Tchar ) ) {
00194 theDataSize = 0;
00195 perror( head.c_str() );
00196 delete [] charbuf;
00197 return element;
00198 } else {
00199 theDataSize += Tsizeof( Tchar );
00200 }
00201 }
00202 id = charbuf;
00203 delete [] charbuf;
00204 element.SetID( id );
00205
00206
00207
00208
00209 if ( recv( theClientDescriptor, &etype, Tsizeof( Telement_t ), 0 ) != Tsizeof( Telement_t ) ) {
00210 theDataSize = 0;
00211 perror( head.c_str() );
00212 return element;
00213 } else {
00214 theDataSize += Tsizeof( Telement_t );
00215 element.SetElementType( etype );
00216 }
00217
00218
00219
00220
00221 if ( recv( theClientDescriptor, &nprvs, Tsizeof( Tint ), 0 ) != Tsizeof( Tint ) ) {
00222 theDataSize = 0;
00223 perror( head.c_str() );
00224 return element;
00225 } else {
00226 theDataSize += Tsizeof( Tint );
00227 element.SetNumberOfPrimitives( nprvs );
00228 }
00229
00230
00231 Tstring* strbuf = 0;
00232 Tchar* cc = 0;
00233 Tint* ii = 0;
00234 TUint* ui = 0;
00235 Tdouble* dd = 0;
00236 TUshort* us = 0;
00237 Tshort* ss = 0;
00238 Tfloat* ff = 0;
00239 Tlong* ll = 0;
00240 TUlong* ul = 0;
00241 Tsize_t rsize;
00242
00243 switch ( etype ) {
00244
00245 case tTypeInt:
00246 ii = new Tint[ nprvs ];
00247 rsize = Tsizeof( Tint );
00248 for ( Tint i = 0; i < nprvs; i ++ ) {
00249 if ( recv( theClientDescriptor, &ii[ i ], rsize, 0 ) != (Tint)rsize ) {
00250 theDataSize = 0;
00251 delete [] ii;
00252 return element;
00253 } else {
00254 theDataSize += (Tint)rsize;
00255 }
00256 }
00257 element.FillData( ii, nprvs );
00258 delete [] ii;
00259 break;
00260
00261
00262 case tTypeUnsignedInt:
00263 ui = new TUint[ nprvs ];
00264 rsize = Tsizeof( TUint );
00265 for ( Tint i = 0; i < nprvs; i ++ ) {
00266 if ( recv( theClientDescriptor, &ui[ i ], rsize, 0 ) != (Tint)rsize ) {
00267 theDataSize = 0;
00268 delete [] ui;
00269 return element;
00270 } else {
00271 theDataSize += (Tint)rsize;
00272 }
00273 }
00274 element.FillData( ui, nprvs );
00275 delete [] ui;
00276 break;
00277
00278
00279 case tTypeWord:
00280 case tTypeUnsignedShort:
00281 us = new TUshort[ nprvs ];
00282 rsize = Tsizeof( TUshort );
00283 for ( Tint i = 0; i < nprvs; i ++ ) {
00284 if ( recv( theClientDescriptor, &us[ i ], rsize, 0 ) != (Tint)rsize ) {
00285 theDataSize = 0;
00286 delete [] us;
00287 return element;
00288 } else {
00289 theDataSize += (Tint)rsize;
00290 }
00291 }
00292 element.FillData( us, nprvs );
00293 delete [] us;
00294 break;
00295
00296 case tTypeDouble:
00297 dd = new Tdouble[ nprvs ];
00298 rsize = Tsizeof( Tdouble );
00299 for ( Tint i = 0; i < nprvs; i ++ ) {
00300 if ( recv( theClientDescriptor, &dd[ i ], rsize, 0 ) != (Tint)rsize ) {
00301 theDataSize = 0;
00302 delete [] dd;
00303 return element;
00304 } else {
00305 theDataSize += (Tint)rsize;
00306 }
00307 }
00308 element.FillData( dd, nprvs );
00309 delete [] dd;
00310 break;
00311
00312 case tTypeFloat:
00313 ff = new Tfloat[ nprvs ];
00314 rsize = Tsizeof( Tfloat );
00315 for ( Tint i = 0; i < nprvs; i ++ ) {
00316 if ( recv( theClientDescriptor, &ff[ i ], rsize, 0 ) != (Tint)rsize ) {
00317 theDataSize = 0;
00318 delete [] ff;
00319 return element;
00320 } else {
00321 theDataSize += (Tint)rsize;
00322 }
00323 }
00324 element.FillData( ff, nprvs );
00325 delete [] ff;
00326 break;
00327
00328 case tTypeShort:
00329 ss = new Tshort[ nprvs ];
00330 rsize = Tsizeof( Tshort );
00331 for ( Tint i = 0; i < nprvs; i ++ ) {
00332 if ( recv( theClientDescriptor, &ss[ i ], rsize, 0 ) != (Tint)rsize ) {
00333 theDataSize = 0;
00334 delete [] ss;
00335 return element;
00336 } else {
00337 theDataSize += (Tint)rsize;
00338 }
00339 }
00340 element.FillData( ss, nprvs );
00341 delete [] ss;
00342 break;
00343
00344 case tTypeLong:
00345 ll = new Tlong[ nprvs ];
00346 rsize = Tsizeof( Tlong );
00347 for ( Tint i = 0; i < nprvs; i ++ ) {
00348 if ( recv( theClientDescriptor, &ll[ i ], rsize, 0 ) != (Tint)rsize ) {
00349 theDataSize = 0;
00350 delete [] ll;
00351 return element;
00352 } else {
00353 theDataSize += (Tint)rsize;
00354 }
00355 }
00356 element.FillData( ll, nprvs );
00357 delete [] ll;
00358 break;
00359
00360 case tTypeUnsignedLong:
00361 ul = new TUlong[ nprvs ];
00362 rsize = Tsizeof( TUlong );
00363 for ( Tint i = 0; i < nprvs; i ++ ) {
00364 if ( recv( theClientDescriptor, &ul[ i ], rsize, 0 ) != (Tint)rsize ) {
00365 theDataSize = 0;
00366 delete [] ul;
00367 return element;
00368 } else {
00369 theDataSize += (Tint)rsize;
00370 }
00371 }
00372 element.FillData( ul, nprvs );
00373 delete [] ul;
00374 break;
00375
00376 case tTypeString:
00377 strbuf = new Tstring[ nprvs ];
00378 for ( Tint i = 0; i < nprvs; i ++ ) {
00379 Tsize_t nchar;
00380 rsize = Tsizeof( Tsize_t );
00381 if ( recv( theClientDescriptor, &nchar, rsize, 0 ) != (Tint)rsize ) {
00382 theDataSize = 0;
00383 delete [] strbuf;
00384 return element;
00385 } else {
00386 theDataSize += (Tint)rsize;
00387 cc = new Tchar[ nchar ];
00388 }
00389 rsize = Tsizeof( Tchar );
00390 for ( Tsize_t j = 0; j < nchar; j ++ ) {
00391 if ( recv( theClientDescriptor, &cc[ j ], rsize, 0 ) != (Tint)rsize ) {
00392 theDataSize = 0;
00393 delete [] cc;
00394 delete [] strbuf;
00395 return element;
00396 } else {
00397 theDataSize += (Tint)rsize;
00398 }
00399 }
00400 strbuf[ i ] = cc;
00401 delete [] cc;
00402 }
00403 element.FillData( strbuf, nprvs );
00404 delete [] strbuf;
00405 break;
00406
00407 case tTypeUnknown:
00408 case tTypeObject:
00409 default:
00410 break;
00411 }
00412
00413 return element;
00414 }
00415
00416 Tint TInputObjectSocket::OpenClient()
00417 {
00418 Tsocklen_t server_len = (Tsocklen_t)Tsizeof( theAddress );
00419 if ( bind( theServerDescriptor, (struct sockaddr *)&theAddress, server_len ) == -1 ) {
00420 perror( "TInputObjectSocket::OpenClient" );
00421 exit( -errno );
00422 }
00423
00424 if ( listen( theServerDescriptor, tDefaultBackLog ) == -1 ) {
00425 perror( "TInputObjectSocket::OpenClient" );
00426 exit( -errno );
00427 }
00428
00429 struct sockaddr_in client_address;
00430 Tsocklen_t client_len;
00431 theClientDescriptor = accept( theServerDescriptor, (struct sockaddr *)&client_address, &client_len );
00432 if ( theClientDescriptor == -1 )
00433 perror( "TInputObjectSocket::OpenClient" );
00434 return theClientDescriptor;
00435 }
00436
00437 Tint TInputObjectSocket::CloseClient()
00438 {
00439 if ( shutdown( theClientDescriptor, 2 ) == -1 ) {
00440 perror( "TInputObjectSocket::CloseClient" );
00441 return -1;
00442 }
00443
00444 if ( close( theClientDescriptor ) == -1 ) {
00445 perror( "TInputObjectSocket::CloseClient" );
00446 return -1;
00447 }
00448 theClientDescriptor = -1;
00449 return 0;
00450 }
00451
00452 Tvoid TInputObjectSocket::readProperties( Tint& recsize, Tobject_t& type, Tstring& id, Tsize_t& entries )
00453 {
00454 static const Tstring head = "TInputObjectSocket::readProperties";
00455
00456
00457 if ( recv( theClientDescriptor, &recsize, Tsizeof( Tint ), 0 ) != (Tint)Tsizeof( Tint ) ) {
00458
00459 theDataSize = 0;
00460 return;
00461 } else {
00462 theDataSize += Tsizeof( Tint );
00463 }
00464
00465
00466
00467 if ( recv( theClientDescriptor, &type, Tsizeof( Tobject_t ), 0 ) != (Tint)Tsizeof( Tobject_t ) ) {
00468
00469 theDataSize = 0;
00470 return;
00471 } else {
00472 theDataSize += Tsizeof( Tobject_t );
00473 }
00474
00475
00476 Tsize_t nchar;
00477 Tchar* charbuf = 0;
00478 if ( recv( theClientDescriptor, &nchar, Tsizeof( Tsize_t ), 0 ) != (Tint)Tsizeof( Tsize_t ) ) {
00479
00480 theDataSize = 0;
00481 return;
00482 } else {
00483 theDataSize += Tsizeof( Tsize_t );
00484 charbuf = new Tchar[ nchar ];
00485 }
00486 for ( Tsize_t i = 0; i < nchar; i ++ ) {
00487 if ( recv( theClientDescriptor, &charbuf[ i ], Tsizeof( Tchar ), 0 ) != (Tint)Tsizeof( Tchar ) ) {
00488
00489 theDataSize = 0;
00490 delete [] charbuf;
00491 return;
00492 } else {
00493 theDataSize += Tsizeof( Tchar );
00494 }
00495 }
00496 id = charbuf;
00497 delete [] charbuf;
00498
00499
00500
00501 if ( recv( theClientDescriptor, &entries, Tsizeof( Tsize_t ), 0 ) != Tsizeof( Tsize_t ) ) {
00502
00503 theDataSize = 0;
00504 return;
00505 } else {
00506 theDataSize += Tsizeof( Tsize_t );
00507 }
00508
00509 return;
00510 }
00511
00512 Tvoid TInputObjectSocket::initialize()
00513 {
00514 theAddress.sin_family = PF_INET;
00515 theAddress.sin_port = htons( (TUshort)thePortNumber );
00516 theAddress.sin_addr.s_addr = htonl( INADDR_ANY );
00517
00518
00519 return;
00520 }
00521
00522 #ifdef __CLDAQ_ROOT_DLL
00523 ClassImp(TInputObjectSocket)
00524 #endif