~maddevelopers/mg5amcnlo/2.9.4

« back to all changes in this revision

Viewing changes to vendor/StdHEP/mcfio/src/mcfio_Direct.c

pass to v2.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*******************************************************************************
 
2
*                                                                              *
 
3
* mcfio_Direct.c --  Utility routines for the McFast Monte-Carlo                 *
 
4
*               Direct Access I/O core routines                                *
 
5
*                                                                              *
 
6
* Copyright (c) 1994 Universities Research Association, Inc.                   *
 
7
* All rights reserved.                                                         *
 
8
*                                                                              *
 
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.           *
 
19
*                                                                              *
 
20
*                                                                              *
 
21
* Written by Paul Lebrun                                                       *
 
22
*                                                                              *
 
23
*                                                                              *
 
24
*******************************************************************************/
 
25
#include <stdio.h>
 
26
#include <string.h>
 
27
#include <sys/param.h>
 
28
#include <rpc/types.h>
 
29
#include <sys/types.h>
 
30
#include <sys/stat.h>
 
31
#include <rpc/xdr.h>
 
32
#include <limits.h>
 
33
#include <stdlib.h>
 
34
#include <unistd.h>
 
35
#include <time.h>
 
36
#include <sys/mman.h>
 
37
#include <fcntl.h>
 
38
#ifdef SUNOS
 
39
#include <floatingpoint.h>
 
40
#else /* SUNOS */
 
41
#include <float.h>
 
42
#endif /* SUNOS */
 
43
#include "mcf_nTupleDescript.h"
 
44
#include "mcf_xdr.h"
 
45
#include "mcfio_Dict.h"
 
46
#include "mcfio_Util1.h"
 
47
#include "mcfio_Direct.h"
 
48
#include "mcf_NTuIOUtils.h"
 
49
#ifndef FALSE
 
50
#define FALSE 0
 
51
#endif
 
52
#ifndef TRUE
 
53
#define TRUE 1
 
54
#endif
 
55
#ifndef MAP_FILE 
 
56
#define MAP_FILE 0
 
57
#endif
 
58
 
 
59
extern nTuDDL **NTuDDLList;
 
60
extern int NumOfNTuples;
 
61
 
 
62
 
 
63
/* Static routine used in this module */
 
64
 
 
65
static int mcfioC_gofornextevent(mcfStream *str);   
 
66
static int  mcfioC_nextspecevt(mcfStream *str, int inum, int istore, 
 
67
                                       int irun, int itrig); 
 
68
static int openReadDirect(char*filename, int mode);
 
69
 
 
70
 
 
71
int mcfioC_OpenReadDirect(char *filename)
 
72
{                                            
 
73
/*
 
74
** Routine to open and read the header file for a Direct access Stream, 
 
75
** Standard Unix I/O 
 
76
*/
 
77
    return openReadDirect(filename, MCFIO_DIRECT);
 
78
}
 
79
 
 
80
int mcfioC_OpenReadMapped(char *filename)
 
81
{                                            
 
82
/*
 
83
** Routine to open and read the header file for a Direct access Stream, 
 
84
** Standard Unix I/O 
 
85
*/
 
86
    return openReadDirect(filename, MCFIO_MEMMAPPED);
 
87
}
 
88
 
 
89
static int openReadDirect(char *filename, int mode)
 
90
/*
 
91
** Routine to open and read the header file for a Direct access Stream.
 
92
*/
 
93
{
 
94
   int i, j, jstr, idtmp, ntot, ll1, jdRef, oldNumOfNTuples;
 
95
   int iff;
 
96
   u_int p1, p2;
 
97
   FILE *ff;
 
98
   mcfStream *str;
 
99
   nTuDDL *ddl, *ddlRef;
 
100
   struct stat statbuf;
 
101
   char *srcFile;
 
102
   
 
103
   
 
104
  if (McfStreamPtrList == NULL) mcfioC_Init(); 
 
105
   
 
106
  if (McfNumOfStreamActive >= MCF_STREAM_NUM_MAX) {
 
107
     fprintf(stderr,
 
108
  " mcfio_OpenReadDirect: Too many streams opened simultaneously.\n"); 
 
109
     return -1;
 
110
   }
 
111
   jstr = -1; i=0;
 
112
   while ((jstr == -1) && (i<MCF_STREAM_NUM_MAX)) {
 
113
          if (McfStreamPtrList[i] == NULL) jstr=i;
 
114
          i++;
 
115
          }
 
116
   if(jstr == -1) {
 
117
     fprintf(stderr,
 
118
  " mcfio_OpenReadDirect: Internal error, please report \n"); 
 
119
     return -1;
 
120
   }
 
121
   if ((filename == NULL) || (strlen(filename) > 255)) {
 
122
     fprintf(stderr,
 
123
  " mcfio_OpenReadDirect: You must give a valid UNIX filename.\n"); 
 
124
     return -1;
 
125
   }
 
126
   /*
 
127
   ** Now we can try to open this file.... 
 
128
   */
 
129
   if (mode == MCFIO_DIRECT) {
 
130
       ff = fopen(filename, "r");
 
131
       if (ff == NULL) {
 
132
           fprintf(stderr,
 
133
    " mcfio_OpenReadDirect: Problem opening file %s, message \n", filename);
 
134
           perror ("mcfio_OpenReadDirect"); 
 
135
           return -1;
 
136
       }
 
137
   } else { 
 
138
      /*
 
139
      ** Using memory mapped i/o
 
140
      */
 
141
      iff = open(filename, O_RDONLY);
 
142
          if (iff < NULL) {
 
143
          fprintf(stderr,
 
144
  " mcfio_OpenReadMapped: Problem opening file %s, message \n", filename);
 
145
          perror ("mcfio_OpenReadMapped"); 
 
146
          return -1;
 
147
      }
 
148
   }
 
149
   McfStreamPtrList[jstr] = (mcfStream *) malloc(sizeof(mcfStream));
 
150
   str = McfStreamPtrList[jstr];
 
151
   str->xdr = (XDR *) malloc(sizeof(XDR));
 
152
   str->id = jstr+1;
 
153
   str->row = MCFIO_READ;
 
154
   str->dos = mode;
 
155
   str->numWordsC = 0;
 
156
   str->numWordsT = 0;
 
157
   ll1 = strlen(filename) + 1;
 
158
   str->filename = (char *) malloc(sizeof(char) * ll1);
 
159
   strcpy(str->filename,filename);
 
160
   if (mode == MCFIO_DIRECT) {
 
161
       str->filePtr = ff;
 
162
       xdrstdio_create(str->xdr, ff, XDR_DECODE);
 
163
       str->fileDescr = 0;
 
164
       str->fileAddr = NULL;
 
165
       str->fileLen = 0; 
 
166
   } else {
 
167
      /*
 
168
      ** Use memory mapped I/O 
 
169
      */
 
170
      if (fstat(iff, &statbuf) < 0) {
 
171
          fprintf (stderr,
 
172
  " mcfio_OpenReadMapped: Problem getting file length for %s \n", filename);
 
173
          perror ("mcfio_OpenReadMapped"); 
 
174
          return -1;
 
175
      }
 
176
      if ((srcFile =
 
177
        mmap(0, statbuf.st_size, PROT_READ, MAP_FILE | MAP_SHARED, iff, 0 )) 
 
178
        == (caddr_t) -1) {
 
179
       fprintf (stderr,
 
180
  " mcfio_OpenReadMapped: Problem with memory mapping for %s \n", filename);
 
181
       perror ("mcfio_OpenReadMapped"); 
 
182
       return -1;
 
183
      }
 
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);          
 
189
   }         
 
190
   str->device = NULL;
 
191
   str->vsn = NULL;
 
192
   str->filenumber = -1;
 
193
   str->minlrec = -1;
 
194
   str->maxlrec = -1;
 
195
   str->shead = NULL;
 
196
   str->ehead = NULL;
 
197
   str->table = NULL;
 
198
   str->buffer = NULL;
 
199
   str->buffer2 = NULL;
 
200
   p1 = xdr_getpos(str->xdr);
 
201
   str->firstPos = p1;
 
202
   str->status = MCFIO_BOF;
 
203
   str->fhead = NULL;
 
204
   oldNumOfNTuples = NumOfNTuples;
 
205
   if (xdr_mcfast_fileheader(str->xdr, &idtmp,
 
206
                &ntot, McfGenericVersion, &(str->fhead), str->id) == FALSE) {
 
207
       fprintf (stderr, 
 
208
               "mcfio_OpenReadDirect: Unable to decode fileheader \n");
 
209
       mcfioC_FreeStream(&McfStreamPtrList[jstr]);
 
210
       mcfioC_Close(jstr+1);
 
211
       return -1;
 
212
   }
 
213
   if (idtmp != FILEHEADER) {
 
214
       fprintf (stderr, 
 
215
            "mcfio_OpenReadDirect: First Structure not the header \n");
 
216
      
 
217
       fprintf (stderr, 
 
218
            "                    : Further accesses probably suspicious \n");
 
219
       mcfioC_FreeStream(&McfStreamPtrList[jstr]);
 
220
       mcfioC_Close(jstr+1);
 
221
       return -1;
 
222
   }    
 
223
   p2 = xdr_getpos(str->xdr);
 
224
   str->numWordsC += (ntot/4);
 
225
   /*
 
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.
 
231
   */
 
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));
 
241
               /*
 
242
               ** back up in the linked list if need be, until we 
 
243
                ** a fully documented descriptor.
 
244
                */
 
245
               while (ddlRef->descrNtu == NULL) ddlRef = ddlRef->reference;
 
246
                 ddl->reference = ddlRef;
 
247
                      break;
 
248
             }
 
249
        }
 
250
      } else {
 
251
          if (McfNTuPleSaveDecoding == TRUE) {
 
252
             mcf_ComputeNTuOffsets(ddl);    
 
253
             mcf_ComputeNTuLengths(ddl);
 
254
          }   
 
255
      }           
 
256
   }
 
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++;
 
280
   return (jstr+1);
 
281
}
 
282
    
 
283
int mcfioC_OpenWriteDirect(char *filename, char *title, char *comment,
 
284
                           int numevts_pred, int *blkIds, u_int nBlocks)
 
285
 
 
286
/*
 
287
** Routine to open and write the header file for a Direct access Stream.
 
288
*/
 
289
{
 
290
   int i, jstr, idtmp, ntot;
 
291
   u_int p1, p2;
 
292
   FILE *ff;
 
293
   mcfStream *str;
 
294
   
 
295
  if (McfStreamPtrList == NULL) { 
 
296
     fprintf(stderr,
 
297
  " mcfio_OpenWriteDirect: We will first initialize by calling mcfio_Init.\n"); 
 
298
     mcfioC_Init();
 
299
  }
 
300
  if (McfNumOfStreamActive >= MCF_STREAM_NUM_MAX) {
 
301
     fprintf(stderr,
 
302
  " mcfio_OpenWriteDirect: Too many streams opened simultaneously.\n"); 
 
303
     return -1;
 
304
   }
 
305
   jstr = -1; i=0;
 
306
   while ((jstr == -1) && (i<MCF_STREAM_NUM_MAX)) {
 
307
          if (McfStreamPtrList[i] == NULL) jstr=i;
 
308
          i++;
 
309
          }
 
310
   if(jstr == -1) {
 
311
     fprintf(stderr,
 
312
  " mcfio_OpenWriteDirect: Internal error, please report \n"); 
 
313
     return -1;
 
314
   }
 
315
   if ((filename == NULL) || (strlen(filename) > 255)) {
 
316
     fprintf(stderr,
 
317
  " mcfio_OpenWriteDirect: You must give a valid UNIX filename.\n"); 
 
318
     return -1;
 
319
   }
 
320
   if ((title != NULL) && (strlen(title) > 255)) {
 
321
     fprintf(stderr,
 
322
  " mcfio_OpenWriteDirect: Title is too long\n"); 
 
323
     return -1;
 
324
   }
 
325
     
 
326
   if ((comment != NULL) && (strlen(comment) > 255)) {
 
327
     fprintf(stderr,
 
328
  " mcfio_OpenWriteDirect: comment is too long\n"); 
 
329
     return -1;
 
330
   }
 
331
      
 
332
   /*
 
333
   ** Now we can try to open this file.... 
 
334
   */
 
335
   ff = fopen(filename, "w");
 
336
   if (ff == NULL) {
 
337
     fprintf(stderr,
 
338
  " mcfio_OpenWriteDirect: Problem opening file %s, message \n", filename);
 
339
     perror ("mcfio_OpenWriteDirect"); 
 
340
     return -1;
 
341
   }
 
342
   McfStreamPtrList[jstr] = (mcfStream *) malloc(sizeof(mcfStream));
 
343
   str = McfStreamPtrList[jstr];
 
344
   str->xdr = (XDR *) malloc(sizeof(XDR));
 
345
   str->id = jstr+1;
 
346
   str->row = MCFIO_WRITE;
 
347
   str->dos = MCFIO_DIRECT;
 
348
   str->numWordsC = 0;
 
349
   str->numWordsT = 0;
 
350
   str->filename = (char *) malloc(sizeof(char) * ( strlen(filename) +1) );
 
351
   strcpy(str->filename,filename); 
 
352
   str->filePtr = ff;
 
353
   str->device = NULL;
 
354
   str->vsn = NULL;
 
355
   str->filenumber = -1;
 
356
   str->minlrec = -1;
 
357
   str->maxlrec = -1;
 
358
   str->shead = NULL;
 
359
   str->ehead = NULL;
 
360
   str->table = NULL;
 
361
   str->buffer = NULL;
 
362
   str->buffer2 = NULL;
 
363
   xdrstdio_create(str->xdr, ff, XDR_ENCODE);
 
364
   p1 = xdr_getpos(str->xdr);
 
365
   str->firstPos = p1;
 
366
   str->currentPos = p1;
 
367
   str->status = MCFIO_BOF;
 
368
   str->fhead = (mcfxdrFileHeader *) malloc(sizeof(mcfxdrFileHeader));
 
369
   /*
 
370
   ** Fill the file header, additional info will be written on tape
 
371
   */
 
372
   if (title == NULL) strcpy(str->fhead->title,"No Title given");
 
373
    else strcpy(str->fhead->title,title);
 
374
    
 
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;
 
379
   /* 
 
380
   ** Futur expansion : make this a tunable parameter.
 
381
   */
 
382
   str->fhead->dimTable = MCF_DEFAULT_TABLE_SIZE;
 
383
   str->fhead->firstTable = -1;
 
384
   str->fhead->nBlocks = nBlocks;
 
385
   if (nBlocks > 0) {
 
386
      str->fhead->blockIds = (int *) malloc(sizeof(int) * nBlocks);
 
387
      str->fhead->blockNames = (char**) malloc(sizeof(char *) * nBlocks);
 
388
   } else {
 
389
      str->fhead->blockIds = NULL;
 
390
      str->fhead->blockNames = NULL;
 
391
   }     
 
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]);
 
397
   }
 
398
   str->fhead->nNTuples = 0; /* Will be filled later */ 
 
399
   if (mcfioC_Wrtfhead(str, INITIATE) == FALSE){
 
400
       mcfioC_FreeStream(&McfStreamPtrList[jstr]);
 
401
       fclose(ff);
 
402
       return -1;
 
403
   }
 
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);
 
413
   /*
 
414
   ** Write the first dummy table 
 
415
   */
 
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;
 
429
   if (nBlocks > 0) {
 
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);
 
434
   } else {
 
435
       str->ehead->blockIds = NULL;
 
436
       str->ehead->ptrBlocks = NULL; 
 
437
   }       
 
438
   /*
 
439
   ** Write the first dummy event header
 
440
   */
 
441
   if (mcfioC_WrtEvt(str, INITIATE) == FALSE) return -1;
 
442
   str->ehead->evtnum = 0;
 
443
   str->status = MCFIO_RUNNING;
 
444
   McfNumOfStreamActive++;
 
445
   return (jstr+1);
 
446
 
 
447
}
 
448
 
 
449
int mcfioC_NextEvent(int stream)
 
450
/*
 
451
** The Core routine for getting or setting the next event d.s. from/to 
 
452
**  a stream. 
 
453
**
 
454
*/
 
455
{
 
456
   int i, jstr, idtmp, ntot, nn1;
 
457
   u_int p_evt, p1, p2, *p_ptr;
 
458
   mcfStream *str;
 
459
   
 
460
  if (McfStreamPtrList == NULL) { 
 
461
     fprintf(stderr,
 
462
  " mcfio_NextEvent: You must first initialize by calling mcfio_Init.\n"); 
 
463
     return -1;
 
464
  }
 
465
  jstr = stream-1;
 
466
  if (McfStreamPtrList[jstr] == NULL) { 
 
467
     fprintf(stderr,
 
468
 " mcfio_NextEvent: First, declare the stream by calling mcfio_Open...\n"); 
 
469
     return -1;
 
470
  }
 
471
  str = McfStreamPtrList[jstr];
 
472
  if (str->dos == MCFIO_SEQUENTIAL) return mcfioC_NextEventSequential(stream);
 
473
  if (str->row == MCFIO_READ) {
 
474
  /*
 
475
  ** Read the next event, hunt for either an event or a table of event
 
476
  **  if event table not available.
 
477
  */
 
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;
 
486
                 } else {
 
487
                  if( xdr_mcfast_eventtable(str->xdr, &idtmp,
 
488
                     &ntot, McfGenericVersion, &(str->table)) == FALSE) {
 
489
                           fprintf(stderr,
 
490
 " mcfio_NextEvent: XDR Error decoding the EventTable \n"); 
 
491
                            return -1;
 
492
                    }
 
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;
 
498
                    /* 
 
499
                    ** If table empty, cal this routine recursively to get 
 
500
                    **   the next event 
 
501
                    */
 
502
                    if (str->table->numevts <= 0) {
 
503
                      if (str->table->nextLocator == -1) 
 
504
                       mcfioC_Free_EventTable(&(str->table));
 
505
                       return mcfioC_NextEvent(str->id);
 
506
                    }     
 
507
                    p_evt = str->table->ptrEvents[0];
 
508
                } 
 
509
      } else {
 
510
           if (str->table->ievt < str->table->numevts) {
 
511
                 p_evt = str->table->ptrEvents[str->table->ievt];
 
512
           } else {
 
513
           /*
 
514
           ** decode the next table, if valid. If not, scrap the 
 
515
           ** existing table and call next event recursively.
 
516
           */
 
517
              if (str->table->nextLocator == -2) {
 
518
                  /* 
 
519
                  ** Stream is at EOF
 
520
                  */
 
521
                   str->status = MCFIO_EOF;
 
522
                   return MCFIO_EOF;
 
523
              } else if (str->table->nextLocator == -1) { 
 
524
                           fprintf(stderr,
 
525
 " mcfio_NextEvent: Corrupted Event Table \n"); 
 
526
                            return -1;
 
527
                }
 
528
                if (xdr_setpos(str->xdr, str->table->nextLocator) == FALSE) {
 
529
                           fprintf(stderr,
 
530
 " mcfio_NextEvent: Error Repositioning stream \n"); 
 
531
                            return -1;
 
532
                 }
 
533
                 if( xdr_mcfast_eventtable(str->xdr, &idtmp,
 
534
                     &ntot, McfGenericVersion, &(str->table)) == FALSE) {
 
535
                           fprintf(stderr,
 
536
 " mcfio_NextEvent: XDR Error decoding the EventTable \n"); 
 
537
                            return -1;
 
538
                    }
 
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];
 
545
                  }
 
546
       }
 
547
       /* 
 
548
       ** we should be pointing to a good event header here. 
 
549
       */
 
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;
 
558
  } else {
 
559
    /*
 
560
    ** Writing Code here.
 
561
    */
 
562
    str->table->numevts++;
 
563
    str->fhead->numevts++;
 
564
    if (str->ehead->previousevtnum == str->ehead->evtnum) str->ehead->evtnum++;
 
565
     /*
 
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.
 
570
     */
 
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)) {
 
574
      /*
 
575
      ** The Event table is now full. Flush it. Then initiate a new table. 
 
576
      */ 
 
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;
 
580
     }
 
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;
 
587
  }
 
588
}
 
589
 
 
590
int mcfioC_SpecificEvent(int stream, int ievt,
 
591
                             int istore, int irun, int itrig)
 
592
{
 
593
   int i, jstr, idtmp, ntot, ok, nn1;
 
594
   u_int p_evt, p1, p2, *p_ptr;
 
595
   mcfStream *str;
 
596
   
 
597
  if (McfStreamPtrList == NULL) { 
 
598
     fprintf(stderr,
 
599
  " mcfio_SpecificEvent: You must first initialize by calling mcfio_Init.\n"); 
 
600
     return -1;
 
601
  }
 
602
  jstr = stream-1;
 
603
  if (McfStreamPtrList[jstr] == NULL) { 
 
604
     fprintf(stderr,
 
605
 " mcfio_SpecificEvent: First, declare the stream by calling mcfio_Open...\n"); 
 
606
     return -1;
 
607
  }
 
608
  str = McfStreamPtrList[jstr];
 
609
  if ((str->row != MCFIO_READ) || (str->dos == MCFIO_SEQUENTIAL)) {
 
610
     fprintf(stderr,
 
611
" mcfio_SpecificEvent: Only valid for INPUT, DIRECT ACCESS \
 
612
 or Memory Mapped \n"); 
 
613
     return -1;
 
614
     }
 
615
  if (xdr_setpos(str->xdr, str->fhead->firstTable) == FALSE ) {
 
616
       fprintf(stderr,
 
617
 " mcfio_SpecificEvent:  Could not reposition Direct Access Stream %d \n",
 
618
         (jstr+1)) ;
 
619
    return -1;
 
620
   }
 
621
   str->currentPos = str->fhead->firstTable;
 
622
   
 
623
   ok = mcfioC_nextspecevt(str, ievt, istore, irun, itrig);
 
624
   if (ok == FALSE) {
 
625
      mcfioC_RewindDirect(jstr);
 
626
      if (xdr_setpos(str->xdr, str->fhead->firstTable) == FALSE ) {
 
627
           fprintf(stderr,
 
628
     " mcfio_SpecificEvent:  Could not reposition Direct Access Stream %d \n",
 
629
         (jstr+1)) ;
 
630
         return -1;
 
631
      }
 
632
      str->currentPos = str->fhead->firstTable;
 
633
      ok = mcfioC_nextspecevt(str, ievt, istore, irun, itrig);
 
634
    }
 
635
    if (ok == FALSE)   return -1;
 
636
   return ok;
 
637
    
 
638
}                                    
 
639
int mcfioC_NextSpecificEvent(int stream, int ievt,
 
640
                             int istore, int irun, int itrig)
 
641
{
 
642
   int i, jstr, idtmp, ntot, ok, nn1;
 
643
   u_int p_evt, p1, p2, *p_ptr;
 
644
   mcfStream *str;
 
645
   
 
646
  if (McfStreamPtrList == NULL) { 
 
647
     fprintf(stderr,
 
648
  " mcfio_NextSpecific: You must first initialize by calling mcfio_Init.\n"); 
 
649
     return -1;
 
650
  }
 
651
  jstr = stream-1;
 
652
  if (McfStreamPtrList[jstr] == NULL) { 
 
653
     fprintf(stderr,
 
654
 " mcfio_NextSpecific: First, declare the stream by calling mcfio_Open...\n"); 
 
655
     return -1;
 
656
  }
 
657
  str = McfStreamPtrList[jstr];
 
658
  if ((str->row != MCFIO_READ) || (str->dos == MCFIO_SEQUENTIAL)) {
 
659
     fprintf(stderr,
 
660
 " mcfio_NextSpecificEvent: Only valid for INPUT, DIRECT ACCESS\
 
661
 or memory mapped I/O  \n"); 
 
662
     return -1;
 
663
     }
 
664
   ok = mcfioC_nextspecevt(str, ievt, istore, irun, itrig);
 
665
   if (ok == FALSE) return -1;
 
666
   return ok;
 
667
    
 
668
}                                    
 
669
 
 
670
 
 
671
void mcfioC_CloseDirect(int jstr)
 
672
/*
 
673
** Close a direct access stream, Standard I/O or Memory Mapped
 
674
**
 
675
*/
 
676
{
 
677
   int i, idtmp, ntot;
 
678
   u_int p1, p2, *p_ptr;
 
679
   FILE *ff;
 
680
   mcfStream *str;
 
681
   nTuDDL *ddl;
 
682
      
 
683
   str =  McfStreamPtrList[jstr];
 
684
   if (str->row == MCFIO_WRITE) {
 
685
       /*
 
686
       **  Flush the event header, and the last table header. 
 
687
       */
 
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 
 
694
                                        this point */
 
695
         if (mcfioC_Wrttable(str, FLUSH) == FALSE) return;
 
696
         if (mcfioC_Wrtfhead(str, FLUSH) == FALSE) return;
 
697
       }
 
698
     }
 
699
     xdr_destroy(str->xdr);
 
700
     if (str->dos == MCFIO_DIRECT) { 
 
701
         fclose(str->filePtr);
 
702
     } else {
 
703
         /*
 
704
         ** Memory mapped I/O, one has to unmapped.. 
 
705
         */
 
706
         munmap((caddr_t) str->fileAddr, str->fileLen);
 
707
         close(str->fileDescr);
 
708
     }
 
709
     /*
 
710
     ** One must declare the Ntuples obsolete for this stream. 
 
711
     ** Do not release the memory, just flag these Ntuple with an obsolete 
 
712
     ** stream
 
713
     */
 
714
     for (i=0; i<NumOfNTuples; i++) {
 
715
         ddl = mcf_GetNTuByPtrID((i+1));
 
716
         if ((ddl != NULL) && (ddl->streamId == (jstr+1)))
 
717
               ddl->streamId = -1;
 
718
    }
 
719
}
 
720
       
 
721
void mcfioC_RewindDirect(int jstr)
 
722
/*
 
723
** Rewind a direct access stream, open for Read only
 
724
**
 
725
*/
 
726
{
 
727
    mcfStream *str;
 
728
    
 
729
    str =  McfStreamPtrList[jstr];
 
730
    if (xdr_setpos(str->xdr, str->fhead->firstTable) == FALSE )
 
731
       fprintf(stderr,
 
732
       " mcfio_Rewind:  Could not reposition Direct Access Stream %d \n",
 
733
         (jstr+1)) ;
 
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;
 
739
    }    
 
740
    if (str->ehead != NULL) {
 
741
        str->ehead->evtnum = 0;
 
742
        str->ehead->previousevtnum = 0;
 
743
    }
 
744
    return;
 
745
}  
 
746
   
 
747
int  mcfioC_Wrtfhead(mcfStream *str, int mode)     
 
748
/*
 
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.
 
753
**
 
754
*/
 
755
{
 
756
   int idtmp, ntot;
 
757
   u_int p1, p0;
 
758
   int k;
 
759
    time_t clock;
 
760
   
 
761
   idtmp = FILEHEADER;
 
762
   if (mode == FLUSH) {
 
763
     time(&clock);
 
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) {
 
768
       fprintf (stderr, 
 
769
               "mcfio_OpenCloseDirect: Unable to reencode file head \n");
 
770
       return FALSE;
 
771
      }
 
772
      /*
 
773
      ** The version of MCFIO is still at this point v2.0 
 
774
      */
 
775
   } else if (mode == INITIATE) {
 
776
       /* Put the current date/time in a string */
 
777
     time(&clock);
 
778
     strcpy(str->fhead->date, ctime(&clock));
 
779
     /*
 
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..
 
783
     */
 
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) {
 
789
       fprintf (stderr, 
 
790
               "mcfio_OpenWriteDirect: Unable to encode fileheader \n");
 
791
       return FALSE;
 
792
      } 
 
793
      p1 = xdr_getpos(str->xdr);
 
794
      str->numWordsC += (ntot/4);
 
795
      str->numWordsT += ((p1-p0)/4);
 
796
      str->currentPos = p1;
 
797
      return TRUE;
 
798
   } else {
 
799
     fprintf(stderr," mcfioC_Wrtfhead: Internal error, lost mode \n");
 
800
     return FALSE;
 
801
   }
 
802
   return TRUE;
 
803
}
 
804
             
 
805
   
 
806
int  mcfioC_WrtEvt(mcfStream *str, int mode)     
 
807
/*
 
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. 
 
814
**
 
815
*/
 
816
{
 
817
   int i, idtmp, ntot;
 
818
   u_int p1, p0;
 
819
   
 
820
   idtmp = EVENTHEADER;
 
821
   if (mode == FLUSH) {
 
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; 
 
829
    p1 = str->evtPos;
 
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;
 
839
    return TRUE;
 
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);
 
844
    
 
845
    if(xdr_mcfast_eventheader(str->xdr, &idtmp,
 
846
            &ntot, McfGenericVersion, &(str->ehead)) == FALSE) return FALSE;
 
847
    str->currentPos = xdr_getpos(str->xdr);
 
848
    return TRUE;
 
849
   } else {
 
850
     fprintf(stderr," mcfioC_WrtEvt: Internal error, lost mode \n");
 
851
     return FALSE;
 
852
   }
 
853
}
 
854
             
 
855
int  mcfioC_Wrttable(mcfStream *str, int mode)     
 
856
/*
 
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. 
 
862
**
 
863
*/
 
864
{
 
865
   int idtmp, ntot;
 
866
   u_int p1, p0;
 
867
   
 
868
   idtmp = EVENTTABLE;
 
869
   str->table->dim = str->fhead->dimTable;
 
870
   if (mode == FLUSH) {
 
871
    p0 = str->currentPos;
 
872
    if(xdr_setpos(str->xdr,str->tablePos) == FALSE) return FALSE; 
 
873
    p1 = str->tablePos;
 
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;
 
882
    str->tablePos = -1;
 
883
    str->table->nextLocator = -1;
 
884
    str->table->numevts=-1;
 
885
    return TRUE;
 
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);
 
892
    return TRUE;
 
893
   } else {
 
894
     fprintf(stderr," mcfioC_Wrttable: Internal error, lost mode \n");
 
895
     return FALSE;
 
896
   }
 
897
}
 
898
 
 
899
static int mcfioC_gofornextevent(mcfStream *str)   
 
900
/*
 
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. 
 
906
*/
 
907
{
 
908
   u_int p1, p2;
 
909
   int id, ntot, go;
 
910
   
 
911
   go = TRUE;
 
912
   
 
913
   while (go == TRUE) {
 
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;
 
920
         return id;
 
921
     }
 
922
   }
 
923
   return NOTHING; /* This statement is to make the compiler happy */
 
924
}  
 
925
             
 
926
static int  mcfioC_nextspecevt(mcfStream *str, int inum, int istore, 
 
927
                                       int irun, int itrig)
 
928
/*
 
929
** For Input, Direct access streams, hunt for a psecific event
 
930
**
 
931
*/  
 
932
{
 
933
   int i, jstr, j, idtmp, ntot, found;
 
934
   u_int p_evt, p1, p2, *p_ptr;
 
935
   
 
936
   if ((str->table == NULL) || 
 
937
         ((str->table != NULL)&& (str->table->evtnums == NULL))) { 
 
938
                idtmp = mcfioC_gofornextevent(str);
 
939
                if (idtmp != EVENTTABLE) {
 
940
                  fprintf(stderr,
 
941
 " mcfio_SpecificEvent: No event table on stream %d \n", str->id);
 
942
                  return FALSE;
 
943
                 } else {
 
944
                  if( xdr_mcfast_eventtable(str->xdr, &idtmp,
 
945
                     &ntot, McfGenericVersion, &(str->table)) == FALSE) {
 
946
                           fprintf(stderr,
 
947
 " mcfio_SpecificEvent: XDR Error decoding the EventTable \n"); 
 
948
                            return FALSE;
 
949
                    }
 
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;
 
955
                    /* 
 
956
                    ** If table empty, cal this routine recursively to get 
 
957
                    **   the next event 
 
958
                    */
 
959
                    str->table->ievt = 0;
 
960
                } 
 
961
      }
 
962
      found = FALSE;
 
963
      while (found == FALSE){
 
964
           j =  str->table->ievt;    
 
965
           if (str->table->ievt < str->table->numevts) {
 
966
             if (((inum == 0)
 
967
                 || ( inum != 0 && (str->table->evtnums[j] == inum))) &&
 
968
                 (((istore == 0) 
 
969
                 || (istore != 0) && (str->table->storenums[j] == istore))) &&
 
970
                 (((irun == 0) 
 
971
                 || (irun != 0) && (str->table->runnums[j] == irun))) &&
 
972
                 (((itrig == 0) 
 
973
                 || (itrig != 0) && (str->table->trigMasks[j] == itrig))))
 
974
                  found = TRUE;
 
975
                  p_evt = str->table->ptrEvents[str->table->ievt];
 
976
                  str->table->ievt++;
 
977
           } else {
 
978
           /*
 
979
           ** decode the next table, if valid. If not, scrap the 
 
980
           ** existing table and call next event recursively.
 
981
           */
 
982
              if (str->table->nextLocator == -2) {
 
983
                  /* 
 
984
                  ** Stream is at EOF
 
985
                  */
 
986
                   str->status = MCFIO_EOF;
 
987
                   
 
988
                   return FALSE;
 
989
                   
 
990
              } else  if (str->table->nextLocator == -1) {
 
991
                           fprintf(stderr,
 
992
 " mcfio_NextEvent: Next EventTable corrupted, abandoning search \n"); 
 
993
                            return FALSE;
 
994
              }
 
995
              if (xdr_setpos(str->xdr, str->table->nextLocator)
 
996
                      == FALSE) { fprintf(stderr,
 
997
 " mcfio_NextEvent: XDR Error repositioning to the next EventTable \n"); 
 
998
                            return FALSE;
 
999
              } else  {
 
1000
                     if( xdr_mcfast_eventtable(str->xdr, &idtmp,
 
1001
                     &ntot, McfGenericVersion, &(str->table)) == FALSE) {
 
1002
                           fprintf(stderr,
 
1003
 " mcfio_NextEvent: XDR Error decoding the EventTable \n"); 
 
1004
                            return FALSE;
 
1005
                    }
 
1006
               }
 
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];
 
1013
           }
 
1014
       }
 
1015
       if (found == FALSE) return FALSE;
 
1016
       /* 
 
1017
       ** we should be pointing to a good event header here. 
 
1018
       */
 
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;
 
1026
        
 
1027
}