enhanced HOMER reader to work on normal buffer
[u/mrichter/AliRoot.git] / HLT / BASE / HOMER / AliHLTHOMERReader.cxx
CommitLineData
2be16a33 1/************************************************************************
2**
3**
4** This file is property of and copyright by the Technical Computer
5** Science Group, Kirchhoff Institute for Physics, Ruprecht-Karls-
6** University, Heidelberg, Germany, 2001
7** This file has been written by Timm Morten Steinbeck,
8** timm@kip.uni-heidelberg.de
9**
10**
11** See the file license.txt for details regarding usage, modification,
12** distribution and warranty.
13** Important: This file is provided without any warranty, including
14** fitness for any particular purpose.
15**
16**
17** Newer versions of this file's package will be made available from
18** http://web.kip.uni-heidelberg.de/Hardwinf/L3/
19** or the corresponding page of the Heidelberg Alice Level 3 group.
20**
21*************************************************************************/
22
23/*
24***************************************************************************
25**
26** $Author$ - Initial Version by Timm Morten Steinbeck
27**
28** $Id$
29**
30***************************************************************************
31*/
32
9e91e956 33/** @file AliHLTHOMERReader.cxx
2be16a33 34 @author Timm Steinbeck
35 @date Sep 14 2007
36 @brief HLT Online Monitoring Environment including ROOT - Reader
37 @note migrated from PubSub HLT-stable-20070905.141318 (rev 2375) */
38
04a939f7 39// see header file for class documentation
2be16a33 40// or
41// refer to README to build package
42// or
43// visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
44
45#include "AliHLTHOMERReader.h"
46#include <stdio.h>
47#include <string.h>
48#include <errno.h>
49#include <netdb.h>
50extern int h_errno;
51#include <sys/types.h>
52#include <sys/socket.h>
53#include <netinet/in.h>
54#include <netinet/tcp.h>
55#include <unistd.h>
56#include <rpc/types.h>
57#include <fcntl.h>
58#include <sys/stat.h>
59#include <netinet/in.h>
60#include <arpa/inet.h>
61#ifdef USE_ROOT
62#include <Rtypes.h>
63#endif
64
65
66#define MOD_BIN "MOD BIN\n"
67#define MOD_ASC "MOD ASC\n"
68#define GET_ONE "GET ONE\n"
69#define GET_ALL "GET ALL\n"
70
71#ifdef USE_ROOT
fe1edbae 72ClassImp(AliHLTMonitoringReader);
73ClassImp(AliHLTHOMERReader);
2be16a33 74#endif
75
76
77
78
79
80#ifdef USE_ROOT
fe1edbae 81AliHLTHOMERReader::AliHLTHOMERReader()
746d2a94 82 :
83 fCurrentEventType(~(homer_uint64)0),
84 fCurrentEventID(~(homer_uint64)0),
85 fBlockCnt(0),
86 fMaxBlockCnt(0),
87 fBlocks(NULL),
88 fDataSourceCnt(0),
89 fTCPDataSourceCnt(0),
90 fShmDataSourceCnt(0),
91 fDataSourceMaxCnt(0),
04a939f7 92 fDataSources(NULL),
93 fConnectionStatus(0),
94 fErrorConnection(~(unsigned int)0),
95 fEventRequestAdvanceTime(0)
2be16a33 96 {
1d47dbac 97// Reader implementation of the HOMER interface.
98// The HLT Monitoring Environment including ROOT is
99// a native interface to ship out data from the HLT chain.
100// See pdf document shiped with the package
101// for class documentation and tutorial.
2be16a33 102 Init();
103 }
104#endif
105
106
fe1edbae 107AliHLTHOMERReader::AliHLTHOMERReader( const char* hostname, unsigned short port )
746d2a94 108 :
fe1edbae 109 AliHLTMonitoringReader(),
746d2a94 110 fCurrentEventType(~(homer_uint64)0),
111 fCurrentEventID(~(homer_uint64)0),
112 fBlockCnt(0),
113 fMaxBlockCnt(0),
114 fBlocks(NULL),
115 fDataSourceCnt(0),
116 fTCPDataSourceCnt(0),
117 fShmDataSourceCnt(0),
118 fDataSourceMaxCnt(0),
04a939f7 119 fDataSources(NULL),
120 fConnectionStatus(0),
121 fErrorConnection(~(unsigned int)0),
122 fEventRequestAdvanceTime(0)
2be16a33 123 {
04a939f7 124// see header file for class documentation
125// For reading from a TCP port
2be16a33 126 Init();
127 if ( !AllocDataSources(1) )
128 {
129 fErrorConnection = 0;
130 fConnectionStatus = ENOMEM;
131 return;
132 }
133 fConnectionStatus = AddDataSource( hostname, port, fDataSources[0] );
134 if ( fConnectionStatus )
135 fErrorConnection = 0;
136 else
137 {
138 fDataSourceCnt++;
139 fTCPDataSourceCnt++;
140 fDataSources[0].fNdx = 0;
141 }
142 }
143
fe1edbae 144AliHLTHOMERReader::AliHLTHOMERReader( unsigned int tcpCnt, const char** hostnames, unsigned short* ports )
746d2a94 145 :
fe1edbae 146 AliHLTMonitoringReader(),
746d2a94 147 fCurrentEventType(~(homer_uint64)0),
148 fCurrentEventID(~(homer_uint64)0),
149 fBlockCnt(0),
150 fMaxBlockCnt(0),
151 fBlocks(NULL),
152 fDataSourceCnt(0),
153 fTCPDataSourceCnt(0),
154 fShmDataSourceCnt(0),
155 fDataSourceMaxCnt(0),
04a939f7 156 fDataSources(NULL),
157 fConnectionStatus(0),
158 fErrorConnection(~(unsigned int)0),
159 fEventRequestAdvanceTime(0)
2be16a33 160 {
04a939f7 161// see header file for class documentation
162// For reading from multiple TCP ports
2be16a33 163 Init();
164 if ( !AllocDataSources(tcpCnt) )
165 {
166 fErrorConnection = 0;
167 fConnectionStatus = ENOMEM;
168 return;
169 }
170 for ( unsigned int n = 0; n < tcpCnt; n++, fDataSourceCnt++, fTCPDataSourceCnt++ )
171 {
172 fConnectionStatus = AddDataSource( hostnames[n], ports[n], fDataSources[n] );
173 if ( fConnectionStatus )
174 {
175 fErrorConnection = n;
176 return;
177 }
178 fDataSources[n].fNdx = n;
179 }
180 }
181
fe1edbae 182AliHLTHOMERReader::AliHLTHOMERReader( key_t shmKey, int shmSize )
746d2a94 183 :
fe1edbae 184 AliHLTMonitoringReader(),
746d2a94 185 fCurrentEventType(~(homer_uint64)0),
186 fCurrentEventID(~(homer_uint64)0),
187 fBlockCnt(0),
188 fMaxBlockCnt(0),
189 fBlocks(NULL),
190 fDataSourceCnt(0),
191 fTCPDataSourceCnt(0),
192 fShmDataSourceCnt(0),
193 fDataSourceMaxCnt(0),
04a939f7 194 fDataSources(NULL),
195 fConnectionStatus(0),
196 fErrorConnection(~(unsigned int)0),
197 fEventRequestAdvanceTime(0)
2be16a33 198 {
04a939f7 199// see header file for class documentation
200// For reading from a System V shared memory segment
2be16a33 201 Init();
202 if ( !AllocDataSources(1) )
203 {
204 fErrorConnection = 0;
205 fConnectionStatus = ENOMEM;
206 return;
207 }
208 fConnectionStatus = AddDataSource( shmKey, shmSize, fDataSources[0] );
209 if ( fConnectionStatus )
210 fErrorConnection = 0;
211 else
212 {
213 fDataSourceCnt++;
214 fShmDataSourceCnt++;
215 fDataSources[0].fNdx = 0;
216 }
217 }
218
fe1edbae 219AliHLTHOMERReader::AliHLTHOMERReader( unsigned int shmCnt, key_t* shmKeys, int* shmSizes )
746d2a94 220 :
fe1edbae 221 AliHLTMonitoringReader(),
746d2a94 222 fCurrentEventType(~(homer_uint64)0),
223 fCurrentEventID(~(homer_uint64)0),
224 fBlockCnt(0),
225 fMaxBlockCnt(0),
226 fBlocks(NULL),
227 fDataSourceCnt(0),
228 fTCPDataSourceCnt(0),
229 fShmDataSourceCnt(0),
230 fDataSourceMaxCnt(0),
04a939f7 231 fDataSources(NULL),
232 fConnectionStatus(0),
233 fErrorConnection(~(unsigned int)0),
234 fEventRequestAdvanceTime(0)
2be16a33 235 {
04a939f7 236// see header file for class documentation
237// For reading from multiple System V shared memory segments
2be16a33 238 Init();
239 if ( !AllocDataSources(shmCnt) )
240 {
241 fErrorConnection = 0;
242 fConnectionStatus = ENOMEM;
243 return;
244 }
245 for ( unsigned int n = 0; n < shmCnt; n++, fDataSourceCnt++, fShmDataSourceCnt++ )
246 {
247 fConnectionStatus = AddDataSource( shmKeys[n], shmSizes[n], fDataSources[n] );
248 if ( fConnectionStatus )
249 {
250 fErrorConnection = n;
251 return;
252 }
253 fDataSources[n].fNdx = n;
254 }
255 }
256
fe1edbae 257AliHLTHOMERReader::AliHLTHOMERReader( unsigned int tcpCnt, const char** hostnames, unsigned short* ports,
2be16a33 258 unsigned int shmCnt, key_t* shmKeys, int* shmSizes )
746d2a94 259 :
fe1edbae 260 AliHLTMonitoringReader(),
746d2a94 261 fCurrentEventType(~(homer_uint64)0),
262 fCurrentEventID(~(homer_uint64)0),
263 fBlockCnt(0),
264 fMaxBlockCnt(0),
265 fBlocks(NULL),
266 fDataSourceCnt(0),
267 fTCPDataSourceCnt(0),
268 fShmDataSourceCnt(0),
269 fDataSourceMaxCnt(0),
04a939f7 270 fDataSources(NULL),
271 fConnectionStatus(0),
272 fErrorConnection(~(unsigned int)0),
273 fEventRequestAdvanceTime(0)
2be16a33 274 {
04a939f7 275// see header file for class documentation
276// For reading from multiple TCP ports and multiple System V shared memory segments
2be16a33 277 Init();
278 if ( !AllocDataSources(tcpCnt+shmCnt) )
279 {
280 fErrorConnection = 0;
281 fConnectionStatus = ENOMEM;
282 return;
283 }
284 for ( unsigned int n = 0; n < tcpCnt; n++, fDataSourceCnt++, fTCPDataSourceCnt++ )
285 {
286 fConnectionStatus = AddDataSource( hostnames[n], ports[n], fDataSources[n] );
287 if ( fConnectionStatus )
288 {
289 fErrorConnection = n;
290 return;
291 }
292 fDataSources[n].fNdx = n;
293 }
294 for ( unsigned int n = 0; n < shmCnt; n++, fDataSourceCnt++, fShmDataSourceCnt++ )
295 {
296 fConnectionStatus = AddDataSource( shmKeys[n], shmSizes[n], fDataSources[tcpCnt+n] );
297 if ( fConnectionStatus )
298 {
299 fErrorConnection = tcpCnt+n;
300 return;
301 }
302 fDataSources[n].fNdx = n;
303 }
304 }
8c617325 305
306AliHLTHOMERReader::AliHLTHOMERReader( const void* pBuffer, int size )
307 :
308 AliHLTMonitoringReader(),
309 fCurrentEventType(~(homer_uint64)0),
310 fCurrentEventID(~(homer_uint64)0),
311 fBlockCnt(0),
312 fMaxBlockCnt(0),
313 fBlocks(NULL),
314 fDataSourceCnt(0),
315 fTCPDataSourceCnt(0),
316 fShmDataSourceCnt(0),
317 fDataSourceMaxCnt(0),
318 fDataSources(NULL),
319 fConnectionStatus(0),
320 fErrorConnection(~(unsigned int)0),
321 fEventRequestAdvanceTime(0)
322 {
323// see header file for class documentation
324// For reading from a System V shared memory segment
325 Init();
326 if ( !AllocDataSources(1) )
327 {
328 fErrorConnection = 0;
329 fConnectionStatus = ENOMEM;
330 return;
331 }
332 //fConnectionStatus = AddDataSource( shmKey, shmSize, fDataSources[0] );
333 if ( fConnectionStatus )
334 fErrorConnection = 0;
335 else
336 {
337 fDataSourceCnt++;
338 fShmDataSourceCnt++;
339 fDataSources[0].fNdx = 0;
340 }
341 }
342
fe1edbae 343AliHLTHOMERReader::~AliHLTHOMERReader()
2be16a33 344 {
04a939f7 345// see header file for class documentation
2be16a33 346 ReleaseCurrentEvent();
347 FreeDataSources();
348 }
349
fe1edbae 350int AliHLTHOMERReader::ReadNextEvent()
2be16a33 351 {
04a939f7 352// see header file for class documentation
353// Read in the next available event
2be16a33 354 return ReadNextEvent( false, 0 );
355 }
356
fe1edbae 357int AliHLTHOMERReader::ReadNextEvent( unsigned long timeout )
2be16a33 358 {
04a939f7 359// see header file for class documentation
360// Read in the next available event
2be16a33 361 return ReadNextEvent( true, timeout );
362 }
363
fe1edbae 364unsigned long AliHLTHOMERReader::GetBlockDataLength( unsigned long ndx ) const
2be16a33 365 {
04a939f7 366// see header file for class documentation
367// Return the size (in bytes) of the current event's data
368// block with the given block index (starting at 0).
2be16a33 369 if ( ndx >= fBlockCnt )
370 return 0;
371 return fBlocks[ndx].fLength;
372 }
373
fe1edbae 374const void* AliHLTHOMERReader::GetBlockData( unsigned long ndx ) const
2be16a33 375 {
04a939f7 376// see header file for class documentation
377// Return a pointer to the start of the current event's data
378// block with the given block index (starting at 0).
2be16a33 379 if ( ndx >= fBlockCnt )
380 return NULL;
381 return fBlocks[ndx].fData;
382 }
383
fe1edbae 384const char* AliHLTHOMERReader::GetBlockSendNodeID( unsigned long ndx ) const
2be16a33 385 {
04a939f7 386// see header file for class documentation
387// Return IP address or hostname of node which sent the
388// current event's data block with the given block index
389// (starting at 0).
390// For HOMER this is the ID of the node on which the subscriber
391// that provided this data runs/ran.
2be16a33 392 if ( ndx >= fBlockCnt )
393 return NULL;
394#ifdef DEBUG
395 if ( fBlocks[ndx].fSource >= fDataSourceCnt )
396 {
397 fprintf( stderr, "%s:%d: Internal Error: fBlocks[ndx].fSource (%lu) >= fDataSourceCnt (%lu)\n",
398 __FILE__, __LINE__, fBlocks[ndx].fSource, fDataSourceCnt );
399 return NULL;
400 }
401#endif
402 return fDataSources[ fBlocks[ndx].fSource ].fHostname;
403 //return fBlocks[ndx].fOriginatingNodeID;
404 }
405
fe1edbae 406homer_uint8 AliHLTHOMERReader::GetBlockByteOrder( unsigned long ndx ) const
2be16a33 407 {
04a939f7 408// see header file for class documentation
409// Return byte order of the data stored in the
410// current event's data block with the given block index (starting at 0).
411// 0 is unknown alignment,
412// 1 ist little endian,
413// 2 is big endian. */
2be16a33 414 if ( ndx >= fBlockCnt )
415 return 0;
416 //return ((AliHLTRIBlockDescriptorV1*)fBlocks[ndx].fMetaData)->fType.fID;
417 return *(((homer_uint8*)fBlocks[ndx].fMetaData)+kByteOrderAttribute_8b_Offset);
418 }
04a939f7 419
fe1edbae 420homer_uint8 AliHLTHOMERReader::GetBlockTypeAlignment( unsigned long ndx, homer_uint8 dataType ) const
2be16a33 421 {
04a939f7 422// see header file for class documentation
423// Return the alignment (in bytes) of the given datatype
424// in the data stored in the current event's data block
425// with the given block index (starting at 0).
426// Possible values for the data type are
427// 0: homer_uint64
428// 1: homer_uint32
429// 2: uin16
430// 3: homer_uint8
431// 4: double
432// 5: float
2be16a33 433 if ( ndx >= fBlockCnt )
434 return 0;
435 if ( dataType > (kFloatAlignment_8b_Offset-kAlignment_8b_StartOffset) )
436 return 0;
437 //return ((AliHLTRIBlockDescriptorV1*)fBlocks[ndx].fMetaData)->fType.fID;
438 return *(((homer_uint8*)fBlocks[ndx].fMetaData)+kAlignment_8b_StartOffset+dataType);
439 }
440
fe1edbae 441homer_uint64 AliHLTHOMERReader::GetBlockStatusFlags( unsigned long ndx ) const
2be16a33 442 {
04a939f7 443// see header file for class documentation
2be16a33 444 if ( ndx >= fBlockCnt )
445 return 0;
446 return *(((homer_uint64*)fBlocks[ndx].fMetaData)+kStatusFlags_64b_Offset);
447 }
448
449/* HOMER specific */
450/* Return the type of the data in the current event's data
451 block with the given block index (starting at 0). */
fe1edbae 452homer_uint64 AliHLTHOMERReader::GetBlockDataType( unsigned long ndx ) const
2be16a33 453 {
04a939f7 454// see header file for class documentation
2be16a33 455 if ( ndx >= fBlockCnt )
456 return ~(homer_uint64)0;
457 //return ((AliHLTRIBlockDescriptorV1*)fBlocks[ndx].fMetaData)->fType.fID;
458 return *(((homer_uint64*)fBlocks[ndx].fMetaData)+kType_64b_Offset);
459 }
460
461/* Return the origin of the data in the current event's data
462 block with the given block index (starting at 0). */
fe1edbae 463homer_uint32 AliHLTHOMERReader::GetBlockDataOrigin( unsigned long ndx ) const
2be16a33 464 {
04a939f7 465// see header file for class documentation
2be16a33 466 if ( ndx >= fBlockCnt )
467 return ~(homer_uint32)0;
468 //return (homer_uint32)( ((AliHLTRIBlockDescriptorV1*)fBlocks[ndx].fMetaData)->fSubType1.fID );
469 return (homer_uint32)*(((homer_uint64*)fBlocks[ndx].fMetaData)+kSubType1_64b_Offset);
470 }
471
472/* Return a specification of the data in the current event's data
473 block with the given block index (starting at 0). */
fe1edbae 474homer_uint32 AliHLTHOMERReader::GetBlockDataSpec( unsigned long ndx ) const
2be16a33 475 {
04a939f7 476// see header file for class documentation
2be16a33 477 if ( ndx >= fBlockCnt )
478 return ~(homer_uint32)0;
479 //return (homer_uint32)( ((AliHLTRIBlockDescriptorV1*)fBlocks[ndx].fMetaData)->fSubType2.fID );
480 return (homer_uint32)*(((homer_uint64*)fBlocks[ndx].fMetaData)+kSubType2_64b_Offset);
481 }
482
483/* Find the next data block in the current event with the given
484 data type, origin, and specification. Returns the block's
485 index. */
fe1edbae 486unsigned long AliHLTHOMERReader::FindBlockNdx( homer_uint64 type, homer_uint32 origin,
2be16a33 487 homer_uint32 spec, unsigned long startNdx ) const
488 {
04a939f7 489// see header file for class documentation
2be16a33 490 for ( unsigned long n=startNdx; n < fBlockCnt; n++ )
491 {
492 if ( ( type == 0xFFFFFFFFFFFFFFFFULL || *(((homer_uint64*)fBlocks[n].fMetaData)+kType_64b_Offset)==type ) &&
493 ( origin == 0xFFFFFFFF || (homer_uint32)( *(((homer_uint64*)fBlocks[n].fMetaData)+kSubType1_64b_Offset) )==origin ) &&
494 ( spec == 0xFFFFFFFF || (homer_uint32)( *(((homer_uint64*)fBlocks[n].fMetaData)+kSubType2_64b_Offset) )==spec ) )
495 return n;
496 }
497 return ~(unsigned long)0;
498 }
499
500/* Find the next data block in the current event with the given
501 data type, origin, and specification. Returns the block's
502 index. */
fe1edbae 503unsigned long AliHLTHOMERReader::FindBlockNdx( char type[8], char origin[4],
2be16a33 504 homer_uint32 spec, unsigned long startNdx ) const
505 {
04a939f7 506// see header file for class documentation
2be16a33 507 for ( unsigned long n=startNdx; n < fBlockCnt; n++ )
508 {
509 bool found1=true, found2=true;
510 for ( unsigned i = 0; i < 8; i++ )
511 {
512 if ( type[i] != (char)0xFF )
513 {
514 found1=false;
515 break;
516 }
517 }
518 if ( !found1 )
519 {
520 found1 = true;
521 for ( unsigned i = 0; i < 8; i++ )
522 {
523 //printf( "%u: Comparing type '%c' and '%c'\n", i, ((char*)(((homer_uint64*)fBlocks[n].fMetaData)+kType_64b_Offset))[i], type[i] );
524 if ( ((char*)(((homer_uint64*)fBlocks[n].fMetaData)+kType_64b_Offset))[i] != type[i] )
525 {
526 found1=false;
527 break;
528 }
529 }
530 }
531 for ( unsigned i = 0; i < 4; i++ )
532 {
533 if ( origin[i] != (char)0xFF )
534 {
535 found2 = false;
536 break;
537 }
538 }
539 if ( !found2 )
540 {
541 found2 = true;
542 for ( unsigned i = 0; i < 4; i++ )
543 {
544 //printf( "Comparing origin '%c' and '%c'\n", ((char*)(((homer_uint64*)fBlocks[n].fMetaData)+kSubType1_64b_Offset))[i], origin[i] );
545 if ( ((char*)(((homer_uint64*)fBlocks[n].fMetaData)+kSubType1_64b_Offset))[i] != origin[i] )
546 {
547 found2=false;
548 break;
549 }
550 }
551 }
552 //printf( "Comparing spec '0x%08lX' and '0x%08lX'\n", (homer_uint32)( *(((homer_uint64*)fBlocks[n].fMetaData)+kSubType2_64b_Offset) ), spec );
553 if ( found1 && found2 &&
554 ( spec == 0xFFFFFFFF || ((homer_uint32)( *(((homer_uint64*)fBlocks[n].fMetaData)+kSubType2_64b_Offset)) )==spec ) )
555 return n;
556 }
557 return ~(unsigned long)0;
558 }
559
560/* Return the ID of the node that actually produced this data block.
561 This may be different from the node which sent the data to this
562 monitoring object as returned by GetBlockSendNodeID. */
fe1edbae 563const char* AliHLTHOMERReader::GetBlockCreateNodeID( unsigned long ndx ) const
2be16a33 564 {
04a939f7 565// see header file for class documentation
2be16a33 566 if ( ndx >= fBlockCnt )
567 return NULL;
568 return fBlocks[ndx].fOriginatingNodeID;
569 }
570
571
fe1edbae 572void AliHLTHOMERReader::Init()
2be16a33 573 {
04a939f7 574// see header file for class documentation
2be16a33 575 fCurrentEventType = ~(homer_uint64)0;
576 fCurrentEventID = ~(homer_uint64)0;
577 fMaxBlockCnt = fBlockCnt = 0;
578 fBlocks = NULL;
579
580 fDataSourceMaxCnt = fDataSourceCnt = fTCPDataSourceCnt = fShmDataSourceCnt = 0;
581 fDataSources = NULL;
582
583
584 fConnectionStatus = 0;
585 fErrorConnection = ~(unsigned int)0;
586
04a939f7 587 fEventRequestAdvanceTime = 0;
2be16a33 588 }
589
fe1edbae 590bool AliHLTHOMERReader::AllocDataSources( unsigned int sourceCnt )
2be16a33 591 {
04a939f7 592// see header file for class documentation
2be16a33 593 fDataSources = new DataSource[ sourceCnt ];
594 if ( !fDataSources )
595 return false;
596 fDataSourceCnt = 0;
597 fDataSourceMaxCnt = sourceCnt;
598 return true;
599 }
600
fe1edbae 601int AliHLTHOMERReader::AddDataSource( const char* hostname, unsigned short port, DataSource& source )
2be16a33 602 {
04a939f7 603// see header file for class documentation
2be16a33 604 struct hostent* he;
605 he = gethostbyname( hostname );
606 if ( he == NULL )
607 {
608 //fprintf( stderr, "Unable to determine remote host address from '%s'.\n", hostname );
609 return EADDRNOTAVAIL;
610 }
611
612 struct sockaddr_in remoteAddr;
613 remoteAddr.sin_family = AF_INET; // host byte order
614 remoteAddr.sin_port = htons(port); // short, network byte order
615 remoteAddr.sin_addr = *((struct in_addr *)he->h_addr);
616 memset(&(remoteAddr.sin_zero), '\0', 8); // zero the rest of the struct
617
618 // Create socket and connect to target program on remote node
619 source.fTCPConnection = socket( AF_INET, SOCK_STREAM, 0 );
620 if ( source.fTCPConnection == -1 )
621 {
622 return errno;
623 }
624
625 int ret;
626
627 ret = connect( source.fTCPConnection, (struct sockaddr *)&remoteAddr, sizeof(struct sockaddr) );
628 if ( ret == -1 )
629 {
630 ret=errno;
631 close( source.fTCPConnection );
632 return ret;
633 }
634
635 ret = write( source.fTCPConnection, MOD_BIN, strlen(MOD_BIN) );
636 if ( ret != (int)strlen(MOD_BIN) )
637 {
638 ret=errno;
639 close( source.fTCPConnection );
640 return ret;
641 }
642
643 char* tmpchar = new char[ strlen( hostname )+1 ];
644 if ( !tmpchar )
645 {
646 close( source.fTCPConnection );
647 return ENOMEM;
648 }
649 strcpy( tmpchar, hostname );
650 source.fHostname = tmpchar;
651
652 source.fType = kTCP;
653 source.fTCPPort = port;
654 source.fData = NULL;
655 source.fDataSize = 0;
656 source.fDataRead = 0;
657 return 0;
658 }
659
fe1edbae 660int AliHLTHOMERReader::AddDataSource( key_t shmKey, int shmSize, DataSource& source )
2be16a33 661 {
04a939f7 662// see header file for class documentation
2be16a33 663 int ret;
664 char* tmpchar = new char[ MAXHOSTNAMELEN+1 ];
665 if ( !tmpchar )
666 {
667 return ENOMEM;
668 }
669 gethostname( tmpchar, MAXHOSTNAMELEN );
670 tmpchar[MAXHOSTNAMELEN]=(char)0;
671 source.fHostname = tmpchar;
672
673 source.fShmID = shmget( shmKey, shmSize, 0660 );
674 if ( source.fShmID == -1 )
675 {
676 ret = errno;
677 delete [] source.fHostname;
678 return ret;
679 }
680
681 source.fShmPtr = (void*)shmat( source.fShmID, NULL, 0 );
682
683 if ( !source.fShmPtr )
684 {
685 ret = errno;
686 shmctl( source.fShmID, IPC_RMID, NULL );
687 delete [] source.fHostname;
688 return ret;
689 }
690
691 source.fType = kShm;
692 source.fShmKey = shmKey;
693 source.fShmSize = shmSize;
694 source.fDataSize = 0;
695 source.fDataRead = 0;
696 return 0;
697 }
698
8c617325 699int AliHLTHOMERReader::AddDataSource( void* pBuffer, int size, DataSource& source )
700 {
701// see header file for class documentation
702// a buffer data source is like a shm source apart from the shm attach and detach
703// procedure. Furthermore, the size indicator at the beginning of the buffer is not
704// cleared right before sources are read but after the reading.
705 int ret;
706 if ( !pBuffer || size<=0) return EINVAL;
707
708 char* tmpchar = new char[ MAXHOSTNAMELEN+1 ];
709 if ( !tmpchar )
710 {
711 return ENOMEM;
712 }
713 gethostname( tmpchar, MAXHOSTNAMELEN );
714 tmpchar[MAXHOSTNAMELEN]=(char)0;
715 source.fHostname = tmpchar;
716
717 source.fShmID = -1;
718 // the data buffer does not contain a size indicator in the first 4 bytes
719 // like the shm source buffer. Still we want to use the mechanism to invalidate/
720 // trigger by clearing the size indicator. Take the source.fShmSize variable.
721 source.fShmPtr = &source.fShmSize;
722 source.fType = kBuf;
723 source.fShmKey = 0;
724 source.fShmSize = size;
725 source.fData = pBuffer;
726 source.fDataSize = 0;
727 source.fDataRead = 0;
728 return 0;
729 }
730
fe1edbae 731void AliHLTHOMERReader::FreeDataSources()
2be16a33 732 {
04a939f7 733// see header file for class documentation
2be16a33 734 for ( unsigned n=0; n < fDataSourceCnt; n++ )
735 {
736 if ( fDataSources[n].fType == kTCP )
737 FreeTCPDataSource( fDataSources[n] );
8c617325 738 else if ( fDataSources[n].fType == kShm )
2be16a33 739 FreeShmDataSource( fDataSources[n] );
740 }
741 }
742
fe1edbae 743int AliHLTHOMERReader::FreeShmDataSource( DataSource& source )
2be16a33 744 {
04a939f7 745// see header file for class documentation
2be16a33 746 if ( source.fShmPtr )
747 shmdt( source.fShmPtr );
748// if ( source.fShmID != -1 )
749// shmctl( source.fShmID, IPC_RMID, NULL );
750 if ( source.fHostname )
751 delete [] source.fHostname;
752 return 0;
753 }
754
fe1edbae 755int AliHLTHOMERReader::FreeTCPDataSource( DataSource& source )
2be16a33 756 {
04a939f7 757// see header file for class documentation
2be16a33 758 if ( source.fTCPConnection )
759 close( source.fTCPConnection );
760 if ( source.fHostname )
761 delete [] source.fHostname;
762 return 0;
763 }
764
fe1edbae 765int AliHLTHOMERReader::ReadNextEvent( bool useTimeout, unsigned long timeout )
2be16a33 766 {
04a939f7 767// see header file for class documentation
2be16a33 768 if ( fDataSourceCnt<=0 )
769 return ENXIO;
770 // Clean up currently active event.
771 ReleaseCurrentEvent();
772 int ret;
773 // Trigger all configured data sources
774 for ( unsigned n = 0; n<fDataSourceCnt; n++ )
775 {
776 if ( fDataSources[n].fType == kTCP )
777 ret = TriggerTCPSource( fDataSources[n], useTimeout, timeout );
8c617325 778 else if ( fDataSources[n].fType == kShm )
2be16a33 779 ret = TriggerShmSource( fDataSources[n], useTimeout, timeout );
780 if ( ret )
781 {
782 fErrorConnection = n;
783 fConnectionStatus=ret;
784 return fConnectionStatus;
785 }
786 }
787 // Now read in data from the configured data source
788 ret = ReadDataFromTCPSources( fTCPDataSourceCnt, fDataSources, useTimeout, timeout );
789 if ( ret )
790 {
791 return ret;
792 }
793 ret = ReadDataFromShmSources( fShmDataSourceCnt, fDataSources+fTCPDataSourceCnt, useTimeout, timeout );
794 if ( ret )
795 {
796 return ret;
797 }
798// for ( unsigned n = 0; n<fDataSourceCnt; n++ )
799// {
800// if ( fDataSources[n].fType == kTCP )
801// ret = ReadDataFromTCPSource( fDataSources[n], useTimeout, timeout );
802// else
803// ret = ReadDataFromShmSource( fDataSources[n], useTimeout, timeout );
804// if ( ret )
805// {
806// fErrorConnection = n;
807// fConnectionStatus=ret;
808// return fConnectionStatus;
809// }
810// }
811 //Check to see that all sources contributed data for the same event
812 homer_uint64 eventID;
813 homer_uint64 eventType;
814 eventID = GetSourceEventID( fDataSources[0] );
815 eventType = GetSourceEventType( fDataSources[0] );
816 for ( unsigned n = 1; n < fDataSourceCnt; n++ )
817 {
818 if ( GetSourceEventID( fDataSources[n] ) != eventID || GetSourceEventType( fDataSources[n] ) != eventType )
819 {
820 fErrorConnection = n;
746d2a94 821 fConnectionStatus=56;//EBADRQC;
2be16a33 822 return fConnectionStatus;
823 }
824 }
825 // Find all the different data blocks contained in the data from all
826 // the sources.
827 for ( unsigned n = 0; n < fDataSourceCnt; n++ )
828 {
829 ret = ParseSourceData( fDataSources[n] );
830 if ( ret )
831 {
832 fErrorConnection = n;
746d2a94 833 fConnectionStatus=57;//EBADSLT;
2be16a33 834 return fConnectionStatus;
835 }
836 }
837 fCurrentEventID = eventID;
838 fCurrentEventType = eventType;
839 return 0;
840 }
841
fe1edbae 842void AliHLTHOMERReader::ReleaseCurrentEvent()
2be16a33 843 {
04a939f7 844// see header file for class documentation
2be16a33 845 // sources.fDataRead = 0;
846 // fMaxBlockCnt
847 fCurrentEventID = ~(homer_uint64)0;
848 fCurrentEventType = ~(homer_uint64)0;
849 for ( unsigned n = 0; n < fDataSourceCnt; n++ )
850 {
851 if ( fDataSources[n].fData )
852 {
853 if ( fDataSources[n].fType == kTCP )
854 delete [] (homer_uint8*)fDataSources[n].fData;
855 fDataSources[n].fData = NULL;
856 }
857 fDataSources[n].fDataSize = fDataSources[n].fDataRead = 0;
858 }
859 if ( fBlocks )
860 {
861 for ( unsigned n = 0; n < fMaxBlockCnt; n++ )
862 {
863 if ( fBlocks[n].fOriginatingNodeID )
864 delete [] fBlocks[n].fOriginatingNodeID;
865 }
866 delete [] fBlocks;
867 fBlocks=0;
868 fMaxBlockCnt = 0;
869 fBlockCnt=0;
870 }
871 }
872
fe1edbae 873int AliHLTHOMERReader::TriggerTCPSource( DataSource& source, bool useTimeout, unsigned long timeoutUsec )
2be16a33 874 {
04a939f7 875// see header file for class documentation
2be16a33 876 int ret;
877 struct timeval oldSndTO, newSndTO;
878 if ( useTimeout )
879 {
880 socklen_t optlen=sizeof(oldSndTO);
881 ret = getsockopt( source.fTCPConnection, SOL_SOCKET, SO_SNDTIMEO, &oldSndTO, &optlen );
882 if ( ret )
883 {
884 return errno;
885 }
886 if ( optlen!=sizeof(oldSndTO) )
887 {
888 return ENXIO;
889 }
3a7c0444 890 newSndTO.tv_sec = timeoutUsec / 1000000;
891 newSndTO.tv_usec = timeoutUsec - (newSndTO.tv_sec*1000000);
2be16a33 892 ret = setsockopt( source.fTCPConnection, SOL_SOCKET, SO_SNDTIMEO, &newSndTO, sizeof(newSndTO) );
893 if ( ret )
894 {
895 return errno;
896 }
897 }
898 // Send one event request
04a939f7 899 if ( !fEventRequestAdvanceTime )
2be16a33 900 {
901 ret = write( source.fTCPConnection, GET_ONE, strlen(GET_ONE) );
902
903 if ( ret != (int)strlen(GET_ONE) )
904 {
905 ret=errno;
906 setsockopt( source.fTCPConnection, SOL_SOCKET, SO_SNDTIMEO, &oldSndTO, sizeof(oldSndTO) );
907 return ret;
908 }
909 }
910 else
911 {
912 char tmpCmd[ 128 ];
913
04a939f7 914 int len = snprintf( tmpCmd, 128, "FIRST ORBIT EVENT 0x%Lu\n", (unsigned long long)fEventRequestAdvanceTime );
2be16a33 915 if ( len>128 || len<0 )
916 {
917 ret=EMSGSIZE;
918 setsockopt( source.fTCPConnection, SOL_SOCKET, SO_SNDTIMEO, &oldSndTO, sizeof(oldSndTO) );
919 return ret;
920 }
921
922 ret = write( source.fTCPConnection, tmpCmd, strlen(tmpCmd) );
923
924 if ( ret != (int)strlen(tmpCmd) )
925 {
926 ret=errno;
927 setsockopt( source.fTCPConnection, SOL_SOCKET, SO_SNDTIMEO, &oldSndTO, sizeof(oldSndTO) );
928 return ret;
929 }
930
931 }
932 return 0;
933 }
934
fe1edbae 935int AliHLTHOMERReader::TriggerShmSource( DataSource& source, bool, unsigned long )
2be16a33 936 {
04a939f7 937// see header file for class documentation
fe1edbae 938// clear the size indicator in the first 4 bytes of the buffer to request data
939// from the HOMER writer.
2be16a33 940 if ( source.fShmPtr )
941 {
942 *(homer_uint32*)( source.fShmPtr ) = 0;
943 return 0;
944 }
945 else
946 return EFAULT;
947 }
948
fe1edbae 949int AliHLTHOMERReader::ReadDataFromTCPSources( unsigned sourceCnt, DataSource* sources, bool useTimeout, unsigned long timeout )
2be16a33 950 {
3a7c0444 951// see header file for class documentation
2be16a33 952 bool toRead = false;
953 do
954 {
955 fd_set conns;
956 FD_ZERO( &conns );
957 int highestConn=0;
958 toRead = false;
959 unsigned firstConnection=~(unsigned)0;
960 for ( unsigned long n = 0; n < sourceCnt; n++ )
961 {
962 if ( sources[n].fDataSize == 0 // size specifier not yet read
963 || sources[n].fDataRead < sources[n].fDataSize ) // Data not yet read fully
964 {
965 toRead = true;
966 FD_SET( sources[n].fTCPConnection, &conns );
967 if ( sources[n].fTCPConnection > highestConn )
968 highestConn = sources[n].fTCPConnection;
969 fcntl( sources[n].fTCPConnection, F_SETFL, O_NONBLOCK );
970 if ( firstConnection == ~(unsigned)0 )
971 firstConnection = n;
972 }
973 else
974 {
975 fcntl( sources[n].fTCPConnection, F_SETFL, 0 );
976 }
977 }
978 if ( toRead )
979 {
980 struct timeval tv, *ptv;
981 if ( useTimeout )
982 {
983 tv.tv_sec = timeout / 1000000;
984 tv.tv_usec = timeout - (tv.tv_sec*1000000);
985 ptv = &tv;
986 }
987 else
988 ptv = NULL;
989 // wait until something is ready to be read
990 // either for timeout usecs or until eternity
991 int ret;
992 ret = select( highestConn+1, &conns, NULL, NULL, ptv );
993 if ( ret <=0 )
994 {
995 fErrorConnection = firstConnection;
996 if ( errno )
997 fConnectionStatus = errno;
998 else
999 fConnectionStatus = ETIMEDOUT;
1000 return fConnectionStatus;
1001 }
1002 for ( unsigned n = 0; n < sourceCnt; n++ )
1003 {
1004 if ( FD_ISSET( sources[n].fTCPConnection, &conns ) )
1005 {
1006 if ( sources[n].fDataSize == 0 )
1007 {
1008 ret=read( sources[n].fTCPConnection, &(sources[n].fDataSize), sizeof(homer_uint32) );
1009 if ( ret != sizeof(homer_uint32) )
1010 {
1011 fErrorConnection = n;
1012 if ( errno )
1013 fConnectionStatus = errno;
1014 else
1015 fConnectionStatus = ENOMSG;
1016 return fConnectionStatus;
1017 }
1018 sources[n].fDataSize = ntohl( sources[n].fDataSize );
1019 sources[n].fDataRead = 0;
1020 sources[n].fData = new homer_uint8[ sources[n].fDataSize ];
1021 if ( !sources[n].fData )
1022 {
1023 fErrorConnection = n;
1024 fConnectionStatus = ENOMEM;
1025 return fConnectionStatus;
1026 }
1027 }
1028 else if ( sources[n].fData && sources[n].fDataRead < sources[n].fDataSize)
1029 {
1030 ret=read( sources[n].fTCPConnection, ((homer_uint8*)sources[n].fData)+sources[n].fDataRead, sources[n].fDataSize-sources[n].fDataRead );
1031 if ( ret>0 )
1032 sources[n].fDataRead += ret;
1033 else if ( ret == 0 )
1034 {
1035 fErrorConnection = n;
1036 fConnectionStatus = ECONNRESET;
1037 return fConnectionStatus;
1038 }
1039 else
1040 {
1041 fErrorConnection = n;
1042 fConnectionStatus = errno;
1043 return fConnectionStatus;
1044 }
1045 }
1046 else
1047 {
1048 fErrorConnection = n;
1049 fConnectionStatus = ENXIO;
1050 return fConnectionStatus;
1051 }
1052 }
1053 }
1054 }
1055 }
1056 while ( toRead );
1057 return 0;
1058 }
1059
1060/*
fe1edbae 1061int AliHLTHOMERReader::ReadDataFromTCPSources( DataSource& source, bool useTimeout, unsigned long timeout )
2be16a33 1062 {
1063#warning TODO If useTimeout: Set sockets to nonblocking, select + loop around GET_ONE write
1064 // Send one event request
1065 ret = write( source.fTCPConnection, GET_ONE, strlen(GET_ONE) );
1066 if ( ret != strlen(GET_ONE) )
1067 {
1068 return errno;
1069 }
1070 // wait for and read back size specifier
1071 unsigned sizeNBO;
1072 // The value transmitted is binary, in network byte order
1073 ret = read( source.fTCPConnection, &sizeNBO, sizeof(sizeNBO) );
1074 if ( ret != sizeof(sizeNBO) )
1075 {
1076 return errno;
1077 }
1078 // Convert back to host byte order
1079 source.fDataSize = ntohl( sizeNBO );
1080 source.fData = new homer_uint8[ source.fDataSize ];
1081 unsigned long dataRead=0, toRead;
1082 if ( !source.fData )
1083 {
1084 char buffer[1024];
1085 // Read in data into buffer in order not to block connection
1086 while ( dataRead < source.fDataSize )
1087 {
1088 if ( source.fDataSize-dataRead > 1024 )
1089 toRead = 1024;
1090 else
1091 toRead = source.fDataSize-dataRead;
1092 ret = read( source.fTCPConnection, buffer, toRead );
1093 if ( ret > 0 )
1094 dataRead += ret;
1095 else
1096 return errno;
1097 }
1098 return ENOMEM;
1099 }
1100 while ( dataRead < source.fDataSize )
1101 {
1102 toRead = source.fDataSize-dataRead;
1103 ret = read( source.fTCPConnection, source.fData+dataRead, toRead );
1104 if ( ret > 0 )
1105 dataRead += ret;
1106 else if ( ret == 0 && useTimeout )
1107 {
1108 struct timeval tv;
1109 tv.tv_sec = timeout / 1000000;
1110 tv.tv_usec = timeout - (tv.tv_sec*1000000);
1111 fd_set conns;
1112 FD_ZERO( &conns );
1113 FD_SET( source.fTCPConnection, &conns );
1114 ret = select( source.fTCPConnection+1, &conns, NULL, NULL );
1115 if ( ret <=0 )
1116 return errno;
1117 }
1118 else if ( ret == 0 )
1119 {
1120 if ( errno == EOK )
1121 return ECONNRESET;
1122 else
1123 return errno;
1124 }
1125 else
1126 {
1127 return errno;
1128 }
1129 }
1130 return 0;
1131 }
1132*/
1133
1134/*
fe1edbae 1135int AliHLTHOMERReader::ReadDataFromShmSource( DataSource& source, bool useTimeout, unsigned long timeout )
2be16a33 1136 {
1137
1138 }
1139*/
1140
fe1edbae 1141int AliHLTHOMERReader::ReadDataFromShmSources( unsigned sourceCnt, DataSource* sources, bool useTimeout, unsigned long timeout )
2be16a33 1142 {
04a939f7 1143// see header file for class documentation
2be16a33 1144 struct timeval tv1, tv2;
1145 bool found=false;
1146 bool all=true;
1147 if ( useTimeout )
1148 gettimeofday( &tv1, NULL );
1149 do
1150 {
1151 found = false;
1152 all = true;
1153 for ( unsigned n = 0; n < sourceCnt; n++ )
1154 {
1155 if ( !sources[n].fDataSize )
1156 all = false;
1157 if ( sources[n].fShmPtr && *(homer_uint32*)sources[n].fShmPtr>0 && !sources[n].fDataSize )
1158 {
1159 found = true;
1160 sources[n].fDataSize = *(homer_uint32*)sources[n].fShmPtr;
8c617325 1161 if (sources[n].fType==kBuf)
1162 {
1163 // the data buffer is already set to fData, just need to set fDataSize member
1164 // to invalidate after the first reading. Subsequent calls to ReadNextEvent return 0
1165 TriggerShmSource( sources[n], 0, 0 );
1166 } else
1167 {
1168 sources[n].fData = ((homer_uint8*)sources[n].fShmPtr)+sizeof(homer_uint32);
1169 }
2be16a33 1170 }
1171 }
1172 if ( found && useTimeout )
1173 gettimeofday( &tv1, NULL );
1174 if ( !all && useTimeout )
1175 {
1176 gettimeofday( &tv2, NULL );
1177 unsigned long long tdiff;
1178 tdiff = tv2.tv_sec-tv1.tv_sec;
1179 tdiff *= 1000000;
1180 tdiff += tv2.tv_usec-tv1.tv_usec;
1181 if ( tdiff > timeout )
1182 return ETIMEDOUT;
1183 }
1184 if ( !all )
1185 usleep( 0 );
1186 }
1187 while ( !all );
1188 return 0;
1189 }
1190
fe1edbae 1191int AliHLTHOMERReader::ParseSourceData( DataSource& source )
2be16a33 1192 {
04a939f7 1193// see header file for class documentation
2be16a33 1194 if ( source.fData )
1195 {
1196 homer_uint8 sourceByteOrder = ((homer_uint8*)source.fData)[ kByteOrderAttribute_8b_Offset ];
1197 homer_uint64 blockCnt = Swap( kHOMERNativeByteOrder, sourceByteOrder, ((homer_uint64*)source.fData)[ kSubType2_64b_Offset ] );
1198 int ret=ReAllocBlocks( fMaxBlockCnt+blockCnt );
1199 if ( ret )
1200 return ret;
1201 homer_uint64 descrOffset = Swap( kHOMERNativeByteOrder, sourceByteOrder, ((homer_uint64*)source.fData)[ kOffset_64b_Offset ] );
1202 for ( homer_uint64 n = 0; n < blockCnt && fBlockCnt < fMaxBlockCnt; n++, fBlockCnt++ )
1203 {
1204 homer_uint8* descr = ((homer_uint8*)source.fData)+descrOffset;
1205 unsigned descrLen = Swap( kHOMERNativeByteOrder, sourceByteOrder, ((homer_uint64*)descr)[ kLength_64b_Offset ] );
1206 fBlocks[fBlockCnt].fSource = source.fNdx;
1207 fBlocks[fBlockCnt].fData = ((homer_uint8*)source.fData) + Swap( kHOMERNativeByteOrder, sourceByteOrder, ((homer_uint64*)descr)[ kOffset_64b_Offset ] );
1208 fBlocks[fBlockCnt].fLength = Swap( kHOMERNativeByteOrder, sourceByteOrder, ((homer_uint64*)descr)[ kSize_64b_Offset ] );
1209 fBlocks[fBlockCnt].fMetaData = (homer_uint64*)descr;
1210 struct in_addr tmpA;
1211 tmpA.s_addr = (homer_uint32)( ((homer_uint64*)descr)[ kProducerNode_64b_Offset ] );
1212 char* addr = inet_ntoa( tmpA );
1213 char* tmpchar = new char[ strlen(addr)+1 ];
1214 if ( !tmpchar )
1215 return ENOMEM;
1216 strcpy( tmpchar, addr );
1217 fBlocks[fBlockCnt].fOriginatingNodeID = tmpchar;
1218 descrOffset += descrLen;
1219 }
1220 return 0;
1221 }
1222 return EFAULT;
1223 }
1224
fe1edbae 1225int AliHLTHOMERReader::ReAllocBlocks( unsigned long newCnt )
2be16a33 1226 {
04a939f7 1227// see header file for class documentation
2be16a33 1228 DataBlock* newBlocks;
1229 newBlocks = new DataBlock[ newCnt ];
1230 if ( !newBlocks )
1231 return ENOMEM;
1232 unsigned long cpCnt = (newCnt > fMaxBlockCnt) ? fMaxBlockCnt : newCnt;
1233 memcpy( newBlocks, fBlocks, cpCnt*sizeof(DataBlock) );
1234 if ( newCnt > fMaxBlockCnt )
1235 memset( newBlocks+fMaxBlockCnt, 0, (newCnt-fMaxBlockCnt)*sizeof(DataBlock) );
1236 if ( fBlocks )
1237 delete [] fBlocks;
1238 fBlocks = newBlocks;
1239 fMaxBlockCnt = newCnt;
1240 return 0;
1241 }
1242
fe1edbae 1243homer_uint64 AliHLTHOMERReader::GetSourceEventID( DataSource& source )
2be16a33 1244 {
04a939f7 1245// see header file for class documentation
2be16a33 1246 homer_uint8 sourceByteOrder = ((homer_uint8*)source.fData)[ kByteOrderAttribute_8b_Offset ];
1247 return Swap( kHOMERNativeByteOrder, sourceByteOrder, ((homer_uint64*)source.fData)[ kSubType1_64b_Offset ] );
1248 }
1249
fe1edbae 1250homer_uint64 AliHLTHOMERReader::GetSourceEventType( DataSource& source )
2be16a33 1251 {
04a939f7 1252// see header file for class documentation
2be16a33 1253 homer_uint8 sourceByteOrder = ((homer_uint8*)source.fData)[ kByteOrderAttribute_8b_Offset ];
1254 return Swap( kHOMERNativeByteOrder, sourceByteOrder, ((homer_uint64*)source.fData)[ kType_64b_Offset ] );
1255 }
1256
fe1edbae 1257homer_uint64 AliHLTHOMERReader::Swap( homer_uint8 destFormat, homer_uint8 sourceFormat, homer_uint64 source ) const
3a7c0444 1258 {
1259// see header file for class documentation
1260 if ( destFormat == sourceFormat )
1261 return source;
1262 else
1263 return ((source & 0xFFULL) << 56) |
1264 ((source & 0xFF00ULL) << 40) |
1265 ((source & 0xFF0000ULL) << 24) |
1266 ((source & 0xFF000000ULL) << 8) |
1267 ((source & 0xFF00000000ULL) >> 8) |
1268 ((source & 0xFF0000000000ULL) >> 24) |
1269 ((source & 0xFF000000000000ULL) >> 40) |
1270 ((source & 0xFF00000000000000ULL) >> 56);
1271 }
2be16a33 1272
fe1edbae 1273homer_uint32 AliHLTHOMERReader::Swap( homer_uint8 destFormat, homer_uint8 sourceFormat, homer_uint32 source ) const
3a7c0444 1274 {
1275// see header file for class documentation
1276 if ( destFormat == sourceFormat )
1277 return source;
1278 else
1279 return ((source & 0xFFUL) << 24) |
1280 ((source & 0xFF00UL) << 8) |
1281 ((source & 0xFF0000UL) >> 8) |
1282 ((source & 0xFF000000UL) >> 24);
1283 }
fe1edbae 1284
1285AliHLTHOMERReader* AliHLTHOMERReaderCreate(const void* pBuffer, int size)
1286 {
1287// see header file for function documentation
8c617325 1288 return new AliHLTHOMERReader(pBuffer, size);
fe1edbae 1289 }
1290
1291void AliHLTHOMERReaderDelete(AliHLTHOMERReader* pInstance)
1292 {
1293// see header file for function documentation
1294 if (pInstance) delete pInstance;
1295 }
1296
2be16a33 1297/*
1298***************************************************************************
1299**
1300** $Author$ - Initial Version by Timm Morten Steinbeck
1301**
1302** $Id$
1303**
1304***************************************************************************
1305*/