1
/*******************************************************************************
3
* mcfio_Direct.c -- Utility routines for the McFast Monte-Carlo *
4
* Direct Access I/O core routines *
6
* Copyright (c) 1994 Universities Research Association, Inc. *
7
* All rights reserved. *
9
* This material resulted from work developed under a Government Contract and *
10
* is subject to the following license: The Government retains a paid-up, *
11
* nonexclusive, irrevocable worldwide license to reproduce, prepare derivative *
12
* works, perform publicly and display publicly by or for the Government, *
13
* including the right to distribute to other Government contractors. Neither *
14
* the United States nor the United States Department of Energy, nor any of *
15
* their employees, makes any warranty, express or implied, or assumes any *
16
* legal liability or responsibility for the accuracy, completeness, or *
17
* usefulness of any information, apparatus, product, or process disclosed, or *
18
* represents that its use would not infringe privately owned rights. *
21
* Written by Paul Lebrun *
24
*******************************************************************************/
27
#include <sys/param.h>
28
#include <rpc/types.h>
29
#include <sys/types.h>
39
#include <floatingpoint.h>
43
#include "mcf_nTupleDescript.h"
45
#include "mcfio_Dict.h"
46
#include "mcfio_Util1.h"
47
#include "mcfio_Direct.h"
48
#include "mcf_NTuIOUtils.h"
59
extern nTuDDL **NTuDDLList;
60
extern int NumOfNTuples;
63
/* Static routine used in this module */
65
static int mcfioC_gofornextevent(mcfStream *str);
66
static int mcfioC_nextspecevt(mcfStream *str, int inum, int istore,
68
static int openReadDirect(char*filename, int mode);
71
int mcfioC_OpenReadDirect(char *filename)
74
** Routine to open and read the header file for a Direct access Stream,
77
return openReadDirect(filename, MCFIO_DIRECT);
80
int mcfioC_OpenReadMapped(char *filename)
83
** Routine to open and read the header file for a Direct access Stream,
86
return openReadDirect(filename, MCFIO_MEMMAPPED);
89
static int openReadDirect(char *filename, int mode)
91
** Routine to open and read the header file for a Direct access Stream.
94
int i, j, jstr, idtmp, ntot, ll1, jdRef, oldNumOfNTuples;
104
if (McfStreamPtrList == NULL) mcfioC_Init();
106
if (McfNumOfStreamActive >= MCF_STREAM_NUM_MAX) {
108
" mcfio_OpenReadDirect: Too many streams opened simultaneously.\n");
112
while ((jstr == -1) && (i<MCF_STREAM_NUM_MAX)) {
113
if (McfStreamPtrList[i] == NULL) jstr=i;
118
" mcfio_OpenReadDirect: Internal error, please report \n");
121
if ((filename == NULL) || (strlen(filename) > 255)) {
123
" mcfio_OpenReadDirect: You must give a valid UNIX filename.\n");
127
** Now we can try to open this file....
129
if (mode == MCFIO_DIRECT) {
130
ff = fopen(filename, "r");
133
" mcfio_OpenReadDirect: Problem opening file %s, message \n", filename);
134
perror ("mcfio_OpenReadDirect");
139
** Using memory mapped i/o
141
iff = open(filename, O_RDONLY);
144
" mcfio_OpenReadMapped: Problem opening file %s, message \n", filename);
145
perror ("mcfio_OpenReadMapped");
149
McfStreamPtrList[jstr] = (mcfStream *) malloc(sizeof(mcfStream));
150
str = McfStreamPtrList[jstr];
151
str->xdr = (XDR *) malloc(sizeof(XDR));
153
str->row = MCFIO_READ;
157
ll1 = strlen(filename) + 1;
158
str->filename = (char *) malloc(sizeof(char) * ll1);
159
strcpy(str->filename,filename);
160
if (mode == MCFIO_DIRECT) {
162
xdrstdio_create(str->xdr, ff, XDR_DECODE);
164
str->fileAddr = NULL;
168
** Use memory mapped I/O
170
if (fstat(iff, &statbuf) < 0) {
172
" mcfio_OpenReadMapped: Problem getting file length for %s \n", filename);
173
perror ("mcfio_OpenReadMapped");
177
mmap(0, statbuf.st_size, PROT_READ, MAP_FILE | MAP_SHARED, iff, 0 ))
180
" mcfio_OpenReadMapped: Problem with memory mapping for %s \n", filename);
181
perror ("mcfio_OpenReadMapped");
184
str->filePtr = (FILE *) NULL;
185
str->fileDescr = iff;
186
str->fileAddr = srcFile;
187
str->fileLen = (size_t) statbuf.st_size;
188
xdrmem_create(str->xdr, srcFile, statbuf.st_size, XDR_DECODE);
192
str->filenumber = -1;
200
p1 = xdr_getpos(str->xdr);
202
str->status = MCFIO_BOF;
204
oldNumOfNTuples = NumOfNTuples;
205
if (xdr_mcfast_fileheader(str->xdr, &idtmp,
206
&ntot, McfGenericVersion, &(str->fhead), str->id) == FALSE) {
208
"mcfio_OpenReadDirect: Unable to decode fileheader \n");
209
mcfioC_FreeStream(&McfStreamPtrList[jstr]);
210
mcfioC_Close(jstr+1);
213
if (idtmp != FILEHEADER) {
215
"mcfio_OpenReadDirect: First Structure not the header \n");
218
" : Further accesses probably suspicious \n");
219
mcfioC_FreeStream(&McfStreamPtrList[jstr]);
220
mcfioC_Close(jstr+1);
223
p2 = xdr_getpos(str->xdr);
224
str->numWordsC += (ntot/4);
226
** Check if new these Ntuple template are not reference, if so,
227
** set the reference pointer accordingly, conversely, recompute the
228
** offsets and length if requested. We also fill the sequential
229
** id number for the descriptors. Note: those are trivial for
230
** input streams, but we still fill them for consitency.
232
for (i=0; i<str->fhead->nNTuples; i++) {
233
ddl = mcf_GetNTuByPtrID((oldNumOfNTuples+i+1));
234
if (ddl == NULL) continue;
235
ddl->streamId = (jstr+1);
236
ddl->seqNTuId = (i+1);
237
if (ddl->descrNtu == NULL) {
238
for (j=0, jdRef=1; j<i; j++, jdRef++) {
239
if (jdRef == ddl->referenceId) {
240
ddlRef = mcf_GetNTuByPtrID((oldNumOfNTuples+j+1));
242
** back up in the linked list if need be, until we
243
** a fully documented descriptor.
245
while (ddlRef->descrNtu == NULL) ddlRef = ddlRef->reference;
246
ddl->reference = ddlRef;
251
if (McfNTuPleSaveDecoding == TRUE) {
252
mcf_ComputeNTuOffsets(ddl);
253
mcf_ComputeNTuLengths(ddl);
257
str->currentPos = p2;
258
str->fhead->firstTable = p2;
259
/* presumably correct , assume standard direct acces file config. */
260
str->numWordsT += ((p2-p1)/4);
261
str->status = MCFIO_RUNNING;
262
str->table = (mcfxdrEventTable *) malloc(sizeof(mcfxdrEventTable));
263
str->table->nextLocator = -1;
264
str->table->dim = str->fhead->dimTable;
265
str->table->numevts = 0;
266
str->table->previousnumevts = 0;
267
str->table->evtnums = NULL;
268
str->table->storenums = NULL;
269
str->table->runnums = NULL;
270
str->table->trigMasks = NULL;
271
str->table->ptrEvents = NULL;
272
str->ehead = (mcfxdrEventHeader *) malloc(sizeof(mcfxdrEventHeader));
273
str->ehead->dimBlocks = str->fhead->nBlocks;
274
str->ehead->blockIds = NULL;
275
str->ehead->ptrBlocks = NULL;
276
str->ehead->dimNTuples = str->fhead->nNTuples;
277
str->ehead->nTupleIds = NULL;
278
str->ehead->ptrNTuples = NULL;
279
McfNumOfStreamActive++;
283
int mcfioC_OpenWriteDirect(char *filename, char *title, char *comment,
284
int numevts_pred, int *blkIds, u_int nBlocks)
287
** Routine to open and write the header file for a Direct access Stream.
290
int i, jstr, idtmp, ntot;
295
if (McfStreamPtrList == NULL) {
297
" mcfio_OpenWriteDirect: We will first initialize by calling mcfio_Init.\n");
300
if (McfNumOfStreamActive >= MCF_STREAM_NUM_MAX) {
302
" mcfio_OpenWriteDirect: Too many streams opened simultaneously.\n");
306
while ((jstr == -1) && (i<MCF_STREAM_NUM_MAX)) {
307
if (McfStreamPtrList[i] == NULL) jstr=i;
312
" mcfio_OpenWriteDirect: Internal error, please report \n");
315
if ((filename == NULL) || (strlen(filename) > 255)) {
317
" mcfio_OpenWriteDirect: You must give a valid UNIX filename.\n");
320
if ((title != NULL) && (strlen(title) > 255)) {
322
" mcfio_OpenWriteDirect: Title is too long\n");
326
if ((comment != NULL) && (strlen(comment) > 255)) {
328
" mcfio_OpenWriteDirect: comment is too long\n");
333
** Now we can try to open this file....
335
ff = fopen(filename, "w");
338
" mcfio_OpenWriteDirect: Problem opening file %s, message \n", filename);
339
perror ("mcfio_OpenWriteDirect");
342
McfStreamPtrList[jstr] = (mcfStream *) malloc(sizeof(mcfStream));
343
str = McfStreamPtrList[jstr];
344
str->xdr = (XDR *) malloc(sizeof(XDR));
346
str->row = MCFIO_WRITE;
347
str->dos = MCFIO_DIRECT;
350
str->filename = (char *) malloc(sizeof(char) * ( strlen(filename) +1) );
351
strcpy(str->filename,filename);
355
str->filenumber = -1;
363
xdrstdio_create(str->xdr, ff, XDR_ENCODE);
364
p1 = xdr_getpos(str->xdr);
366
str->currentPos = p1;
367
str->status = MCFIO_BOF;
368
str->fhead = (mcfxdrFileHeader *) malloc(sizeof(mcfxdrFileHeader));
370
** Fill the file header, additional info will be written on tape
372
if (title == NULL) strcpy(str->fhead->title,"No Title given");
373
else strcpy(str->fhead->title,title);
375
if (comment == NULL) strcpy(str->fhead->comment,"No comment");
376
else strcpy(str->fhead->comment, comment);
377
str->fhead->numevts_expect = numevts_pred;
378
str->fhead->numevts = 0;
380
** Futur expansion : make this a tunable parameter.
382
str->fhead->dimTable = MCF_DEFAULT_TABLE_SIZE;
383
str->fhead->firstTable = -1;
384
str->fhead->nBlocks = nBlocks;
386
str->fhead->blockIds = (int *) malloc(sizeof(int) * nBlocks);
387
str->fhead->blockNames = (char**) malloc(sizeof(char *) * nBlocks);
389
str->fhead->blockIds = NULL;
390
str->fhead->blockNames = NULL;
392
for (i=0; i<nBlocks; i++) {
393
str->fhead->blockIds[i] = blkIds[i];
394
str->fhead->blockNames[i] =
395
(char *) malloc(sizeof(char) * (MCF_XDR_B_TITLE_LENGTH + 1));
396
mcfioC_GetBlockName(blkIds[i], str->fhead->blockNames[i]);
398
str->fhead->nNTuples = 0; /* Will be filled later */
399
if (mcfioC_Wrtfhead(str, INITIATE) == FALSE){
400
mcfioC_FreeStream(&McfStreamPtrList[jstr]);
404
str->table = (mcfxdrEventTable *) malloc(sizeof(mcfxdrEventTable));
405
str->table->numevts=-1;
406
str->table->nextLocator = -1;
407
str->table->evtnums = (int *) malloc(sizeof(int) * str->fhead->dimTable);
408
str->table->storenums = (int *) malloc(sizeof(int) * str->fhead->dimTable);
409
str->table->runnums = (int *) malloc(sizeof(int) * str->fhead->dimTable);
410
str->table->trigMasks = (int *) malloc(sizeof(int) * str->fhead->dimTable);
411
str->table->ptrEvents =
412
(u_int *) malloc(sizeof(int) * str->fhead->dimTable);
414
** Write the first dummy table
416
if (mcfioC_Wrttable(str, INITIATE) == FALSE) return -1;
417
str->ehead = (mcfxdrEventHeader *) malloc(sizeof(mcfxdrEventHeader));
418
str->ehead->dimBlocks = str->fhead->nBlocks;
419
str->ehead->nBlocks = 0;
420
str->ehead->dimNTuples = 0;
421
str->ehead->nNTuples = 0;
422
str->ehead->evtnum = 0;
423
str->ehead->previousevtnum = 0;
424
str->ehead->storenum = 0;
425
str->ehead->runnum = 0;
426
str->ehead->trigMask = 0;
427
str->ehead->nTupleIds = NULL;
428
str->ehead->ptrNTuples = NULL;
430
str->ehead->blockIds =
431
(int *) malloc(sizeof(int) * str->fhead->nBlocks);
432
str->ehead->ptrBlocks =
433
(u_int *) malloc(sizeof(int) * str->fhead->nBlocks);
435
str->ehead->blockIds = NULL;
436
str->ehead->ptrBlocks = NULL;
439
** Write the first dummy event header
441
if (mcfioC_WrtEvt(str, INITIATE) == FALSE) return -1;
442
str->ehead->evtnum = 0;
443
str->status = MCFIO_RUNNING;
444
McfNumOfStreamActive++;
449
int mcfioC_NextEvent(int stream)
451
** The Core routine for getting or setting the next event d.s. from/to
456
int i, jstr, idtmp, ntot, nn1;
457
u_int p_evt, p1, p2, *p_ptr;
460
if (McfStreamPtrList == NULL) {
462
" mcfio_NextEvent: You must first initialize by calling mcfio_Init.\n");
466
if (McfStreamPtrList[jstr] == NULL) {
468
" mcfio_NextEvent: First, declare the stream by calling mcfio_Open...\n");
471
str = McfStreamPtrList[jstr];
472
if (str->dos == MCFIO_SEQUENTIAL) return mcfioC_NextEventSequential(stream);
473
if (str->row == MCFIO_READ) {
475
** Read the next event, hunt for either an event or a table of event
476
** if event table not available.
478
if ((str->table == NULL) ||
479
((str->table != NULL)&& (str->table->evtnums == NULL))) {
480
idtmp = mcfioC_gofornextevent(str);
481
if (idtmp != EVENTTABLE) {
482
if (str->table !=NULL)
483
mcfioC_Free_EventTable(&(str->table));
484
if (idtmp == NOTHING) return -1;
485
p_evt = str->currentPos;
487
if( xdr_mcfast_eventtable(str->xdr, &idtmp,
488
&ntot, McfGenericVersion, &(str->table)) == FALSE) {
490
" mcfio_NextEvent: XDR Error decoding the EventTable \n");
493
p2 = xdr_getpos(str->xdr);
494
str->numWordsC += (ntot/4);
495
str->numWordsT += ((p2-str->currentPos)/4);
496
str->currentPos = p2;
497
str->table->ievt = 0;
499
** If table empty, cal this routine recursively to get
502
if (str->table->numevts <= 0) {
503
if (str->table->nextLocator == -1)
504
mcfioC_Free_EventTable(&(str->table));
505
return mcfioC_NextEvent(str->id);
507
p_evt = str->table->ptrEvents[0];
510
if (str->table->ievt < str->table->numevts) {
511
p_evt = str->table->ptrEvents[str->table->ievt];
514
** decode the next table, if valid. If not, scrap the
515
** existing table and call next event recursively.
517
if (str->table->nextLocator == -2) {
521
str->status = MCFIO_EOF;
523
} else if (str->table->nextLocator == -1) {
525
" mcfio_NextEvent: Corrupted Event Table \n");
528
if (xdr_setpos(str->xdr, str->table->nextLocator) == FALSE) {
530
" mcfio_NextEvent: Error Repositioning stream \n");
533
if( xdr_mcfast_eventtable(str->xdr, &idtmp,
534
&ntot, McfGenericVersion, &(str->table)) == FALSE) {
536
" mcfio_NextEvent: XDR Error decoding the EventTable \n");
539
p2 = xdr_getpos(str->xdr);
540
str->numWordsC += (ntot/4);
541
str->numWordsT += ((p2-str->currentPos)/4);
542
str->currentPos = p2;
543
str->table->ievt = 0;
544
p_evt = str->table->ptrEvents[0];
548
** we should be pointing to a good event header here.
550
if (xdr_setpos(str->xdr, p_evt) == FALSE) return -1;
551
if( xdr_mcfast_eventheader(str->xdr, &idtmp,
552
&ntot, McfGenericVersion, &(str->ehead)) == FALSE) return -1;
553
str->currentPos = xdr_getpos(str->xdr);
554
str->numWordsC += (ntot/4);
555
str->numWordsT += ((str->currentPos - p_evt)/4);
556
if (str->table != NULL) str->table->ievt ++;
557
return MCFIO_RUNNING;
560
** Writing Code here.
562
str->table->numevts++;
563
str->fhead->numevts++;
564
if (str->ehead->previousevtnum == str->ehead->evtnum) str->ehead->evtnum++;
566
** Write the current event header, normal case. First Flush the current
567
** event, then initiate the next one event. Note that wrtevt will
568
** reposition the stream after rewriting the event header, if FLUSH.
569
** e.g. ready to initiate either a new table or a new event.
571
if (mcfioC_WrtEvt(str, FLUSH) == FALSE) return -1;
572
str->ehead->previousevtnum = str->ehead->evtnum;
573
if (str->table->numevts == (str->fhead->dimTable - 1)) {
575
** The Event table is now full. Flush it. Then initiate a new table.
577
str->table->nextLocator = xdr_getpos(str->xdr);
578
if (mcfioC_Wrttable(str, FLUSH) == FALSE) return -1;
579
if (mcfioC_Wrttable(str, INITIATE) == FALSE) return -1;
581
str->ehead->nBlocks = 0;
582
str->ehead->nNTuples = 0;
583
nn1 = str->ehead->evtnum;
584
if (mcfioC_WrtEvt(str, INITIATE) == FALSE) return -1;
585
str->ehead->evtnum = nn1;
586
return MCFIO_RUNNING;
590
int mcfioC_SpecificEvent(int stream, int ievt,
591
int istore, int irun, int itrig)
593
int i, jstr, idtmp, ntot, ok, nn1;
594
u_int p_evt, p1, p2, *p_ptr;
597
if (McfStreamPtrList == NULL) {
599
" mcfio_SpecificEvent: You must first initialize by calling mcfio_Init.\n");
603
if (McfStreamPtrList[jstr] == NULL) {
605
" mcfio_SpecificEvent: First, declare the stream by calling mcfio_Open...\n");
608
str = McfStreamPtrList[jstr];
609
if ((str->row != MCFIO_READ) || (str->dos == MCFIO_SEQUENTIAL)) {
611
" mcfio_SpecificEvent: Only valid for INPUT, DIRECT ACCESS \
612
or Memory Mapped \n");
615
if (xdr_setpos(str->xdr, str->fhead->firstTable) == FALSE ) {
617
" mcfio_SpecificEvent: Could not reposition Direct Access Stream %d \n",
621
str->currentPos = str->fhead->firstTable;
623
ok = mcfioC_nextspecevt(str, ievt, istore, irun, itrig);
625
mcfioC_RewindDirect(jstr);
626
if (xdr_setpos(str->xdr, str->fhead->firstTable) == FALSE ) {
628
" mcfio_SpecificEvent: Could not reposition Direct Access Stream %d \n",
632
str->currentPos = str->fhead->firstTable;
633
ok = mcfioC_nextspecevt(str, ievt, istore, irun, itrig);
635
if (ok == FALSE) return -1;
639
int mcfioC_NextSpecificEvent(int stream, int ievt,
640
int istore, int irun, int itrig)
642
int i, jstr, idtmp, ntot, ok, nn1;
643
u_int p_evt, p1, p2, *p_ptr;
646
if (McfStreamPtrList == NULL) {
648
" mcfio_NextSpecific: You must first initialize by calling mcfio_Init.\n");
652
if (McfStreamPtrList[jstr] == NULL) {
654
" mcfio_NextSpecific: First, declare the stream by calling mcfio_Open...\n");
657
str = McfStreamPtrList[jstr];
658
if ((str->row != MCFIO_READ) || (str->dos == MCFIO_SEQUENTIAL)) {
660
" mcfio_NextSpecificEvent: Only valid for INPUT, DIRECT ACCESS\
661
or memory mapped I/O \n");
664
ok = mcfioC_nextspecevt(str, ievt, istore, irun, itrig);
665
if (ok == FALSE) return -1;
671
void mcfioC_CloseDirect(int jstr)
673
** Close a direct access stream, Standard I/O or Memory Mapped
678
u_int p1, p2, *p_ptr;
683
str = McfStreamPtrList[jstr];
684
if (str->row == MCFIO_WRITE) {
686
** Flush the event header, and the last table header.
688
if (str->status == MCFIO_RUNNING) {
689
str->table->numevts++;
690
str->ehead->evtnum++;
691
if (mcfioC_WrtEvt(str, FLUSH) == FALSE) return;
692
str->table->nextLocator = -2;
693
str->table->numevts--; /* Decrement, the table is incomplete at
695
if (mcfioC_Wrttable(str, FLUSH) == FALSE) return;
696
if (mcfioC_Wrtfhead(str, FLUSH) == FALSE) return;
699
xdr_destroy(str->xdr);
700
if (str->dos == MCFIO_DIRECT) {
701
fclose(str->filePtr);
704
** Memory mapped I/O, one has to unmapped..
706
munmap((caddr_t) str->fileAddr, str->fileLen);
707
close(str->fileDescr);
710
** One must declare the Ntuples obsolete for this stream.
711
** Do not release the memory, just flag these Ntuple with an obsolete
714
for (i=0; i<NumOfNTuples; i++) {
715
ddl = mcf_GetNTuByPtrID((i+1));
716
if ((ddl != NULL) && (ddl->streamId == (jstr+1)))
721
void mcfioC_RewindDirect(int jstr)
723
** Rewind a direct access stream, open for Read only
729
str = McfStreamPtrList[jstr];
730
if (xdr_setpos(str->xdr, str->fhead->firstTable) == FALSE )
732
" mcfio_Rewind: Could not reposition Direct Access Stream %d \n",
734
str->currentPos = str->fhead->firstTable;
735
if (str->table != NULL) {
736
str->table->nextLocator = str->fhead->firstTable;
737
str->table->numevts = 0;
738
str->table->previousnumevts = 0;
740
if (str->ehead != NULL) {
741
str->ehead->evtnum = 0;
742
str->ehead->previousevtnum = 0;
747
int mcfioC_Wrtfhead(mcfStream *str, int mode)
749
** Write the file header.
750
** IF Mode = INITIATE, write the dummy information, at the current location.
751
** IF mode = Flush, rewite all the information, this time with the
752
** correct number of events.
764
strcpy(str->fhead->closingDate, ctime(&clock));
765
if(xdr_setpos(str->xdr,str->firstPos) == FALSE) return FALSE;
766
if (xdr_mcfast_fileheader(str->xdr, &idtmp,
767
&ntot, McfGenericVersion, &(str->fhead), str->id) == FALSE) {
769
"mcfio_OpenCloseDirect: Unable to reencode file head \n");
773
** The version of MCFIO is still at this point v2.0
775
} else if (mode == INITIATE) {
776
/* Put the current date/time in a string */
778
strcpy(str->fhead->date, ctime(&clock));
780
** We obviously do not have the closing times stamp yet (Causality)
781
** So we put ?, however, we have to put the right number of them,
782
** the we do not screw up the XDR pointers..
784
for (k=0; k<strlen(ctime(&clock)); k++) str->fhead->closingDate[k] = '?';
785
str->fhead->closingDate[strlen(ctime(&clock))] = '\0';
786
p0 = str->currentPos;
787
if (xdr_mcfast_fileheader(str->xdr, &idtmp,
788
&ntot, McfGenericVersion, &(str->fhead), str->id) == FALSE) {
790
"mcfio_OpenWriteDirect: Unable to encode fileheader \n");
793
p1 = xdr_getpos(str->xdr);
794
str->numWordsC += (ntot/4);
795
str->numWordsT += ((p1-p0)/4);
796
str->currentPos = p1;
799
fprintf(stderr," mcfioC_Wrtfhead: Internal error, lost mode \n");
806
int mcfioC_WrtEvt(mcfStream *str, int mode)
808
** Write an event header, and update the table. Presumably, we have room
809
** in this table to do so.
810
** IF Mode = INITIATE, write the dummy event header, at the current location.
811
** Do not fill the element table.
812
** If mode = FLUSH write the real event header and also
813
** fill the Table elements.
822
str->table->evtnums[str->table->numevts] = str->ehead->evtnum;
823
str->table->storenums[str->table->numevts] = str->ehead->storenum;
824
str->table->runnums[str->table->numevts] = str->ehead->runnum;
825
str->table->trigMasks[str->table->numevts] = str->ehead->trigMask;
826
str->table->ptrEvents[str->table->numevts] = str->evtPos;
827
p0 = str->currentPos;
828
if(xdr_setpos(str->xdr,str->evtPos) == FALSE) return FALSE;
830
if(xdr_mcfast_eventheader(str->xdr, &idtmp,
831
&ntot, McfGenericVersion, &(str->ehead)) == FALSE) return FALSE;
832
str->currentPos = xdr_getpos(str->xdr);
833
str->numWordsC += (ntot/4);
834
str->numWordsT += ((str->currentPos-p1)/4);
835
if(xdr_setpos(str->xdr,p0) == FALSE) return FALSE;
836
str->currentPos = p0;
837
str->ehead->nBlocks = 0;
838
str->ehead->nNTuples = 0;
840
} else if (mode == INITIATE) {
841
str->ehead->nBlocks = 0; /*do not initialize nNTuples, already done */
842
str->ehead->evtnum = -1;
843
str->evtPos = xdr_getpos(str->xdr);
845
if(xdr_mcfast_eventheader(str->xdr, &idtmp,
846
&ntot, McfGenericVersion, &(str->ehead)) == FALSE) return FALSE;
847
str->currentPos = xdr_getpos(str->xdr);
850
fprintf(stderr," mcfioC_WrtEvt: Internal error, lost mode \n");
855
int mcfioC_Wrttable(mcfStream *str, int mode)
857
** Write an event table.
858
** IF Mode = INITIATE, write the dummy event table, at the current location.
859
** Do not fill the element table.
860
** If mode = FLUSH write the real event header and also
861
** fill the Table elements.
869
str->table->dim = str->fhead->dimTable;
871
p0 = str->currentPos;
872
if(xdr_setpos(str->xdr,str->tablePos) == FALSE) return FALSE;
874
str->table->numevts++;
875
if(xdr_mcfast_eventtable(str->xdr, &idtmp,
876
&ntot, McfGenericVersion, &(str->table)) == FALSE) return FALSE;
877
str->currentPos = xdr_getpos(str->xdr);
878
str->numWordsC += (ntot/4);
879
str->numWordsT += ((str->currentPos-p1)/4);
880
if(xdr_setpos(str->xdr,p0) == FALSE) return FALSE;
881
str->currentPos = p0;
883
str->table->nextLocator = -1;
884
str->table->numevts=-1;
886
} else if (mode == INITIATE) {
887
str->tablePos = xdr_getpos(str->xdr);
888
str->table->nextLocator = -1;
889
if(xdr_mcfast_eventtable(str->xdr, &idtmp,
890
&ntot, McfGenericVersion, &(str->table)) == FALSE) return FALSE;
891
str->currentPos = xdr_getpos(str->xdr);
894
fprintf(stderr," mcfioC_Wrttable: Internal error, lost mode \n");
899
static int mcfioC_gofornextevent(mcfStream *str)
901
** Move in the direct access file to the next event or event table,
902
** whatever comes first. The XDR current position is set to the beginning
903
** of the event header or event table, if search sucessfull.
904
** We position the stream to the last Block or Ntuple defined in
905
** the current event.
914
p1 = xdr_getpos(str->xdr);
915
if (xdr_mcfast_headerBlock(str->xdr, &id, &ntot, McfGenericVersion)
916
== FALSE) return NOTHING;
917
if ((id == EVENTTABLE) || (id == EVENTHEADER)) {
918
str->currentPos = p1;
919
if(xdr_setpos(str->xdr, p1) == FALSE) return NOTHING;
923
return NOTHING; /* This statement is to make the compiler happy */
926
static int mcfioC_nextspecevt(mcfStream *str, int inum, int istore,
929
** For Input, Direct access streams, hunt for a psecific event
933
int i, jstr, j, idtmp, ntot, found;
934
u_int p_evt, p1, p2, *p_ptr;
936
if ((str->table == NULL) ||
937
((str->table != NULL)&& (str->table->evtnums == NULL))) {
938
idtmp = mcfioC_gofornextevent(str);
939
if (idtmp != EVENTTABLE) {
941
" mcfio_SpecificEvent: No event table on stream %d \n", str->id);
944
if( xdr_mcfast_eventtable(str->xdr, &idtmp,
945
&ntot, McfGenericVersion, &(str->table)) == FALSE) {
947
" mcfio_SpecificEvent: XDR Error decoding the EventTable \n");
950
p2 = xdr_getpos(str->xdr);
951
str->numWordsC += (ntot/4);
952
str->numWordsT += ((p2-str->currentPos)/4);
953
str->currentPos = p2;
954
str->table->ievt = 0;
956
** If table empty, cal this routine recursively to get
959
str->table->ievt = 0;
963
while (found == FALSE){
964
j = str->table->ievt;
965
if (str->table->ievt < str->table->numevts) {
967
|| ( inum != 0 && (str->table->evtnums[j] == inum))) &&
969
|| (istore != 0) && (str->table->storenums[j] == istore))) &&
971
|| (irun != 0) && (str->table->runnums[j] == irun))) &&
973
|| (itrig != 0) && (str->table->trigMasks[j] == itrig))))
975
p_evt = str->table->ptrEvents[str->table->ievt];
979
** decode the next table, if valid. If not, scrap the
980
** existing table and call next event recursively.
982
if (str->table->nextLocator == -2) {
986
str->status = MCFIO_EOF;
990
} else if (str->table->nextLocator == -1) {
992
" mcfio_NextEvent: Next EventTable corrupted, abandoning search \n");
995
if (xdr_setpos(str->xdr, str->table->nextLocator)
996
== FALSE) { fprintf(stderr,
997
" mcfio_NextEvent: XDR Error repositioning to the next EventTable \n");
1000
if( xdr_mcfast_eventtable(str->xdr, &idtmp,
1001
&ntot, McfGenericVersion, &(str->table)) == FALSE) {
1003
" mcfio_NextEvent: XDR Error decoding the EventTable \n");
1007
p2 = xdr_getpos(str->xdr);
1008
str->numWordsC += (ntot/4);
1009
str->numWordsT += ((p2-str->currentPos)/4);
1010
str->currentPos = p2;
1011
str->table->ievt = 0;
1012
p_evt = str->table->ptrEvents[0];
1015
if (found == FALSE) return FALSE;
1017
** we should be pointing to a good event header here.
1019
if (xdr_setpos(str->xdr, p_evt) == FALSE) return FALSE;
1020
if( xdr_mcfast_eventheader(str->xdr, &idtmp,
1021
&ntot, McfGenericVersion, &(str->ehead)) == FALSE) return FALSE;
1022
str->currentPos = xdr_getpos(str->xdr);
1023
str->numWordsC += (ntot/4);
1024
str->numWordsT += ((str->currentPos - p_evt)/4);
1025
return MCFIO_RUNNING;