source: trunk/mcfio/mcfio_Direct.c@ 4

Last change on this file since 4 was 2, checked in by Pavel Demin, 16 years ago

first commit

File size: 33.6 KB
Line 
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 "mcfio_Sequential.h"
49#include "mcf_NTuIOFiles.h"
50#include "mcf_NTuIOUtils.h"
51#ifndef FALSE
52#define FALSE 0
53#endif
54#ifndef TRUE
55#define TRUE 1
56#endif
57#ifndef MAP_FILE
58#define MAP_FILE 0
59#endif
60
61extern nTuDDL **NTuDDLList;
62extern int NumOfNTuples;
63
64
65/* Static routine used in this module */
66
67static int mcfioC_gofornextevent(mcfStream *str);
68static int mcfioC_nextspecevt(mcfStream *str, int inum, int istore,
69 int irun, int itrig);
70static int openReadDirect(char*filename, int mode);
71
72
73int mcfioC_OpenReadDirect(char *filename)
74{
75/*
76** Routine to open and read the header file for a Direct access Stream,
77** Standard Unix I/O
78*/
79 return openReadDirect(filename, MCFIO_DIRECT);
80}
81
82int mcfioC_OpenReadMapped(char *filename)
83{
84/*
85** Routine to open and read the header file for a Direct access Stream,
86** Standard Unix I/O
87*/
88 return openReadDirect(filename, MCFIO_MEMMAPPED);
89}
90
91static int openReadDirect(char *filename, int mode)
92/*
93** Routine to open and read the header file for a Direct access Stream.
94*/
95{
96 int i, j, jstr, idtmp, ntot, ll1, jdRef, oldNumOfNTuples;
97 int iff;
98 u_int p1, p2;
99 FILE *ff;
100 mcfStream *str;
101 nTuDDL *ddl, *ddlRef;
102 struct stat statbuf;
103 char *srcFile;
104
105
106 if (McfStreamPtrList == NULL) mcfioC_Init();
107
108 if (McfNumOfStreamActive >= MCF_STREAM_NUM_MAX) {
109 fprintf(stderr,
110 " mcfio_OpenReadDirect: Too many streams opened simultaneously.\n");
111 return -1;
112 }
113 jstr = -1; i=0;
114 while ((jstr == -1) && (i<MCF_STREAM_NUM_MAX)) {
115 if (McfStreamPtrList[i] == NULL) jstr=i;
116 i++;
117 }
118 if(jstr == -1) {
119 fprintf(stderr,
120 " mcfio_OpenReadDirect: Internal error, please report \n");
121 return -1;
122 }
123 if ((filename == NULL) || (strlen(filename) > 255)) {
124 fprintf(stderr,
125 " mcfio_OpenReadDirect: You must give a valid UNIX filename.\n");
126 return -1;
127 }
128 /*
129 ** Now we can try to open this file....
130 */
131 if (mode == MCFIO_DIRECT) {
132 ff = fopen(filename, "r");
133 if (ff == NULL) {
134 fprintf(stderr,
135 " mcfio_OpenReadDirect: Problem opening file %s, message \n", filename);
136 perror ("mcfio_OpenReadDirect");
137 return -1;
138 }
139 } else {
140 /*
141 ** Using memory mapped i/o
142 */
143 iff = open(filename, O_RDONLY);
144 if (iff < 0) {
145 fprintf(stderr,
146 " mcfio_OpenReadMapped: Problem opening file %s, message \n", filename);
147 perror ("mcfio_OpenReadMapped");
148 return -1;
149 }
150 }
151 McfStreamPtrList[jstr] = (mcfStream *) malloc(sizeof(mcfStream));
152 str = McfStreamPtrList[jstr];
153 str->xdr = (XDR *) malloc(sizeof(XDR));
154 str->id = jstr+1;
155 str->row = MCFIO_READ;
156 str->dos = mode;
157 str->numWordsC = 0;
158 str->numWordsT = 0;
159 ll1 = strlen(filename) + 1;
160 str->filename = (char *) malloc(sizeof(char) * ll1);
161 strcpy(str->filename,filename);
162 if (mode == MCFIO_DIRECT) {
163 str->filePtr = ff;
164 xdrstdio_create(str->xdr, ff, XDR_DECODE);
165 str->fileDescr = 0;
166 str->fileAddr = NULL;
167 str->fileLen = 0;
168 } else {
169 /*
170 ** Use memory mapped I/O
171 */
172 if (fstat(iff, &statbuf) < 0) {
173 fprintf (stderr,
174 " mcfio_OpenReadMapped: Problem getting file length for %s \n", filename);
175 perror ("mcfio_OpenReadMapped");
176 return -1;
177 }
178 if ((srcFile =
179 mmap(0, statbuf.st_size, PROT_READ, MAP_FILE | MAP_SHARED, iff, 0 ))
180 == (caddr_t) -1) {
181 fprintf (stderr,
182 " mcfio_OpenReadMapped: Problem with memory mapping for %s \n", filename);
183 perror ("mcfio_OpenReadMapped");
184 return -1;
185 }
186 str->filePtr = (FILE *) NULL;
187 str->fileDescr = iff;
188 str->fileAddr = srcFile;
189 str->fileLen = (size_t) statbuf.st_size;
190 xdrmem_create(str->xdr, srcFile, statbuf.st_size, XDR_DECODE);
191 }
192 str->device = NULL;
193 str->vsn = NULL;
194 str->filenumber = -1;
195 str->minlrec = -1;
196 str->maxlrec = -1;
197 str->shead = NULL;
198 str->ehead = NULL;
199 str->table = NULL;
200 str->buffer = NULL;
201 str->buffer2 = NULL;
202 p1 = xdr_getpos(str->xdr);
203 str->firstPos = p1;
204 str->status = MCFIO_BOF;
205 str->fhead = NULL;
206 oldNumOfNTuples = NumOfNTuples;
207 if (xdr_mcfast_fileheader(str->xdr, &idtmp,
208 &ntot, McfGenericVersion, &(str->fhead), str->id) == FALSE) {
209 fprintf (stderr,
210 "mcfio_OpenReadDirect: Unable to decode fileheader \n");
211 mcfioC_FreeStream(&McfStreamPtrList[jstr]);
212 mcfioC_Close(jstr+1);
213 return -1;
214 }
215 if (idtmp != FILEHEADER) {
216 fprintf (stderr,
217 "mcfio_OpenReadDirect: First Structure not the header \n");
218
219 fprintf (stderr,
220 " : Further accesses probably suspicious \n");
221 mcfioC_FreeStream(&McfStreamPtrList[jstr]);
222 mcfioC_Close(jstr+1);
223 return -1;
224 }
225 p2 = xdr_getpos(str->xdr);
226 str->numWordsC += (ntot/4);
227 /*
228 ** Check if new these Ntuple template are not reference, if so,
229 ** set the reference pointer accordingly, conversely, recompute the
230 ** offsets and length if requested. We also fill the sequential
231 ** id number for the descriptors. Note: those are trivial for
232 ** input streams, but we still fill them for consitency.
233 */
234 for (i=0; i<str->fhead->nNTuples; i++) {
235 ddl = mcf_GetNTuByPtrID((oldNumOfNTuples+i+1));
236 if (ddl == NULL) continue;
237 ddl->streamId = (jstr+1);
238 ddl->seqNTuId = (i+1);
239 if (ddl->descrNtu == NULL) {
240 for (j=0, jdRef=1; j<i; j++, jdRef++) {
241 if (jdRef == ddl->referenceId) {
242 ddlRef = mcf_GetNTuByPtrID((oldNumOfNTuples+j+1));
243 /*
244 ** back up in the linked list if need be, until we
245 ** a fully documented descriptor.
246 */
247 while (ddlRef->descrNtu == NULL) ddlRef = ddlRef->reference;
248 ddl->reference = ddlRef;
249 break;
250 }
251 }
252 } else {
253 if (McfNTuPleSaveDecoding == TRUE) {
254 mcf_ComputeNTuOffsets(ddl);
255 mcf_ComputeNTuLengths(ddl);
256 }
257 }
258 }
259 str->currentPos = p2;
260 str->fhead->firstTable = p2;
261 /* presumably correct , assume standard direct acces file config. */
262 str->numWordsT += ((p2-p1)/4);
263 str->status = MCFIO_RUNNING;
264 str->table = (mcfxdrEventTable *) malloc(sizeof(mcfxdrEventTable));
265 str->table->nextLocator = -1;
266 str->table->dim = str->fhead->dimTable;
267 str->table->numevts = 0;
268 str->table->previousnumevts = 0;
269 str->table->evtnums = NULL;
270 str->table->storenums = NULL;
271 str->table->runnums = NULL;
272 str->table->trigMasks = NULL;
273 str->table->ptrEvents = NULL;
274 str->ehead = (mcfxdrEventHeader *) malloc(sizeof(mcfxdrEventHeader));
275 str->ehead->dimBlocks = str->fhead->nBlocks;
276 str->ehead->blockIds = NULL;
277 str->ehead->ptrBlocks = NULL;
278 str->ehead->dimNTuples = str->fhead->nNTuples;
279 str->ehead->nTupleIds = NULL;
280 str->ehead->ptrNTuples = NULL;
281 McfNumOfStreamActive++;
282 return (jstr+1);
283}
284
285int mcfioC_OpenWriteDirect(char *filename, char *title, char *comment,
286 int numevts_pred, int *blkIds, u_int nBlocks)
287
288/*
289** Routine to open and write the header file for a Direct access Stream.
290*/
291{
292 int i, jstr;
293 u_int p1;
294 FILE *ff;
295 mcfStream *str;
296
297 if (McfStreamPtrList == NULL) {
298 fprintf(stderr,
299 " mcfio_OpenWriteDirect: We will first initialize by calling mcfio_Init.\n");
300 mcfioC_Init();
301 }
302 if (McfNumOfStreamActive >= MCF_STREAM_NUM_MAX) {
303 fprintf(stderr,
304 " mcfio_OpenWriteDirect: Too many streams opened simultaneously.\n");
305 return -1;
306 }
307 jstr = -1; i=0;
308 while ((jstr == -1) && (i<MCF_STREAM_NUM_MAX)) {
309 if (McfStreamPtrList[i] == NULL) jstr=i;
310 i++;
311 }
312 if(jstr == -1) {
313 fprintf(stderr,
314 " mcfio_OpenWriteDirect: Internal error, please report \n");
315 return -1;
316 }
317 if ((filename == NULL) || (strlen(filename) > 255)) {
318 fprintf(stderr,
319 " mcfio_OpenWriteDirect: You must give a valid UNIX filename.\n");
320 return -1;
321 }
322 if ((title != NULL) && (strlen(title) > 255)) {
323 fprintf(stderr,
324 " mcfio_OpenWriteDirect: Title is too long\n");
325 return -1;
326 }
327
328 if ((comment != NULL) && (strlen(comment) > 255)) {
329 fprintf(stderr,
330 " mcfio_OpenWriteDirect: comment is too long\n");
331 return -1;
332 }
333
334 /*
335 ** Now we can try to open this file....
336 */
337 ff = fopen(filename, "w");
338 if (ff == NULL) {
339 fprintf(stderr,
340 " mcfio_OpenWriteDirect: Problem opening file %s, message \n", filename);
341 perror ("mcfio_OpenWriteDirect");
342 return -1;
343 }
344 McfStreamPtrList[jstr] = (mcfStream *) malloc(sizeof(mcfStream));
345 str = McfStreamPtrList[jstr];
346 str->xdr = (XDR *) malloc(sizeof(XDR));
347 str->id = jstr+1;
348 str->row = MCFIO_WRITE;
349 str->dos = MCFIO_DIRECT;
350 str->numWordsC = 0;
351 str->numWordsT = 0;
352 str->filename = (char *) malloc(sizeof(char) * ( strlen(filename) +1) );
353 strcpy(str->filename,filename);
354 str->filePtr = ff;
355 str->device = NULL;
356 str->vsn = NULL;
357 str->filenumber = -1;
358 str->minlrec = -1;
359 str->maxlrec = -1;
360 str->shead = NULL;
361 str->ehead = NULL;
362 str->table = NULL;
363 str->buffer = NULL;
364 str->buffer2 = NULL;
365 xdrstdio_create(str->xdr, ff, XDR_ENCODE);
366 p1 = xdr_getpos(str->xdr);
367 str->firstPos = p1;
368 str->currentPos = p1;
369 str->status = MCFIO_BOF;
370 str->fhead = (mcfxdrFileHeader *) malloc(sizeof(mcfxdrFileHeader));
371 /*
372 ** Fill the file header, additional info will be written on tape
373 */
374 if (title == NULL) strcpy(str->fhead->title,"No Title given");
375 else strcpy(str->fhead->title,title);
376
377 if (comment == NULL) strcpy(str->fhead->comment,"No comment");
378 else strcpy(str->fhead->comment, comment);
379 str->fhead->numevts_expect = numevts_pred;
380 str->fhead->numevts = 0;
381 /*
382 ** Futur expansion : make this a tunable parameter.
383 */
384 str->fhead->dimTable = MCF_DEFAULT_TABLE_SIZE;
385 str->fhead->firstTable = -1;
386 str->fhead->nBlocks = nBlocks;
387 if (nBlocks > 0) {
388 str->fhead->blockIds = (int *) malloc(sizeof(int) * nBlocks);
389 str->fhead->blockNames = (char**) malloc(sizeof(char *) * nBlocks);
390 } else {
391 str->fhead->blockIds = NULL;
392 str->fhead->blockNames = NULL;
393 }
394 for (i=0; i<nBlocks; i++) {
395 str->fhead->blockIds[i] = blkIds[i];
396 str->fhead->blockNames[i] =
397 (char *) malloc(sizeof(char) * (MCF_XDR_B_TITLE_LENGTH + 1));
398 mcfioC_GetBlockName(blkIds[i], str->fhead->blockNames[i]);
399 }
400 str->fhead->nNTuples = 0; /* Will be filled later */
401 if (mcfioC_Wrtfhead(str, INITIATE) == FALSE){
402 mcfioC_FreeStream(&McfStreamPtrList[jstr]);
403 fclose(ff);
404 return -1;
405 }
406 str->table = (mcfxdrEventTable *) malloc(sizeof(mcfxdrEventTable));
407 str->table->numevts=-1;
408 str->table->nextLocator = -1;
409 str->table->evtnums = (int *) malloc(sizeof(int) * str->fhead->dimTable);
410 str->table->storenums = (int *) malloc(sizeof(int) * str->fhead->dimTable);
411 str->table->runnums = (int *) malloc(sizeof(int) * str->fhead->dimTable);
412 str->table->trigMasks = (int *) malloc(sizeof(int) * str->fhead->dimTable);
413 str->table->ptrEvents =
414 (u_int *) malloc(sizeof(int) * str->fhead->dimTable);
415 /*
416 ** Write the first dummy table
417 */
418 if (mcfioC_Wrttable(str, INITIATE) == FALSE) return -1;
419 str->ehead = (mcfxdrEventHeader *) malloc(sizeof(mcfxdrEventHeader));
420 str->ehead->dimBlocks = str->fhead->nBlocks;
421 str->ehead->nBlocks = 0;
422 str->ehead->dimNTuples = 0;
423 str->ehead->nNTuples = 0;
424 str->ehead->evtnum = 0;
425 str->ehead->previousevtnum = 0;
426 str->ehead->storenum = 0;
427 str->ehead->runnum = 0;
428 str->ehead->trigMask = 0;
429 str->ehead->nTupleIds = NULL;
430 str->ehead->ptrNTuples = NULL;
431 if (nBlocks > 0) {
432 str->ehead->blockIds =
433 (int *) malloc(sizeof(int) * str->fhead->nBlocks);
434 str->ehead->ptrBlocks =
435 (u_int *) malloc(sizeof(int) * str->fhead->nBlocks);
436 } else {
437 str->ehead->blockIds = NULL;
438 str->ehead->ptrBlocks = NULL;
439 }
440 /*
441 ** Write the first dummy event header
442 */
443 if (mcfioC_WrtEvt(str, INITIATE) == FALSE) return -1;
444 str->ehead->evtnum = 0;
445 str->status = MCFIO_RUNNING;
446 McfNumOfStreamActive++;
447 return (jstr+1);
448
449}
450
451int mcfioC_NextEvent(int stream)
452/*
453** The Core routine for getting or setting the next event d.s. from/to
454** a stream.
455**
456*/
457{
458 int jstr, idtmp, ntot, nn1;
459 u_int p_evt, p2;
460 mcfStream *str;
461
462 if (McfStreamPtrList == NULL) {
463 fprintf(stderr,
464 " mcfio_NextEvent: You must first initialize by calling mcfio_Init.\n");
465 return -1;
466 }
467 jstr = stream-1;
468 if (McfStreamPtrList[jstr] == NULL) {
469 fprintf(stderr,
470 " mcfio_NextEvent: First, declare the stream by calling mcfio_Open...\n");
471 return -1;
472 }
473 str = McfStreamPtrList[jstr];
474 if (str->dos == MCFIO_SEQUENTIAL) return mcfioC_NextEventSequential(stream);
475 if (str->row == MCFIO_READ) {
476 /*
477 ** Read the next event, hunt for either an event or a table of event
478 ** if event table not available.
479 */
480 if ((str->table == NULL) ||
481 ((str->table != NULL)&& (str->table->evtnums == NULL))) {
482 idtmp = mcfioC_gofornextevent(str);
483 if (idtmp != EVENTTABLE) {
484 if (str->table !=NULL)
485 mcfioC_Free_EventTable(&(str->table));
486 if (idtmp == NOTHING) return -1;
487 p_evt = str->currentPos;
488 } else {
489 if( xdr_mcfast_eventtable(str->xdr, &idtmp,
490 &ntot, McfGenericVersion, &(str->table)) == FALSE) {
491 fprintf(stderr,
492 " mcfio_NextEvent: XDR Error decoding the EventTable \n");
493 return -1;
494 }
495 p2 = xdr_getpos(str->xdr);
496 str->numWordsC += (ntot/4);
497 str->numWordsT += ((p2-str->currentPos)/4);
498 str->currentPos = p2;
499 str->table->ievt = 0;
500 /*
501 ** If table empty, cal this routine recursively to get
502 ** the next event
503 */
504 if (str->table->numevts <= 0) {
505 if (str->table->nextLocator == -1)
506 mcfioC_Free_EventTable(&(str->table));
507 return mcfioC_NextEvent(str->id);
508 }
509 p_evt = str->table->ptrEvents[0];
510 }
511 } else {
512 if (str->table->ievt < str->table->numevts) {
513 p_evt = str->table->ptrEvents[str->table->ievt];
514 } else {
515 /*
516 ** decode the next table, if valid. If not, scrap the
517 ** existing table and call next event recursively.
518 */
519 if (str->table->nextLocator == -2) {
520 /*
521 ** Stream is at EOF
522 */
523 str->status = MCFIO_EOF;
524 return MCFIO_EOF;
525 } else if (str->table->nextLocator == -1) {
526 fprintf(stderr,
527 " mcfio_NextEvent: Corrupted Event Table \n");
528 return -1;
529 }
530 if (xdr_setpos(str->xdr, str->table->nextLocator) == FALSE) {
531 fprintf(stderr,
532 " mcfio_NextEvent: Error Repositioning stream \n");
533 return -1;
534 }
535 if( xdr_mcfast_eventtable(str->xdr, &idtmp,
536 &ntot, McfGenericVersion, &(str->table)) == FALSE) {
537 fprintf(stderr,
538 " mcfio_NextEvent: XDR Error decoding the EventTable \n");
539 return -1;
540 }
541 p2 = xdr_getpos(str->xdr);
542 str->numWordsC += (ntot/4);
543 str->numWordsT += ((p2-str->currentPos)/4);
544 str->currentPos = p2;
545 str->table->ievt = 0;
546 p_evt = str->table->ptrEvents[0];
547 }
548 }
549 /*
550 ** we should be pointing to a good event header here.
551 */
552 if (xdr_setpos(str->xdr, p_evt) == FALSE) return -1;
553 if( xdr_mcfast_eventheader(str->xdr, &idtmp,
554 &ntot, McfGenericVersion, &(str->ehead)) == FALSE) return -1;
555 str->currentPos = xdr_getpos(str->xdr);
556 str->numWordsC += (ntot/4);
557 str->numWordsT += ((str->currentPos - p_evt)/4);
558 if (str->table != NULL) str->table->ievt ++;
559 return MCFIO_RUNNING;
560 } else {
561 /*
562 ** Writing Code here.
563 */
564 str->table->numevts++;
565 str->fhead->numevts++;
566 if (str->ehead->previousevtnum == str->ehead->evtnum) str->ehead->evtnum++;
567 /*
568 ** Write the current event header, normal case. First Flush the current
569 ** event, then initiate the next one event. Note that wrtevt will
570 ** reposition the stream after rewriting the event header, if FLUSH.
571 ** e.g. ready to initiate either a new table or a new event.
572 */
573 if (mcfioC_WrtEvt(str, FLUSH) == FALSE) return -1;
574 str->ehead->previousevtnum = str->ehead->evtnum;
575 if (str->table->numevts == (str->fhead->dimTable - 1)) {
576 /*
577 ** The Event table is now full. Flush it. Then initiate a new table.
578 */
579 str->table->nextLocator = xdr_getpos(str->xdr);
580 if (mcfioC_Wrttable(str, FLUSH) == FALSE) return -1;
581 if (mcfioC_Wrttable(str, INITIATE) == FALSE) return -1;
582 }
583 str->ehead->nBlocks = 0;
584 str->ehead->nNTuples = 0;
585 nn1 = str->ehead->evtnum;
586 if (mcfioC_WrtEvt(str, INITIATE) == FALSE) return -1;
587 str->ehead->evtnum = nn1;
588 return MCFIO_RUNNING;
589 }
590}
591
592int mcfioC_SpecificEvent(int stream, int ievt,
593 int istore, int irun, int itrig)
594{
595 int jstr, ok;
596 mcfStream *str;
597
598 if (McfStreamPtrList == NULL) {
599 fprintf(stderr,
600 " mcfio_SpecificEvent: You must first initialize by calling mcfio_Init.\n");
601 return -1;
602 }
603 jstr = stream-1;
604 if (McfStreamPtrList[jstr] == NULL) {
605 fprintf(stderr,
606 " mcfio_SpecificEvent: First, declare the stream by calling mcfio_Open...\n");
607 return -1;
608 }
609 str = McfStreamPtrList[jstr];
610 if ((str->row != MCFIO_READ) || (str->dos == MCFIO_SEQUENTIAL)) {
611 fprintf(stderr,
612" mcfio_SpecificEvent: Only valid for INPUT, DIRECT ACCESS \
613 or Memory Mapped \n");
614 return -1;
615 }
616 if (xdr_setpos(str->xdr, str->fhead->firstTable) == FALSE ) {
617 fprintf(stderr,
618 " mcfio_SpecificEvent: Could not reposition Direct Access Stream %d \n",
619 (jstr+1)) ;
620 return -1;
621 }
622 str->currentPos = str->fhead->firstTable;
623
624 ok = mcfioC_nextspecevt(str, ievt, istore, irun, itrig);
625 if (ok == FALSE) {
626 mcfioC_RewindDirect(jstr);
627 if (xdr_setpos(str->xdr, str->fhead->firstTable) == FALSE ) {
628 fprintf(stderr,
629 " mcfio_SpecificEvent: Could not reposition Direct Access Stream %d \n",
630 (jstr+1)) ;
631 return -1;
632 }
633 str->currentPos = str->fhead->firstTable;
634 ok = mcfioC_nextspecevt(str, ievt, istore, irun, itrig);
635 }
636 if (ok == FALSE) return -1;
637 return ok;
638
639}
640int mcfioC_NextSpecificEvent(int stream, int ievt,
641 int istore, int irun, int itrig)
642{
643 int jstr, ok;
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
671void mcfioC_CloseDirect(int jstr)
672/*
673** Close a direct access stream, Standard I/O or Memory Mapped
674**
675*/
676{
677 int i;
678 mcfStream *str;
679 nTuDDL *ddl;
680
681 str = McfStreamPtrList[jstr];
682 if (str->row == MCFIO_WRITE) {
683 /*
684 ** Flush the event header, and the last table header.
685 */
686 if (str->status == MCFIO_RUNNING) {
687 str->table->numevts++;
688 str->ehead->evtnum++;
689 if (mcfioC_WrtEvt(str, FLUSH) == FALSE) return;
690 str->table->nextLocator = -2;
691 str->table->numevts--; /* Decrement, the table is incomplete at
692 this point */
693 if (mcfioC_Wrttable(str, FLUSH) == FALSE) return;
694 if (mcfioC_Wrtfhead(str, FLUSH) == FALSE) return;
695 }
696 }
697 xdr_destroy(str->xdr);
698 if (str->dos == MCFIO_DIRECT) {
699 fclose(str->filePtr);
700 } else {
701 /*
702 ** Memory mapped I/O, one has to unmapped..
703 */
704 munmap((caddr_t) str->fileAddr, str->fileLen);
705 close(str->fileDescr);
706 }
707 /*
708 ** One must declare the Ntuples obsolete for this stream.
709 ** Do not release the memory, just flag these Ntuple with an obsolete
710 ** stream
711 */
712 for (i=0; i<NumOfNTuples; i++) {
713 ddl = mcf_GetNTuByPtrID((i+1));
714 if ((ddl != NULL) && (ddl->streamId == (jstr+1)))
715 ddl->streamId = -1;
716 }
717}
718
719void mcfioC_RewindDirect(int jstr)
720/*
721** Rewind a direct access stream, open for Read only
722**
723*/
724{
725 mcfStream *str;
726
727 str = McfStreamPtrList[jstr];
728 if (xdr_setpos(str->xdr, str->fhead->firstTable) == FALSE )
729 fprintf(stderr,
730 " mcfio_Rewind: Could not reposition Direct Access Stream %d \n",
731 (jstr+1)) ;
732 str->currentPos = str->fhead->firstTable;
733 if (str->table != NULL) {
734 str->table->nextLocator = str->fhead->firstTable;
735 str->table->numevts = 0;
736 str->table->previousnumevts = 0;
737 }
738 if (str->ehead != NULL) {
739 str->ehead->evtnum = 0;
740 str->ehead->previousevtnum = 0;
741 }
742 return;
743}
744
745int mcfioC_Wrtfhead(mcfStream *str, int mode)
746/*
747** Write the file header.
748** IF Mode = INITIATE, write the dummy information, at the current location.
749** IF mode = Flush, rewite all the information, this time with the
750** correct number of events.
751**
752*/
753{
754 int idtmp, ntot;
755 u_int p1, p0;
756 int k;
757 time_t clock;
758
759 idtmp = FILEHEADER;
760 if (mode == FLUSH) {
761 time(&clock);
762 strcpy(str->fhead->closingDate, ctime(&clock));
763 if(xdr_setpos(str->xdr,str->firstPos) == FALSE) return FALSE;
764 if (xdr_mcfast_fileheader(str->xdr, &idtmp,
765 &ntot, McfGenericVersion, &(str->fhead), str->id) == FALSE) {
766 fprintf (stderr,
767 "mcfio_OpenCloseDirect: Unable to reencode file head \n");
768 return FALSE;
769 }
770 /*
771 ** The version of MCFIO is still at this point v2.0
772 */
773 } else if (mode == INITIATE) {
774 /* Put the current date/time in a string */
775 time(&clock);
776 strcpy(str->fhead->date, ctime(&clock));
777 /*
778 ** We obviously do not have the closing times stamp yet (Causality)
779 ** So we put ?, however, we have to put the right number of them,
780 ** the we do not screw up the XDR pointers..
781 */
782 for (k=0; k<strlen(ctime(&clock)); k++) str->fhead->closingDate[k] = '?';
783 str->fhead->closingDate[strlen(ctime(&clock))] = '\0';
784 p0 = str->currentPos;
785 if (xdr_mcfast_fileheader(str->xdr, &idtmp,
786 &ntot, McfGenericVersion, &(str->fhead), str->id) == FALSE) {
787 fprintf (stderr,
788 "mcfio_OpenWriteDirect: Unable to encode fileheader \n");
789 return FALSE;
790 }
791 p1 = xdr_getpos(str->xdr);
792 str->numWordsC += (ntot/4);
793 str->numWordsT += ((p1-p0)/4);
794 str->currentPos = p1;
795 return TRUE;
796 } else {
797 fprintf(stderr," mcfioC_Wrtfhead: Internal error, lost mode \n");
798 return FALSE;
799 }
800 return TRUE;
801}
802
803
804int mcfioC_WrtEvt(mcfStream *str, int mode)
805/*
806** Write an event header, and update the table. Presumably, we have room
807** in this table to do so.
808** IF Mode = INITIATE, write the dummy event header, at the current location.
809** Do not fill the element table.
810** If mode = FLUSH write the real event header and also
811** fill the Table elements.
812**
813*/
814{
815 int idtmp, ntot;
816 u_int p1, p0;
817
818 idtmp = EVENTHEADER;
819 if (mode == FLUSH) {
820 str->table->evtnums[str->table->numevts] = str->ehead->evtnum;
821 str->table->storenums[str->table->numevts] = str->ehead->storenum;
822 str->table->runnums[str->table->numevts] = str->ehead->runnum;
823 str->table->trigMasks[str->table->numevts] = str->ehead->trigMask;
824 str->table->ptrEvents[str->table->numevts] = str->evtPos;
825 p0 = str->currentPos;
826 if(xdr_setpos(str->xdr,str->evtPos) == FALSE) return FALSE;
827 p1 = str->evtPos;
828 if(xdr_mcfast_eventheader(str->xdr, &idtmp,
829 &ntot, McfGenericVersion, &(str->ehead)) == FALSE) return FALSE;
830 str->currentPos = xdr_getpos(str->xdr);
831 str->numWordsC += (ntot/4);
832 str->numWordsT += ((str->currentPos-p1)/4);
833 if(xdr_setpos(str->xdr,p0) == FALSE) return FALSE;
834 str->currentPos = p0;
835 str->ehead->nBlocks = 0;
836 str->ehead->nNTuples = 0;
837 return TRUE;
838 } else if (mode == INITIATE) {
839 str->ehead->nBlocks = 0; /*do not initialize nNTuples, already done */
840 str->ehead->evtnum = -1;
841 str->evtPos = xdr_getpos(str->xdr);
842
843 if(xdr_mcfast_eventheader(str->xdr, &idtmp,
844 &ntot, McfGenericVersion, &(str->ehead)) == FALSE) return FALSE;
845 str->currentPos = xdr_getpos(str->xdr);
846 return TRUE;
847 } else {
848 fprintf(stderr," mcfioC_WrtEvt: Internal error, lost mode \n");
849 return FALSE;
850 }
851}
852
853int mcfioC_Wrttable(mcfStream *str, int mode)
854/*
855** Write an event table.
856** IF Mode = INITIATE, write the dummy event table, at the current location.
857** Do not fill the element table.
858** If mode = FLUSH write the real event header and also
859** fill the Table elements.
860**
861*/
862{
863 int idtmp, ntot;
864 u_int p1, p0;
865
866 idtmp = EVENTTABLE;
867 str->table->dim = str->fhead->dimTable;
868 if (mode == FLUSH) {
869 p0 = str->currentPos;
870 if(xdr_setpos(str->xdr,str->tablePos) == FALSE) return FALSE;
871 p1 = str->tablePos;
872 str->table->numevts++;
873 if(xdr_mcfast_eventtable(str->xdr, &idtmp,
874 &ntot, McfGenericVersion, &(str->table)) == FALSE) return FALSE;
875 str->currentPos = xdr_getpos(str->xdr);
876 str->numWordsC += (ntot/4);
877 str->numWordsT += ((str->currentPos-p1)/4);
878 if(xdr_setpos(str->xdr,p0) == FALSE) return FALSE;
879 str->currentPos = p0;
880 str->tablePos = -1;
881 str->table->nextLocator = -1;
882 str->table->numevts=-1;
883 return TRUE;
884 } else if (mode == INITIATE) {
885 str->tablePos = xdr_getpos(str->xdr);
886 str->table->nextLocator = -1;
887 if(xdr_mcfast_eventtable(str->xdr, &idtmp,
888 &ntot, McfGenericVersion, &(str->table)) == FALSE) return FALSE;
889 str->currentPos = xdr_getpos(str->xdr);
890 return TRUE;
891 } else {
892 fprintf(stderr," mcfioC_Wrttable: Internal error, lost mode \n");
893 return FALSE;
894 }
895}
896
897static int mcfioC_gofornextevent(mcfStream *str)
898/*
899** Move in the direct access file to the next event or event table,
900** whatever comes first. The XDR current position is set to the beginning
901** of the event header or event table, if search sucessfull.
902** We position the stream to the last Block or Ntuple defined in
903** the current event.
904*/
905{
906 u_int p1;
907 int id, ntot, go;
908
909 go = TRUE;
910
911 while (go == TRUE) {
912 p1 = xdr_getpos(str->xdr);
913 if (xdr_mcfast_headerBlock(str->xdr, &id, &ntot, McfGenericVersion)
914 == FALSE) return NOTHING;
915 if ((id == EVENTTABLE) || (id == EVENTHEADER)) {
916 str->currentPos = p1;
917 if(xdr_setpos(str->xdr, p1) == FALSE) return NOTHING;
918 return id;
919 }
920 }
921 return NOTHING; /* This statement is to make the compiler happy */
922}
923
924static int mcfioC_nextspecevt(mcfStream *str, int inum, int istore,
925 int irun, int itrig)
926/*
927** For Input, Direct access streams, hunt for a psecific event
928**
929*/
930{
931 int j, idtmp, ntot, found;
932 u_int p_evt, p2;
933
934 if ((str->table == NULL) ||
935 ((str->table != NULL)&& (str->table->evtnums == NULL))) {
936 idtmp = mcfioC_gofornextevent(str);
937 if (idtmp != EVENTTABLE) {
938 fprintf(stderr,
939 " mcfio_SpecificEvent: No event table on stream %d \n", str->id);
940 return FALSE;
941 } else {
942 if( xdr_mcfast_eventtable(str->xdr, &idtmp,
943 &ntot, McfGenericVersion, &(str->table)) == FALSE) {
944 fprintf(stderr,
945 " mcfio_SpecificEvent: XDR Error decoding the EventTable \n");
946 return FALSE;
947 }
948 p2 = xdr_getpos(str->xdr);
949 str->numWordsC += (ntot/4);
950 str->numWordsT += ((p2-str->currentPos)/4);
951 str->currentPos = p2;
952 str->table->ievt = 0;
953 /*
954 ** If table empty, cal this routine recursively to get
955 ** the next event
956 */
957 str->table->ievt = 0;
958 }
959 }
960 found = FALSE;
961 while (found == FALSE){
962 j = str->table->ievt;
963 if (str->table->ievt < str->table->numevts) {
964 if (((inum == 0)
965 || ( inum != 0 && (str->table->evtnums[j] == inum))) &&
966 (((istore == 0)
967 || (istore != 0) && (str->table->storenums[j] == istore))) &&
968 (((irun == 0)
969 || (irun != 0) && (str->table->runnums[j] == irun))) &&
970 (((itrig == 0)
971 || (itrig != 0) && (str->table->trigMasks[j] == itrig))))
972 found = TRUE;
973 p_evt = str->table->ptrEvents[str->table->ievt];
974 str->table->ievt++;
975 } else {
976 /*
977 ** decode the next table, if valid. If not, scrap the
978 ** existing table and call next event recursively.
979 */
980 if (str->table->nextLocator == -2) {
981 /*
982 ** Stream is at EOF
983 */
984 str->status = MCFIO_EOF;
985
986 return FALSE;
987
988 } else if (str->table->nextLocator == -1) {
989 fprintf(stderr,
990 " mcfio_NextEvent: Next EventTable corrupted, abandoning search \n");
991 return FALSE;
992 }
993 if (xdr_setpos(str->xdr, str->table->nextLocator)
994 == FALSE) { fprintf(stderr,
995 " mcfio_NextEvent: XDR Error repositioning to the next EventTable \n");
996 return FALSE;
997 } else {
998 if( xdr_mcfast_eventtable(str->xdr, &idtmp,
999 &ntot, McfGenericVersion, &(str->table)) == FALSE) {
1000 fprintf(stderr,
1001 " mcfio_NextEvent: XDR Error decoding the EventTable \n");
1002 return FALSE;
1003 }
1004 }
1005 p2 = xdr_getpos(str->xdr);
1006 str->numWordsC += (ntot/4);
1007 str->numWordsT += ((p2-str->currentPos)/4);
1008 str->currentPos = p2;
1009 str->table->ievt = 0;
1010 p_evt = str->table->ptrEvents[0];
1011 }
1012 }
1013 if (found == FALSE) return FALSE;
1014 /*
1015 ** we should be pointing to a good event header here.
1016 */
1017 if (xdr_setpos(str->xdr, p_evt) == FALSE) return FALSE;
1018 if( xdr_mcfast_eventheader(str->xdr, &idtmp,
1019 &ntot, McfGenericVersion, &(str->ehead)) == FALSE) return FALSE;
1020 str->currentPos = xdr_getpos(str->xdr);
1021 str->numWordsC += (ntot/4);
1022 str->numWordsT += ((str->currentPos - p_evt)/4);
1023 return MCFIO_RUNNING;
1024
1025}
Note: See TracBrowser for help on using the repository browser.