RawFileParser.cpp
Go to the documentation of this file.
1 #include <sys/types.h>
2 #include <sys/stat.h>
3 #include <fcntl.h>
4 #include <stdlib.h>
5 #include <stdio.h>
6 #include <string.h>
7 #include <unistd.h>
8 #include <sys/mman.h> // Mem Map Header
9 
10 #include <vector>
11 
12 #include "DAQDataFormats/DAQDataFormats.h"
13 #include "DAQDataFormats/RawRun.h"
14 #include "DAQDataFormats/RawRunHeader.h"
15 #include "DAQDataFormats/RawEvent.h"
16 #include "DAQDataFormats/RawEventHeader.h"
17 #include "DAQDataFormats/RawTrigger.h"
18 #include "DAQDataFormats/RawMicroBlock.h"
19 #include "DAQDataFormats/RawNanoSlice.h"
20 #include "DAQDataFormats/RawConfigurationBlock.h"
21 
22 #include "RawFileParser/RawFileParser.h"
23 
24 #pragma GCC diagnostic ignored "-Wformat="
25 
26 #ifndef TRUE
27 #define TRUE 1
28 #endif /* TRUE */
29 
30 #ifndef FALSE
31 #define FALSE 0
32 #endif /* FALSE */
33 
34 #ifndef FAIL
35 #define FAIL -1
36 #endif /* FAIL */
37 
38 using namespace rawfileparser;
39 using namespace daqdataformats;
40 
41 #define DEBUGMSG(...) if(debug_flag){fprintf(stderr, __VA_ARGS__);}
42 
43 
44 const char* RawFileParser::filetypes[] = {
45  "No File open",
46  "NOvA Run File",
47  "NOvA Event File",
48  "NOvA File, Corrupted",
49  "Unknown File Type"
50 };
51 
52 
53 
55  :
56  fileopenned(false),
57  infile(-1),
58  infilename(0),
59  filetype(NO_FILE),
60  fileversion(0),
61  memmap_io_flag(true),
62  header_start(-1),
63  first_event(-1),
64  config_block_start(-1),
65  config_block_end(-1),
66  tail_start(-1),
67  filepos(0),
68  current_event_index(-1),
69  indexBuilt(NO_INDEX),
70  indexsize(-1),
71  event_offset_list(),
72  event_addr_list(),
73  debug_flag(false)
74 {
75  Init();
76 }
77 
79  :
80  fileopenned(false),
81  infile(-1),
82  infilename(0),
84  fileversion(0),
85  memmap_io_flag(true),
86  header_start(-1),
87  first_event(-1),
89  config_block_end(-1),
90  tail_start(-1),
91  filepos(0),
94  indexsize(-1),
97  debug_flag(false)
98 {
99  Init();
100  this->open(filename);
101 
102 }
103 
105  this->close();
106  if(infilename != NULL){
107  free(infilename);
108  }
109 }
110 
112  if(infilename != NULL){
113  free(infilename);
114  }
115 
116  debug_flag = false;
117 
118  infilename = NULL;
119 
120  memmap_io_flag = true;
121  mmfile_start = NULL;
122  mmfile_end = NULL;
123  mmfile_current = NULL;
124 
125  header_start_addr = NULL;
126  first_event_addr = NULL;
128  config_block_end_addr = NULL;
129  tail_start_addr = NULL;
130 
131  fileopenned = false;
132  infile = -1;
133  filetype = NO_FILE;
134  fileversion = 0;
135 
136  filepos = 0;
137 
138  header_start = -1;
139  config_block_start = -1;
140  config_block_end = -1;
141  first_event = -1;
142  tail_start = -1;
143 
144  event_addr_list.clear();
145  event_offset_list.clear();
146 
148 }
149 
150 int RawFileParser::open(const char* filename){
151  struct stat statbuff;
152 
153  // If there is a file already open, we close it
154  if(fileopenned){
155  this->close();
156  }
157 
158  infilename = (char*)malloc(strlen(filename)+1);
159  strcpy(infilename, filename);
160 
161  infile = ::open(infilename,O_RDONLY);
162 
163  if(!infile){
164  DEBUGMSG("Failed to open file for reading: %s\n",infilename);
165  Init();
166  return infile;
167  }else{
168  DEBUGMSG("Opened file: %s for reading.\n",infilename);
169  fileopenned = true;
170  }
171 
172  // Retrieve the file system statistics on the file
173  if(fstat(infile,&statbuff) < 0){
174  perror("fstat error");
175  return -1;
176  }
177 
178  // Check to make sure the file is not zero size
179  if( statbuff.st_size < 1){
180  // This is an empty file
181  printf("Empty File. Returned size: %Zd\n",statbuff.st_size);
182  DEBUGMSG("Empty File. Returned size: %Zd\n",statbuff.st_size);
183  return -1;
184  }
185 
186  // At this point the file is open. We now want
187  // to memory map the file into the address space
188  // of our library
189 
190  if(memmap_io_flag){
191 
192  // We set our flag to false just in case
193  // we fail to setup our memory mapping correctly
194  memmap_io_flag = false;
195 
196  if(
197  (mmfile_start = mmap(NULL, statbuff.st_size, PROT_READ, MAP_SHARED, infile, 0)) == (caddr_t) -1){
198  perror("mmap error on file");
199  }else{
200  DEBUGMSG("Mem Map Successful\n");
201  memmap_io_flag = true; // Mem mapped io is turned on
202  mmfile_end8 = mmfile_start8 + statbuff.st_size;
204  }
205  } // endif memmap_io_flag
206 
207  // Now check the file type
208  if(CheckFileType() > 0){
209  return filetype;
210  }else{
211  return FAIL;
212  }
213 
214  return FAIL;
215 }
216 
217 
219  struct stat statbuff;
220  int ret=0;
221 
222  // First we close any memory maps we had on our file
223  if(memmap_io_flag){
224  if(mmfile_start != NULL){
225 
226  // First retrieve the size of the file
227  if(fstat(infile, &statbuff) < 0){
228  perror("fstat error");
229  }
230 
231  if( (ret = munmap(mmfile_start, statbuff.st_size)) < 0){
232  perror("Error unmapping file from memory");
233  }
234 
235  }
236  }
237 
238  if(infile > 0){
239  ret = ::close(infile);
240  }
241 
242  // If we were able to close the file, then
243  // we clean up
244  if(ret != 0){
245 
246  // If for some reason we were unable to close a file
247  // we still clean up, but we report the error
248  perror("File Close");
249  }
250  Init();
251 
252  return ret;
253 }
254 
256  if(memmap_io_flag){
257  return CheckFileType_mem();
258  }else{
259  return CheckFileType_file();
260  }
261  return UNKNOWN_FILE;
262 }
263 
265  // Attempt to use memory mapped IO
266 
267  DEBUGMSG("Ussing mem\n");
268  switch(mmfile_start32[0]){
269  // Run File Magic
270  case NOVA_ASCII: // first word of a Run should read "NOVA" in ASCII
271  switch(mmfile_start32[1]){
272  case E929_ASCII:
273  DEBUGMSG("NOVA Run File detected\n");
275  break;
276  default:
277  DEBUGMSG("Corrupt Run File detected\n");
279  break;
280  }; // endswitch word2
281  break;
282  // Event File Magic
283  case EVENT_MARKER: // First word of an Event should read "E929" in hex
285  DEBUGMSG("NOVA Event File detected\n");
286  break;
287  default:
288  DEBUGMSG("Unrecognized NOvA File type\n");
290  break;
291  }; // endswitch word1
292 
293  return filetype;
294 }
295 
297  int bytes_read = 0;
298  unsigned int buff[4]={0,0,0,0};
299 
300  // First Check to make sure we have a file openned
301  if(!fileopenned){
302  return NO_FILE;
303  }
304 
305  /* Perform some Magic Number Checking to determine the file type */
306  /* To do this we allocate a small (4 word) buffer and fill it */
307  /* with the start of the file. This allows us to do both magic */
308  /* number and version checking. Currently only the magic is */
309  /* checked. Will impliment file version later */
310 
311  // Read in 16 bytes of data */
312  bytes_read = ::read(infile, &buff, 16);
313  if(bytes_read < 0){
314  // throw
315  }
316 
317  switch(buff[0]){
318  // Run File Magic
319  case NOVA_ASCII: // first word of a Run should read "NOVA" in ASCII
320  switch(buff[1]){
321  case E929_ASCII:
322  DEBUGMSG("NOVA Run File detected\n");
324  break;
325  default:
326  DEBUGMSG("Corrupt Run File detected\n");
328  break;
329  }; // endswitch word2
330  break;
331  // Event File Magic
332  case EVENT_MARKER: // First word of an Event should read "E929" in hex
334  DEBUGMSG("NOVA Event File detected\n");
335  break;
336  default:
337  DEBUGMSG("Unrecognized NOvA File type\n");
339  break;
340  }; // endswitch word1
341 
342  // After parsing out the file type, rewind the file
343  filepos = lseek(infile, 0, SEEK_SET);
344  return filetype;
345 }
346 
347 // Method to return the file type
349  if(fileopenned){
350  return filetype;
351  }else{
352  DEBUGMSG("Error retrieving file type: %s",filetypes[filetype]);
353  return NO_FILE;
354  }
355 
356 }
357 
358 /***********************************************
359  * Methods that Advance around the file
360  *
361  ***********************************************/
362 
364  if(memmap_io_flag){
365  return AdvanceToRunHeader_mem(header_pos);
366  }else{
367  return AdvanceToRunHeader_file(header_pos);
368  }
369  return FALSE;
370 }
371 
373  int ret;
374  uint32_t* start_pos;
375  off_t pos;
376 
377  RawRunHeader theHeader;
378 
379  // First see if we already have an address of the config block
380  // in our cache
381  if(header_start_addr != NULL){
382  // Set the cached position to the current position
385 
386  // Set the file position to the current position
387  filepos = rewind(pos);
388  return TRUE;
389  }
390 
391  // The Run header should be near the begining of the
392  // the file. We save the current position and then
393  // repostion to the start of the file
394  start_pos = mmfile_current32;
396 
397  bool found_block=false;
398  while(!found_block){
399  // Search for the first config block header word
400  ret = wordsearch(theHeader.getMarkerHi());
401 
402  switch(ret){
403  case TRUE:
404  // Check the adjacent word
406  if(checkWord(theHeader.getMarkerLo()) > 0){found_block=true;};
408  break;
409  case FALSE:
410  DEBUGMSG("End of file reached during run file header block start search, no header block found\n");
411  // Rewind the file to where we started from
412  mmfile_current32 = start_pos;
413  return FALSE;
414  break;
415  case FAIL:
416  DEBUGMSG("Read from file failed during run header block search");
417  return FAIL;
418  break;
419  default:
420  DEBUGMSG("Unknown error in wordsearch(0x%08x)\n",theHeader.getMarkerHi());
421  return FAIL;
422  break;
423  } // endswitch ret
424 
425  } // endwhile
426 
427  // We have found our header block marker at this point
428 
431 
432  filepos = rewind(pos);
433  header_pos = filepos;
434 
435  return TRUE;
436 
437 }
438 
440  int ret;
441  off_t start_pos;
442 
443  RawRunHeader theHeader;
444 
445  // Make sure we have a file open
446  if(!fileopenned){
447  DEBUGMSG("AdvanceToRunHeader(): File not openned for parsing\n");
448  return FALSE;
449  }
450 
451  // First see if we already have an address of the config block
452  // in our cache
453  if(header_start > -1){
454  if( rewind(header_start) < 0){
455  DEBUGMSG("Unable to advance to cache position of config block start\n");
456  return FAIL;
457  }else{
458  // Set the file position to the current position
459  filepos = curpos();
460  header_pos = filepos;
461  return TRUE;
462  }
463  }
464 
465  // Record the current file position
466  if( savepos(start_pos) < 0){
467  DEBUGMSG("AdvanceToRunHeader(): unable to save file position\n");
468  return FAIL;
469  };
470 
471  // The Run header should be near the begining of the
472  // the file so we jump to the zero offset in the file
473  rewind(0);
474 
475  bool found_block=false;
476  while(!found_block){
477  // Search for the first config block header word
478  ret = wordsearch(theHeader.getMarkerHi());
479 
480  switch(ret){
481  case TRUE:
482  // Check the adjacent word
483  forward(sizeof(unsigned int));
484  if(checkWord(theHeader.getMarkerLo()) > 0){found_block=true;};
485  backup(sizeof(unsigned int));
486 
487  break;
488  case FALSE:
489  DEBUGMSG("End of file reached during run file header block start search, no header block found\n");
490  // Rewind the file to where we started from
491  rewind(start_pos);
492  return FALSE;
493  break;
494  case FAIL:
495  DEBUGMSG("Read from file failed during run header block search");
496  return FAIL;
497  break;
498  default:
499  DEBUGMSG("Unknown error in wordsearch(0x%08x)\n",theHeader.getMarkerHi());
500  return FAIL;
501  break;
502  } // endswitch ret
503 
504  } // endwhile
505 
506  // We have found our header block marker at this point
507 
508  // Record our first event point
509  header_start = curpos();
510  if(header_start < 0){
511  return FAIL;
512  }
513 
515  header_pos = header_start;
516  return TRUE;
517 }
518 
519 
520 
522  if(memmap_io_flag){
523  return AdvanceToConfigStart_mem(config_pos);
524  }else{
525  return AdvanceToConfigStart_file(config_pos);
526  }
527  return FALSE;
528 }
529 
531  int ret;
532  uint32_t* start_pos;
533  off_t pos;
534 
535  RawConfigurationHeader theConfigHeader;
536 
537  // First see if we already have an address of the config block
538  // in our cache
539  if(config_block_start_addr != NULL){
540  // Set the cached position to the current position
543 
544  // Set the file position to the current position
545  filepos = rewind(pos);
546  config_pos = filepos;
547  return TRUE;
548  }
549 
550  // Save the current position before searching
551  start_pos = mmfile_current32;
552 
553  bool found_block=false;
554  while(!found_block){
555  // Search for the first config block header word
556  ret = wordsearch(theConfigHeader.getMarkerHi1());
557  switch(ret){
558  case TRUE:
559  // Check the adjacent word
561  if(checkWord(theConfigHeader.getMarkerHi2()) > 0){found_block=true;};
563  break;
564  case FALSE:
565  DEBUGMSG("End of file reached during config block start search, no config block found\n");
566  // Rewind the file to where we started from
567  mmfile_current32 = start_pos;
568  // rewind(start_pos);
569  return FALSE;
570  break;
571  case FAIL:
572  DEBUGMSG("Read from file failed during config block start search");
573  return FAIL;
574  break;
575  default:
576  DEBUGMSG("Unknown error in wordsearch(0x%08x)\n",theConfigHeader.getMarkerHi1());
577  return FAIL;
578  break;
579  } // endswitch ret
580 
581  } // endwhile
582 
583  // We have found our event block marker at this point
584 
587 
588  filepos = rewind(pos);
590 
591  return TRUE;
592 }
593 
595  int ret;
596  off_t start_pos;
597 
598  RawConfigurationHeader theConfigHeader;
599 
600  // Make sure we have a file open
601  if(!fileopenned){
602  DEBUGMSG("AdvanceToConfigStart(): File not openned for parsing\n");
603  return FALSE;
604  }
605 
606  // First see if we already have an address of the config block
607  // in our cache
608  if(config_block_start > -1){
609  if( rewind(config_block_start) < 0){
610  DEBUGMSG("Unable to advance to cache position of config block start\n");
611  return FAIL;
612  }else{
613  // Set the file position to the current position
614  filepos = curpos();
615  config_pos = filepos;
616  return TRUE;
617  }
618  }
619 
620  // Record the current file position
621  if( savepos(start_pos) < 0){
622  DEBUGMSG("AdvanceToRunStart(): unable to save file position\n");
623  return FAIL;
624  };
625 
626  bool found_block=false;
627  while(!found_block){
628  // Search for the first config block header word
629  ret = wordsearch(theConfigHeader.getMarkerHi1());
630 
631  switch(ret){
632  case TRUE:
633  // Check the adjacent word
634  forward(sizeof(unsigned int));
635  if(checkWord(theConfigHeader.getMarkerHi2()) > 0){found_block=true;};
636  backup(sizeof(unsigned int));
637 
638  break;
639  case FALSE:
640  DEBUGMSG("End of file reached during config block start search, no config block found\n");
641  // Rewind the file to where we started from
642  rewind(start_pos);
643  return FALSE;
644  break;
645  case FAIL:
646  DEBUGMSG("Read from file failed during config block start search");
647  return FAIL;
648  break;
649  default:
650  DEBUGMSG("Unknown error in wordsearch(0x%08x)\n",theConfigHeader.getMarkerHi1());
651  return FAIL;
652  break;
653  } // endswitch ret
654 
655  } // endwhile
656 
657  // We have found our event block marker at this point
658 
659  // Record our first event point
661  if(config_block_start < 0){
662  return FAIL;
663  }
664 
666  config_pos = config_block_start;
667  return TRUE;
668 }
669 
670 
672  int ret;
673  off_t start_pos;
674 
675  RawConfigurationTail theConfigTail;
676 
677  // Make sure we have a file open
678  if(!fileopenned){
679  DEBUGMSG("AdvanceToConfigEnd(): File not openned for parsing\n");
680  return FALSE;
681  }
682 
683  // First see if we already have an address of the config block
684  // in our cache
685  if(config_block_end > -1){
686  if( rewind(config_block_end) < 0){
687  DEBUGMSG("Unable to advance to cache position of config block tail\n");
688  return FAIL;
689  }else{
690  // Set the file position to the current position
691  filepos = curpos();
692  config_pos = filepos;
693  return TRUE;
694  }
695  }
696 
697  // Record the current file position
698  if( savepos(start_pos) < 0){
699  DEBUGMSG("AdvanceToConfigEnd(): unable to save file position\n");
700  return FAIL;
701  };
702 
703  bool found_block=false;
704  while(!found_block){
705  // Search for the first config block header word
706  ret = wordsearch(theConfigTail.getMarkerLo1());
707 
708  switch(ret){
709  case TRUE:
710  // Check the adjacent word
711  forward(sizeof(unsigned int));
712  if(checkWord(theConfigTail.getMarkerLo2()) > 0){found_block=true;};
713  backup(sizeof(unsigned int));
714 
715  break;
716  case FALSE:
717  DEBUGMSG("End of file reached during config block end search, no config tail found\n");
718  // Rewind the file to where we started from
719  rewind(start_pos);
720  return FALSE;
721  break;
722  case FAIL:
723  DEBUGMSG("Read from file failed during config block tail search");
724  return FAIL;
725  break;
726  default:
727  DEBUGMSG("Unknown error in wordsearch(0x%08x)\n",theConfigTail.getMarkerLo1());
728  return FAIL;
729  break;
730  } // endswitch ret
731 
732  } // endwhile
733 
734  // We have found our end config block marker at this point
735 
736  // Record our config block end point
738  if(config_block_end < 0){
739  return FAIL;
740  }
741 
743  config_pos = config_block_end;
744  return TRUE;
745 }
746 
748  if(memmap_io_flag){
749  return AdvanceToRunTail_mem(tail_pos);
750  }else{
751  return AdvanceToRunTail_file(tail_pos);
752  }
753  return FALSE;
754 }
755 
757  int ret;
758  uint32_t* start_pos;
759  off_t pos;
760 
761  // First see if we already have an address of the tail
762  // event in our cache
763  if(tail_start_addr != NULL){
764  // Set the cached position to the current position
767 
768  // Set the file position to the current position
769  filepos = rewind(pos);
770  return TRUE;
771  }
772 
773  start_pos = mmfile_current32; // Record the current position
774 
775  mmfile_current32 = mmfile_end32; // Jump to the end of the file buffer
776  mmfile_current32 -= 400; // Back off from the end by 400 words
777 
778  ret = wordsearch(TAIL_MARKER); // Look for the TAIL_MARKER
779 
780  switch(ret){
781  case TRUE:
782  // Check the adjacent word
786  break;
787  case FALSE:
788  DEBUGMSG("End of file reached during run tail search, no tail found\n");
789  // Rewind the file to where we started from
790  mmfile_current32 = start_pos;
791  return FALSE;
792  break;
793  case FAIL:
794  DEBUGMSG("Read from file failed during run tail search");
795  return FAIL;
796  break;
797  default:
798  DEBUGMSG("Unknown error in wordsearch(0x%08x)\n",TAIL_MARKER);
799  return FAIL;
800  break;
801  }
802 
805 
806  filepos = rewind(pos);
808 
809  return true;
810 }
811 
813  int ret;
814  off_t start_pos;
815 
816  RawRunHeader theTail;
817 
818  // Make sure we have a file open
819  if(!fileopenned){
820  DEBUGMSG("AdvanceToRunTail(): File not openned for parsing\n");
821  return FALSE;
822  }
823 
824  // First see if we already have an address of the config block
825  // in our cache
826  if(tail_start > -1){
827  if( rewind(tail_start) < 0){
828  DEBUGMSG("Unable to advance to cache position of run tail\n");
829  return FAIL;
830  }else{
831  // Set the file position to the current position
832  filepos = curpos();
833  tail_pos = filepos;
834  return TRUE;
835  }
836  }
837 
838  // Record the current file position
839  if( savepos(start_pos) < 0){
840  DEBUGMSG("AdvanceToRunTail(): unable to save file position\n");
841  return FAIL;
842  };
843 
844  bool found_block=false;
845  while(!found_block){
846  // Search for the tail block header word
847  ret = wordsearch(TAIL_MARKER);
848 
849  switch(ret){
850  case TRUE:
851  // Check the adjacent word
852  forward(sizeof(unsigned int));
853  if(checkWord(TAIL_MARKER) > 0){found_block=true;};
854  backup(sizeof(unsigned int));
855 
856  break;
857  case FALSE:
858  DEBUGMSG("End of file reached during run tail search, no tail found\n");
859  // Rewind the file to where we started from
860  rewind(start_pos);
861  return FALSE;
862  break;
863  case FAIL:
864  DEBUGMSG("Read from file failed during run tail search");
865  return FAIL;
866  break;
867  default:
868  DEBUGMSG("Unknown error in wordsearch(0x%08x)\n",TAIL_MARKER);
869  return FAIL;
870  break;
871  } // endswitch ret
872 
873  } // endwhile
874 
875  // We have found our end config block marker at this point
876 
877  // Record our config block end point
878  tail_start = curpos();
879  if(tail_start < 0){
880  return FAIL;
881  }
882 
884  tail_pos = tail_start;
885  return TRUE;
886 }
887 
888 
889 // This function advances us to the first event in a file
890 // This function should only be used to find the FIRST
891 // event, not to skip to subsequent events.
892 int RawFileParser::AdvanceToFirstEvent(off_t& first_event_pos, bool index_entries){
893  if(memmap_io_flag){
894  return AdvanceToFirstEvent_mem(first_event_pos, index_entries);
895  }else{
896  return AdvanceToFirstEvent_file(first_event_pos, index_entries);
897  }
898  return FALSE;
899 }
900 
901 int RawFileParser::AdvanceToFirstEvent_mem(off_t& /*first_event_pos*/, bool /*index_entries*/){
902  int ret;
903  uint32_t* start_pos;
904  off_t pos;
905 
906  // First see if we already have an address of the fist
907  // event in our cache
908  if(first_event_addr != NULL){
909  // Set the cached position to the current position
912 
913  // Set the file position to the current position
914  filepos = rewind(pos);
915  return TRUE;
916  }
917 
918  start_pos = mmfile_current32;
920 
921  ret = wordsearch(EVENT_MARKER);
922 
923  switch(ret){
924  case TRUE:
925  break;
926  case FALSE:
927  DEBUGMSG("End of file reached during first event search, no event block found\n");
928  // Rewind the file to where we started from
929  mmfile_current32 = start_pos;
930  return FALSE;
931  break;
932  case FAIL:
933  DEBUGMSG("Read from file failed during event header search");
934  return FAIL;
935  break;
936  default:
937  DEBUGMSG("Unknown error in wordsearch(0x%08x)\n",EVENT_MARKER);
938  return FAIL;
939  break;
940  }
941 
944 
945  filepos = rewind(pos);
947 
948  std::vector<uint32_t*>::iterator it_addr;
949  it_addr = event_addr_list.begin();
950  event_addr_list.insert(it_addr, 0, (uint32_t*)first_event_addr);
951 
952  std::vector<off_t>::iterator it_offset;
953  it_offset = event_offset_list.begin();
954  event_offset_list.insert(it_offset,0,first_event);
955 
957  return true;
958 
959 }
960 
961 int RawFileParser::AdvanceToFirstEvent_file(off_t& first_event_pos, bool index_entries){
962  int ret;
963  off_t start_pos;
964 
965  // Make sure we have a file open
966  if(!fileopenned){
967  DEBUGMSG("AdvanceToFirstEvent(): File not openned for parsing\n");
968  return FALSE;
969  }
970 
971  // First see if we already have an address of the first
972  // event in our cache
973  if(first_event > -1){
974  DEBUGMSG("Using Cached position of first event\n");
975  if( rewind(first_event) < 0){
976  DEBUGMSG("Unable to advance to cache position of first event\n");
977  return FAIL;
978  }else{
979  // Set the file position to the current position
980  filepos = curpos();
981  first_event_pos = first_event;
982  return TRUE;
983  }
984  }
985 
986  // Record the current file position
987  if( savepos(start_pos) < 0){
988  DEBUGMSG("wordsearch(): unable to save file position\n");
989  return FAIL;
990  };
991 
992  // At this point we have no idea where in the file we might be
993  // but we also know that we have not yet found the first event's
994  // position. The safest thing to do is to backup to the start of
995  // the file and do a hard search from there
996 
997  // Rewind to the start of the file
998  rewind(0);
999 
1000  // Do a hard search for the first event
1001  ret = wordsearch(EVENT_MARKER);
1002 
1003  switch(ret){
1004  case TRUE:
1005  break;
1006  case FALSE:
1007  DEBUGMSG("End of file reached during first event search, no event block found\n");
1008  // Rewind the file to where we started from
1009  rewind(start_pos);
1010  return FALSE;
1011  break;
1012  case FAIL:
1013  DEBUGMSG("Read from file failed during event header search");
1014  return FAIL;
1015  break;
1016  default:
1017  DEBUGMSG("Unknown error in wordsearch(0x%08x)\n",EVENT_MARKER);
1018  return FAIL;
1019  break;
1020  }
1021 
1022  // We have found our event block marker at this point
1023 
1024  // Record our first event point
1025  first_event = curpos();
1026  if(first_event < 0){
1027  return FAIL;
1028  }
1029 
1030  // Set the file position to the current position
1031  if(index_entries){
1032  // Put the event on the list
1033  event_offset_list.push_back(first_event);
1035  }
1036 
1037  filepos = first_event;
1038  first_event_pos = first_event;
1039  return TRUE;
1040 }
1041 
1042 
1043 int RawFileParser::AdvanceToPreviousEvent(off_t& next_event_pos, bool index_entries){
1044  if(memmap_io_flag){
1045  return AdvanceToPreviousEvent_mem(next_event_pos, index_entries);
1046  }else{
1047  // return AdvanceToNextEvent_file(next_event_pos, index_entries);
1048  return FALSE;
1049  }
1050  return FALSE;
1051 }
1052 
1053 int RawFileParser::AdvanceToPreviousEvent_mem(off_t& next_event_pos, bool index_entries){
1054  int ret;
1055  uint32_t* start_pos;
1056  off_t pos;
1057 
1058  // Save the current position
1059  start_pos = mmfile_current32;
1060 
1061  // Now check that we are starting on an event boundary
1062  ret = checkWord(EVENT_MARKER);
1063 
1064  if(ret < 0){
1065  // Something went wrong, return back an error
1066  return FAIL;
1067  }
1068 
1069  // We force the direct reverse search
1070  ret = 0;
1071 
1072  if(ret == 0){
1073  // For some reason our current position doesn't appear to
1074  // be an event start boundary. We move backwards with
1075  // a direct word by word search
1076  DEBUGMSG("trying reverse direct...");
1077 
1078  --mmfile_current32;
1080  case TRUE:
1081  break;
1082  case FALSE:
1083  DEBUGMSG("AdvanceToPreviousEvent(): End of file reached during event search, no event block found\n");
1084  // Rewind the file to where we started from
1085  mmfile_current32 = start_pos;
1086  return FALSE;
1087  break;
1088  case FAIL:
1089  DEBUGMSG("AdvanceToPreviousEvent(): Read from file failed during event header search");
1090  return FAIL;
1091  break;
1092  default:
1093  DEBUGMSG("Unknown error in wordsearch(0x%08x)\n",EVENT_MARKER);
1094  return FAIL;
1095  break;
1096  }
1097  // We have found our next event
1098  }
1099 
1100  // Calculate the offset
1102 
1103  // Check the offset to make sure something moved
1104  if(pos != 0) {
1105  return TRUE;
1106  }else{
1107  return FALSE;
1108  }
1109 
1110  return FALSE;
1111 }
1112 
1113 
1114 // This function advances us to the next event in a file.
1115 // It is assumed when calling this function that the
1116 // entry point that we are sitting is an event record
1117 // so that we can just jump ahead by the size of the record
1118 // There is limited checking though so it can move forward
1119 // byte by byte looking for an event if it has problems
1120 // with the direct jump. (i.e. file is damaged)
1121 int RawFileParser::AdvanceToNextEvent(off_t& next_event_pos, bool index_entries){
1122  if(memmap_io_flag){
1123  return AdvanceToNextEvent_mem(next_event_pos, index_entries);
1124  }else{
1125  return AdvanceToNextEvent_file(next_event_pos, index_entries);
1126  }
1127  return FALSE;
1128 }
1129 
1130 int RawFileParser::AdvanceToNextEvent_mem(off_t& next_event_pos, bool index_entries){
1131  int ret;
1132  uint32_t* start_pos;
1133  off_t pos;
1134 
1135  // Save the current position
1136  start_pos = mmfile_current32;
1137 
1138  // Now check that we are starting on an event boundary
1139  ret = checkWord(EVENT_MARKER);
1140 
1141  if(ret < 0){
1142  // Something went wrong, return back an error
1143  return FAIL;
1144  }
1145 
1146  if(ret == 0){
1147  // For some reason our current position doesn't appear to
1148  // be an event start boundary. We move forward with
1149  // a direct word by word search
1150  DEBUGMSG("trying direct...");
1151 
1152  switch(wordsearch(EVENT_MARKER)){
1153  case TRUE:
1154  break;
1155  case FALSE:
1156  DEBUGMSG("AdvanceToNextEvent(): End of file reached during event search, no event block found\n");
1157  // Rewind the file to where we started from
1158  mmfile_current32 = start_pos;
1159  return FALSE;
1160  break;
1161  case FAIL:
1162  DEBUGMSG("AdvanceToNextEvent(): Read from file failed during event header search");
1163  return FAIL;
1164  break;
1165  default:
1166  DEBUGMSG("Unknown error in wordsearch(0x%08x)\n",EVENT_MARKER);
1167  return FAIL;
1168  break;
1169  }
1170  // We have found our next event
1171  }
1172 
1173  if(ret > 0){
1174  // We appear to be on a standard event start boundary
1175  // We try to advance forward in a smart fashion by
1176  // reading the event size and jumping ahead
1177  ssize_t eventsize;
1178 
1179  // First retrieve the size of the current event
1180  eventsize = readEventSize();
1181  // DEBUGMSG("Size: 0x%08Zx\t%Zd\n",eventsize,eventsize);
1182 
1183  if(eventsize < 0){
1184  DEBUGMSG("Unable to retrieve event size in AdvanceToNextEvent()\n");
1185  return FAIL;
1186  }
1187 
1188  // Now skip ahead in the file by the event size
1189  mmfile_current32 += eventsize;
1190 
1191  // Check to see that we are NOW on an event header boundary
1192  if( checkWord(EVENT_MARKER) != TRUE){
1193  DEBUGMSG("Error in advancing to next event in AdvanceToNextEvent()\n");
1194  }else{
1195  // We have found the next event so we set the position and return
1196  filepos = curpos();
1197  next_event_pos = curpos();
1198  return TRUE;
1199  }
1200 
1201  // Check to see that we are NOW on an event header boundary
1202  if( checkWord(EVENT_MARKER) != TRUE){
1203  // We don't appear to be on the right boundary
1204  // we are going to back up and try to locate the next event
1205  // via direct search
1206  mmfile_current32 = start_pos+1;
1207 
1208  switch(wordsearch(EVENT_MARKER)){
1209  case TRUE:
1210  break;
1211  case FALSE:
1212  DEBUGMSG("AdvanceToNextEvent(): End of file reached during event search, no event block found\n");
1213  // Rewind the file to where we started from
1214  mmfile_current32 = start_pos;
1215  return FALSE;
1216  break;
1217  case FAIL:
1218  DEBUGMSG("AdvanceToNextEvent(): Read from file failed during event header search");
1219  return FAIL;
1220  break;
1221  default:
1222  DEBUGMSG("Unknown error in wordsearch(0x%08x)\n",EVENT_MARKER);
1223  return FAIL;
1224  break;
1225  }
1226 
1227  // DEBUGMSG("Error in advancing to next event in AdvanceToNextEvent()\n");
1228  }
1229 
1230  } /* endif ret */
1231 
1232  // We have found our next event
1233 
1234  // Calculate the offset
1236 
1237  // Record it on our event list index
1238  if(index_entries){
1239  event_addr_list.push_back(mmfile_current32);
1240  event_offset_list.push_back(pos);
1242  }
1243 
1244  // Move the file to this offset
1245  filepos = rewind(pos);
1246  next_event_pos = pos;
1247 
1248  return TRUE;
1249 }
1250 
1251 int RawFileParser::AdvanceToNextEvent_file(off_t& next_event_pos, bool index_entries){
1252 
1253  int ret;
1254  off_t start_pos;
1255  ssize_t eventsize;
1256 
1257  // Make sure we have a file open
1258  if(!fileopenned){
1259  DEBUGMSG("AdvanceToNextEvent(): File not openned for parsing\n");
1260  return FALSE;
1261  }
1262 
1263  // First save our position in the file
1264  if( savepos(start_pos) < 0){
1265  DEBUGMSG("AdvanceToNextEvent(): unable to save file position\n");
1266  return FAIL;
1267  }
1268 
1269  // Now check that we are starting on an event boundary
1270  ret = checkWord(EVENT_MARKER);
1271 
1272  if(ret < 0){
1273  // Something went wrong, return back an error
1274  return FAIL;
1275  }
1276 
1277  if(ret == 0){
1278  // For some reason our current position doesn't appear to
1279  // be an event start boundary. We move forward with
1280  // a direct word by word search
1281 
1282  switch(wordsearch(EVENT_MARKER)){
1283  case TRUE:
1284  break;
1285  case FALSE:
1286  DEBUGMSG("AdvanceToNextEvent(): End of file reached during event search, no event block found\n");
1287  // Rewind the file to where we started from
1288  rewind(start_pos);
1289  return FALSE;
1290  break;
1291  case FAIL:
1292  DEBUGMSG("AdvanceToNextEvent(): Read from file failed during event header search");
1293  return FAIL;
1294  break;
1295  default:
1296  DEBUGMSG("Unknown error in wordsearch(0x%08x)\n",EVENT_MARKER);
1297  return FAIL;
1298  break;
1299  }
1300 
1301  if(index_entries){
1302  // We have found our next event
1303  // Record it on our event list
1304  event_offset_list.push_back(curpos());
1306  }
1307 
1308  // Set the file position to the current position
1309  filepos = curpos();
1310  next_event_pos = curpos();
1311  return TRUE;
1312  } /* endif ret == 0 */
1313 
1314  if(ret > 0){
1315  // We appear to be on a standard event start boundary
1316  // We try to advance forward in a smart fashion by
1317  // reading the event size and jumping ahead
1318 
1319  // First retrieve the size of the current event
1320  eventsize = readEventSize();
1321  if(eventsize < 0){
1322  DEBUGMSG("Unable to retrieve event size in AdvanceToNextEvent()\n");
1323  return FAIL;
1324  }
1325 
1326  // Now skip ahead in the file by the event size
1327  if( forward(eventsize) < 0){
1328  perror("Unable to advance file in AdvanceToNextEvent()");
1329  }
1330 
1331  // Check to see that we are NOW on an event header boundary
1332  if( checkWord(EVENT_MARKER) != TRUE){
1333  DEBUGMSG("Error in advancing to next event in AdvanceToNextEvent()\n");
1334  }else{
1335  // We have found the next event so we set the position and return
1336  filepos = curpos();
1337  next_event_pos = curpos();
1338  return TRUE;
1339  }
1340  } /* endif ret */
1341 
1342  return FALSE;
1343 }
1344 
1345 // Method to advance to an event (and tries to be smart
1346 // depending on where we are in the file)
1347 int RawFileParser::AdvanceToEvent(off_t& event_pos, bool index_entries){
1348 
1349  // Make sure we have a file open
1350  if(!fileopenned){
1351  DEBUGMSG("AdvanceToNextEvent(): File not openned for parsing\n");
1352  return FALSE;
1353  }
1354 
1355  // Check to see if we have located our first event
1356  if(isMemoryMappedIO()){
1357  if(first_event_addr == NULL){
1358  return AdvanceToFirstEvent(event_pos, index_entries);
1359  }else{
1360  return AdvanceToNextEvent(event_pos, index_entries);
1361  }
1362  }else{
1363  if(first_event == -1){
1364  // We haven't found our first event yet, so we default
1365  // to the finding it the safe way
1366  return AdvanceToFirstEvent(event_pos, index_entries);
1367  }
1368 
1369  // If we are at a position before the first event
1370  // we move to the first event
1371  if(first_event > filepos){
1372  return AdvanceToFirstEvent(event_pos, index_entries);
1373  }
1374 
1375  // If we are at or after the first event,
1376  // we go to the Next event
1377  if(first_event <= filepos){
1378  return AdvanceToNextEvent(event_pos, index_entries);
1379  }
1380  }
1381  return FAIL;
1382 }
1383 
1384 int RawFileParser::GotoEvent(int event_no){
1385  if(isMemoryMappedIO()){
1386  return GotoEvent_mem(event_no);
1387  }else{
1388  return GotoEvent_file(event_no);
1389  }
1390  return FAIL;
1391 }
1392 
1394  static int recursion_depth=0;
1395 
1396  recursion_depth++;
1397  if(recursion_depth > 2){return FAIL;}
1398 
1399  if(indexBuilt == FULL_INDEX){
1400  if((unsigned int)event_no < event_addr_list.size()){
1401  mmfile_current32 = event_addr_list[event_no];
1402  recursion_depth = 0;
1403  return TRUE;
1404  }else{
1405  DEBUGMSG("GotoEvent_mem(): Requested index exceeds maximum event in file\n");
1406  recursion_depth = 0;
1407  return FALSE;
1408  }
1409  }else{
1410  // We don't have a full index so we attempt to index
1411  // the file and then return the events
1412  BuildEventIndex_mem(-1,true);
1413  return GotoEvent_mem(event_no);
1414  }
1415  recursion_depth = 0;
1416  return FALSE;
1417 }
1418 
1420  off_t evtpos;
1421  int ret;
1422 
1423  // Make sure we have a file open
1424  if(!fileopenned){
1425  DEBUGMSG("GotoEvent(): File not openned for parsing\n");
1426  return FALSE;
1427  }
1428 
1429  // First check to see if we have an index built
1430  switch(indexBuilt){
1431  case FULL_INDEX:
1432  // If we have a full index, then we try to just go directly
1433  // to the event of interest
1434  if( (unsigned)event_no <= event_offset_list.size()){
1435  if( rewind(event_offset_list[event_no] <0)){
1436  DEBUGMSG("Error going to event: %d under current index\n",event_no);
1437  return FAIL;
1438  }else{
1439  // Set the file position to the current position
1440  filepos = curpos();
1441  return TRUE;
1442  }
1443  }else{
1444  DEBUGMSG("Requested event number: %d, exceeds maximum number of events in index\n",event_no);
1445  return FALSE;
1446  }
1447  break;
1448 
1449  case NO_INDEX:
1450  // If we have no index and we were asked to goto an event,
1451  // we have to do it the painful way, one event at a time
1452  // we do however build the index as we go so at least
1453  // the next time we can jump around
1454  for(int num_events=0; num_events<event_no; ++num_events){
1455  ret = AdvanceToEvent(evtpos,true);
1456  if(ret == TRUE){continue;}
1457  if(ret == FALSE){
1458  // We have reached the end of the file but not yet found the event
1459  indexsize = num_events;
1461  // Since we didn't find the event we return false
1462  evtpos = 0;
1463  return FALSE;
1464  }
1465  if(ret == FAIL){
1466  // Something failed
1467  evtpos = 0;
1468  return FAIL;
1469  }
1470  } // endif i
1471  // We have advanced to our event successfully
1472  return TRUE;
1473  break;
1474 
1475  case PARTIAL_INDEX:
1476  // We have a partial index, so we jump directly as far as we can
1477  // and then after that we step event by event
1478  if(event_no <= indexsize){
1479  // we can jump directly to our event
1480  rewind(event_offset_list[event_no]);
1481  filepos = event_offset_list[event_no];
1482  }
1483 
1484  if(event_no > indexsize){
1485  // First jump to the last position we have indexed
1489 
1490  // Now pickup at this point and step forward
1491  for(int num_events= event_offset_list.size(); num_events<event_no; ++num_events){
1492  ret = AdvanceToEvent(evtpos,true);
1493  if(ret == TRUE){continue;}
1494  if(ret == FALSE){
1495  // We have reached the end of the file but not yet found the event
1496  indexsize = num_events;
1498  // Since we didn't find the event we return false
1499  evtpos = 0;
1500  return FALSE;
1501  }
1502  if(ret == FAIL){
1503  // Something failed
1504  evtpos = 0;
1505  return FAIL;
1506  }
1507  } // endif i
1508  // We found the event
1509  return TRUE;
1510  }
1511 
1512  break;
1513  } // endswitch
1514 
1515  return FALSE;
1516 }
1517 
1518 int RawFileParser::BuildEventIndex(int max_idx, bool force_rebuild){
1519  if(memmap_io_flag){
1520  return BuildEventIndex_mem(max_idx, force_rebuild);
1521  }else{
1522  return BuildEventIndex_file(max_idx, force_rebuild);
1523  }
1524  return FALSE;
1525 }
1526 
1527 int RawFileParser::BuildEventIndex_mem(int max_idx, bool force_rebuild){
1528  int ret;
1529  int num_events;
1530  off_t pos;
1531 
1532  // Guard against rebuilding the index
1533  // except when asked to do it
1534  if(indexBuilt==FULL_INDEX){
1535  if(!force_rebuild){
1536  return TRUE;
1537  }
1538  }
1539 
1540  // If we have been asked to rebuild the index
1541  // We don't support partial rebuilds right now
1542  // so we just clear the current index and rebuilt it all
1543  if(force_rebuild){
1544  event_addr_list.clear();
1545  indexBuilt = NO_INDEX;
1546  num_events = 0;
1547 
1548  // Goto the first event in the file
1549  AdvanceToFirstEvent(pos,true);
1550  ret = TRUE;
1551  while(ret == TRUE){
1552  ret = AdvanceToNextEvent(pos,true);
1553  if(ret > 0){num_events++;}
1554  }
1555  if(ret == FALSE){indexBuilt = FULL_INDEX; return TRUE;}
1556  if(ret == FAIL){indexBuilt = PARTIAL_INDEX; return FALSE;}
1557  }
1558  return FALSE;
1559 }
1560 
1561 int RawFileParser::BuildEventIndex_file(int max_idx, bool force_rebuild){
1562  int ret;
1563  int num_events;
1564  off_t current_event_position;
1565 
1566  // Guard against rebuilding the index
1567  // except when asked to do it
1568  if(indexBuilt==FULL_INDEX){
1569  if(!force_rebuild){
1570  return TRUE;
1571  }
1572  }
1573 
1574  if(force_rebuild){
1575  event_offset_list.clear();
1576  indexBuilt = NO_INDEX;
1577  num_events = 0;
1578  }else{
1579  num_events = current_event_index;
1580  }
1581 
1582  // Now go and build the index
1583  while(true){
1584  ret = AdvanceToEvent(current_event_position,true);
1585 
1586  if(ret == TRUE){
1587  ++num_events;
1589  continue;
1590  }
1591 
1592  if(ret == 0){
1593  // We have reached the end of the file and should have
1594  // all the events indexed
1595  indexsize = num_events;
1597  return TRUE;
1598  }
1599 
1600  if(ret < 0){
1601  // An error occured
1602  DEBUGMSG("Error Building event index at event %d\n",num_events+1);
1603  return FAIL;
1604  }
1605 
1606  // If we were requested to do only a partial rebuild
1607  // check the indexing here
1608  if(max_idx > 0){
1609  if(num_events > max_idx){return TRUE;}
1610  }
1611 
1612  } // endwhile
1613 
1614  return FALSE;
1615 }
1616 
1617 ssize_t RawFileParser::readEventSize(bool freemem_flag){
1618  if(memmap_io_flag){
1619  return readEventSize_mem(freemem_flag);
1620  }else{
1621  return readEventSize_file(freemem_flag);
1622  }
1623  return FAIL;
1624 }
1625 ssize_t RawFileParser::readEventSize_mem(bool freemem_flag){
1626  // With the memory mapped IO method we don't need
1627  // to worry about allocating any buffers
1628  RawEventHeader theHeader;
1629 
1630  // Ensure that we are on a current event boundary
1631  if(checkWord(EVENT_MARKER) != TRUE){
1632  return -1;
1633  }
1634 
1635  // Set the event to point at the current position in the
1636  // memory mapped file
1637  theHeader.setBufferSource(mmfile_current32);
1638 
1639  // Return the size of the event
1640  return theHeader.getEventSize();
1641 }
1642 
1643 ssize_t RawFileParser::readEventSize_file(bool freemem_flag){
1644  int bytes_read;
1645  uint32_t event_size;
1646  static unsigned char* header_buff=NULL; // Buffer pointer for 8bit aligned header data
1647 
1648  RawEventHeader theHeader;
1649 
1650  // Allocate a memory buffer for the header read
1651  if(header_buff == NULL){
1652  header_buff = (unsigned char*) malloc(theHeader.sizeofdata()*sizeof(uint32_t));
1653  }
1654 
1655  // Assume that the current seek point of the
1656  // file descriptor points to the start of a RawEvent
1657  bytes_read = ::read(infile, header_buff, theHeader.sizeofdata()*sizeof(uint32_t));
1658 
1659  // Check for end of file or read error
1660  if(bytes_read < 0){
1661  // We have a read error
1662  perror("File read error during event header read");
1663  return FAIL;
1664  }
1665 
1666  if(bytes_read == 0){
1667  // We have reached the end of the file
1668  DEBUGMSG("End of file reached during event header read");
1669  return FALSE;
1670  }
1671 
1672  // Check for incomplete reads
1673  if(bytes_read != (int)(theHeader.sizeofdata()*sizeof(uint32_t))){
1674  perror("Incomplete read encountered while reading event header");
1675  return FAIL;
1676  }
1677 
1678  // Point the header to the input buffer we just filled
1679  theHeader.setBufferSource(header_buff);
1680 
1681  // We extract the full event size
1682  event_size = theHeader.getEventSize();
1683 
1684  // Rewind our read point
1685  backup(bytes_read);
1686 
1687  // If we were passed the flag to cleanup our memory
1688  // buffer, we free it now
1689  if(freemem_flag){
1690  if(header_buff != NULL){
1691  free(header_buff);
1692  }
1693  }
1694 
1695  // Return the size of the event in bytes
1696  return (event_size)*(sizeof(uint32_t));
1697 
1698 }
1699 
1700 //
1701 // Utility functions to search for a given 32bit word
1702 //
1703 int RawFileParser::wordsearch(unsigned int searchword){
1704  if(memmap_io_flag){
1705  return wordsearch_mem(searchword);
1706  }else{
1707  return wordsearch_file(searchword);
1708  }
1709  return FALSE;
1710 }
1711 
1712 int RawFileParser::wordsearchreverse(unsigned int searchword){
1713  if(memmap_io_flag){
1714  return wordsearchreverse_mem(searchword);
1715  }else{
1716  // return wordsearch_file(searchword);
1717  return FALSE;
1718  }
1719  return FALSE;
1720 }
1721 
1722 int RawFileParser::wordsearch_mem(unsigned int searchword){
1723  uint32_t* start_pos;
1724  bool notfound = true;
1725 
1726  DEBUGMSG("Current is %p, end of file is %p, and start is %p\n", mmfile_current32, mmfile_end32, mmfile_start32)
1727  start_pos = mmfile_current32;
1728  if(start_pos < mmfile_start32) {
1729  start_pos = mmfile_start32;
1731  }
1732 
1733  while(notfound){ ;
1735  DEBUGMSG("End of file reached, no event block found\n");
1736  mmfile_current32 = start_pos;
1737  return FALSE;
1738  }
1739 
1740  if(*mmfile_current32 == searchword){
1741  notfound = false;
1742  return TRUE;
1743  }
1744 
1746  ++mmfile_current32;
1747  }
1748 
1749  } // endwhile
1750 
1751  return FALSE;
1752 }
1753 
1754 int RawFileParser::wordsearchreverse_mem(unsigned int searchword){
1755  uint32_t* start_pos;
1756  bool notfound = true;
1757 
1758  start_pos = mmfile_current32;
1759 
1760  while(notfound){
1761 
1763  DEBUGMSG("End of file reached, no event block found\n");
1764  mmfile_current32 = start_pos;
1765  return FALSE;
1766  }
1767 
1768  if(*mmfile_current32 == searchword){
1769  notfound = false;
1770  return TRUE;
1771  }
1772 
1774  --mmfile_current32;
1775  }
1776 
1777  } // endwhile
1778 
1779  return FALSE;
1780 }
1781 
1782 int RawFileParser::wordsearch_file(unsigned int searchword){
1783 
1784  // Make sure we have a file open
1785  if(!fileopenned){
1786  DEBUGMSG("wordsearch(): File not openned for parsing\n");
1787  return FALSE;
1788  }
1789 
1790  off_t start_pos;
1791  // Record the current file position
1792  if( savepos(start_pos) < 0){
1793  DEBUGMSG("wordsearch(): unable to save file position\n");
1794  return FAIL;
1795  };
1796 
1797  int bytes_read = -1;
1798  unsigned int buff = 0;
1799  /// Need to make sure that it's going to start search
1800  if(buff == searchword) buff = searchword + 1;
1801  // Parse through the file from the current position
1802  // look for the searchword
1803  while(buff != searchword){
1804  bytes_read = ::read(infile, &buff, sizeof(int));
1805 
1806  // Check for errors on the read
1807  switch(bytes_read){
1808  case -1:
1809  perror("Read from file failed during event header search");
1810  rewind(start_pos);
1811  return FAIL;
1812  break;
1813  case 0:
1814  DEBUGMSG("End of file reached, no event block found\n");
1815 
1816  // Rewind the file to where we started from
1817  rewind(start_pos);
1818  return FALSE;
1819  break;
1820  default:
1821  // Our read returned the right number of bytes so we
1822  // continue to the next block
1823  break;
1824  }// end of switch
1825 
1826  } // endwhile
1827 
1828  // We have found our search word. Hurrah!
1829 
1830  // Rewind the current file pointer by 4 bytes to position
1831  // it at the start of the event block
1832  if( backup(bytes_read) < 0 ){
1833  DEBUGMSG("Unable to rewind file in wordsearch()\n");
1834  return FAIL;
1835  };
1836 
1837  // Set the file position to the current position
1838  filepos = curpos();
1839 
1840  // Return success
1841  return TRUE;
1842 
1843 }
1844 
1845 int RawFileParser::checkWord(unsigned int testword){
1846  if(memmap_io_flag){
1847  return checkWord_mem(testword);
1848  }else{
1849  return checkWord_file(testword);
1850  }
1851  return FALSE;
1852 }
1853 
1854 int RawFileParser::checkWord_mem(unsigned int testword){
1855  // Guard against going out of bounds on the memory map
1856  if(mmfile_current32 > (mmfile_end32 - 1)){ return FAIL;}
1857 
1858  if(*mmfile_current32 == testword){
1859  return TRUE;
1860  }else{
1861  return FALSE;
1862  }
1863  return FALSE;
1864 }
1865 
1866 int RawFileParser::checkWord_file(unsigned int testword){
1867  unsigned int buff;
1868  int bytes_read;
1869 
1870  bytes_read = ::read(infile, &buff, sizeof(unsigned int));
1871 
1872  // Check for errors on the read
1873  switch(bytes_read){
1874  case -1:
1875  perror("Read Failed during checkWord()");
1876  return FAIL;
1877  break;
1878  case 0:
1879  DEBUGMSG("End of file reached during checkWord()\n");
1880  return FAIL;
1881  break;
1882  default:
1883  // Our read returned the right number of bytes so we
1884  // continue to the next block
1885  break;
1886  }
1887 
1888  // rewind back to where we started
1889  if(backup(bytes_read) < 0){
1890  perror("Unable to rewind file in checkWord()");
1891  return FAIL;
1892  }
1893 
1894  if( buff == testword){
1895  return TRUE;
1896  }else{
1897  return FALSE;
1898  }
1899  return FALSE;
1900 }
1901 
1903  position = lseek(infile, 0, SEEK_CUR);
1904 
1905  if(position < 0){
1906  perror("Unable to save file position, savepos()");
1907  position = 0;
1908  return -1;
1909  }
1910 
1911  return position;
1912 }
1913 
1914 //
1915 // Utility Function for dumping a buffer
1916 //
1917 void RawFileParser::dumpBuffer(int bytes, int col){
1918  int i;
1919  int words;
1920 
1921  if(isMemoryMappedIO()){
1922  words = bytes/sizeof(int);
1923  for(i=0; i<words; ++i){
1924  printf("0x%08x ",mmfile_current32[i]);
1925  if(((i+1)%col)==0){DEBUGMSG("\n");}
1926  }
1927  printf("\n");
1928  return;
1929  }
1930 
1931 }
1932 
1933 void RawFileParser::dumpBuffer(void* buff, int bytes, int col){
1934  int i;
1935  int words;
1936  int* buff32;
1937  buff32 = (int*)buff;
1938  words = bytes/sizeof(int);
1939  for(i=0; i<words; ++i){
1940  printf("0x%08x ",buff32[i]);
1941  if(((i+1)%col)==0){DEBUGMSG("\n");}
1942  }
1943  printf("\n");
1944  return;
1945 }
1946 
1947 //
1948 // Utility Functions for verifying buffers
1949 //
1951  uint32_t* buff32;
1952  buff32 = (uint32_t*)buff;
1953 
1954  if((buff32[0]==NOVA_ASCII) && (buff32[1]==E929_ASCII)){
1955  return true;
1956  }else{
1957  return false;
1958  }
1959  return false;
1960 }
1961 
1963  uint32_t* buff32;
1964  RawConfigurationHeader theConfigHeader;
1965 
1966  buff32 = (uint32_t*)buff;
1967 
1968  if( (buff32[0]==theConfigHeader.getMarkerHi1()) && (buff32[1]==theConfigHeader.getMarkerHi2())){
1969  return true;
1970  }else{
1971  return false;
1972  }
1973  return false;
1974 }
1975 
1977  uint32_t* buff32;
1978  buff32 = (uint32_t*)buff;
1979 
1980  if(buff32[0]==EVENT_MARKER){
1981  return true;
1982  }else{
1983  return false;
1984  }
1985  return false;
1986 }
1987 
1988 bool RawFileParser::checkEvent(void* buff){
1989  uint32_t* buff32;
1990  buff32 = (uint32_t*)buff;
1991 
1992  if(buff32[0]==EVENT_MARKER){
1993  return true;
1994  }else{
1995  return false;
1996  }
1997  return false;
1998 }
1999 
2001  uint32_t* buff32;
2002  buff32 = (uint32_t*)buff;
2003 
2004  if(buff32[0]==TAIL_MARKER){
2005  return true;
2006  }else{
2007  return false;
2008  }
2009  return false;
2010 }
2011 
2013  int ret;
2014  off_t pos;
2015 
2016  // Move to the position of the Run Header
2017  ret = AdvanceToRunHeader(pos);
2018 
2019  // Check that we found it correctly
2020  switch(ret){
2021  case TRUE:
2022  // Set the buffer source of the RunHeader Object to the current position
2023  theRunHeader.setBufferSource(mmfile_current);
2024  break;
2025  }
2026  return ret;
2027 }
2028 
2030  int ret;
2031  off_t pos;
2032 
2033  // Move to the position of the Run Header
2034  ret = AdvanceToRunTail(pos);
2035 
2036  // Check that we found it correctly
2037  switch(ret){
2038  case TRUE:
2039  // Set the buffer source of the RunHeader Object to the current position
2040  theRunTail.setBufferSource(mmfile_current);
2041  break;
2042  }
2043  return ret;
2044 }
2045 
2047  int ret;
2048  off_t pos;
2049 
2050  // Move to the position of the Run Header
2051  ret = AdvanceToConfigStart(pos);
2052 
2053  // Check that we found it correctly
2054  switch(ret){
2055  case TRUE:
2056  // Set the buffer source of the RunHeader Object to the current position
2057  theConfigBlock.setBufferSource(mmfile_current);
2058  break;
2059  }
2060  return ret;
2061 }
2062 
2064  int ret;
2065  off_t pos;
2066 
2067  // Move to the position of the Run Header
2068  ret = AdvanceToFirstEvent(pos);
2069 
2070  // Check that we found it correctly
2071  switch(ret){
2072  case TRUE:
2073  // Set the buffer source of the RunHeader Object to the current position
2074  theEvent.setBufferSource(mmfile_current);
2075  break;
2076  }
2077  return ret;
2078 }
2079 
2081  int ret;
2082  off_t pos;
2083 
2084  // Move to the position of the Run Header
2085  ret = AdvanceToPreviousEvent(pos,true);
2086 
2087  // Check that we found it correctly
2088  switch(ret){
2089  case TRUE:
2090  // Set the buffer source of the RunHeader Object to the current position
2091  theEvent.setBufferSource(mmfile_current);
2092  return TRUE;
2093  break;
2094  }
2095  return ret;
2096 }
2097 
2099  int ret;
2100  off_t pos;
2101 
2102  // Move to the position of the Run Header
2103  ret = AdvanceToNextEvent(pos,true);
2104 
2105  // Check that we found it correctly
2106  switch(ret){
2107  case TRUE:
2108  // Set the buffer source of the RunHeader Object to the current position
2109  theEvent.setBufferSource(mmfile_current);
2110  return TRUE;
2111  break;
2112  }
2113  return ret;
2114 }
2115 
2117  int ret;
2118  off_t pos;
2119  uint32_t s;
2120  static RawEvent tmpEvent;
2121 
2122  // Move to the position of the Run Header
2123  ret = AdvanceToEvent(pos,true);
2124 
2125  if(ret){
2126  tmpEvent.setBufferSource(mmfile_current);
2127  s = tmpEvent.getEventSize();
2128  if( (mmfile_current32+s) > mmfile_end32){
2129  return FALSE;
2130  }
2131  }
2132 
2133  // Check that we found it correctly
2134  switch(ret){
2135  case TRUE:
2136  // Set the buffer source of the RunHeader Object to the current position
2137  theEvent.setBufferSource(mmfile_current);
2138  return TRUE;
2139  break;
2140  }
2141  return ret;
2142 }
2143 
2144 int RawFileParser::getEvent(RawEvent& theEvent, int event_no){
2145  int ret;
2146 
2147  // Move to the position of the Run Header
2148  ret = GotoEvent(event_no);
2149 
2150  // Check that we found it correctly
2151  switch(ret){
2152  case TRUE:
2153  // Set the buffer source of the RunHeader Object to the current position
2154  theEvent.setBufferSource(mmfile_current);
2155  return TRUE;
2156  break;
2157  }
2158  return ret;
2159 }
int wordsearch(unsigned int searchword)
int open(const char *filename)
General initialization and reinitialization.
int AdvanceToConfigStart_file(off_t &conf_start_pos)
int AdvanceToNextEvent_file(off_t &next_event_pos, bool index_entries=false)
int BuildEventIndex(int max_idx=-1, bool force_rebuilt=false)
Return the type of file that is open.
int AdvanceToNextEvent_mem(off_t &next_event_pos, bool index_entries=false)
int checkWord_file(unsigned int testword)
Memory mapped IO version.
int AdvanceToRunHeader_mem(off_t &header_pos)
Method that builds a full event index.
int AdvanceToRunTail(off_t &tail_start_pos)
Moves to the end of the configuration block.
off_t forward(size_t bytes)
int AdvanceToRunTail_mem(off_t &tail_start_pos)
int GotoEvent_file(int event_no)
Direct access method for events.
int GotoEvent(int event_no)
Moves to the start of the run tail block.
bool checkRunHeader(void *buff)
Return the current parse position address as an unsigned 32bit int*.
void dumpBuffer(int bytes=128, int col=4)
Check if the buffer is a valid Run Tail.
int wordsearch_mem(unsigned int searchword)
int getRunHeader(daqdataformats::RawRunHeader &theRunHeader)
Method that builds a full event index.
std::vector< uint32_t * > event_addr_list
int CheckFileType_file()
File type checking for memory mapped IO.
int AdvanceToFirstEvent(off_t &first_event_pos, bool index_entries=false)
Moves the current parse point to the Config Block start.
int AdvanceToConfigStart(off_t &conf_start_pos)
Moves the current parse point to the Run header.
string filename
Definition: shutoffs.py:106
int wordsearch_file(unsigned int searchword)
int getPreviousEvent(daqdataformats::RawEvent &theEvent)
Retrieve the Nth event from the file.
int checkWord(unsigned int testword)
File type checking for raw file IO.
int wordsearchreverse_mem(unsigned int searchword)
ssize_t readEventSize_mem(bool freemem_flag=false)
int CheckFileType_mem()
Search for the given 32bit word in the file.
bool isMemoryMappedIO()
Set the access mode for IO calls (Memory Mapped or system read)
Definition: RawFileParser.h:67
int AdvanceToFirstEvent_mem(off_t &first_event_pos, bool index_entries=false)
const XML_Char * s
Definition: expat.h:262
off_t savepos(off_t &position)
int AdvanceToPreviousEvent_mem(off_t &next_event_pos, bool index_entries=false)
~RawFileParser()
Constructor with input filename (file is openned)
int AdvanceToConfigEnd(off_t &conf_end_pos)
Moves to the most appropriate event in the file.
std::vector< off_t > event_offset_list
int wordsearchreverse(unsigned int searchword)
Search for the given 32bit word in the file.
int CheckFileType()
Obtain the current IO access mode.
string infile
int GotoEvent_mem(int event_no)
Raw file IO version.
bool checkConfigStart(void *buff)
Check if the buffer is a valid Run Header.
Int_t col[ntarg]
Definition: Style.C:29
int close()
Open a file for parsing.
printf("%d Experimental points found\n", nlines)
ssize_t readEventSize(bool freemem_flag=false)
bool checkEvent(void *buff)
Check if the buffer is a valid Event Header.
#define TRUE
bool checkEventHeader(void *buff)
Check if the buffer is a valid Run configuration block.
#define off_t
Definition: macconfig.h:47
int AdvanceToRunHeader(off_t &header_pos)
Retrieve the run header from the file.
int AdvanceToFirstEvent_file(off_t &first_event_pos, bool index_entries=false)
static const char * filetypes[]
Definition: RawFileParser.h:51
int BuildEventIndex_mem(int max_idx=-1, bool force_rebuilt=false)
Direct access method for events.
ssize_t readEventSize_file(bool freemem_flag=false)
int checkWord_mem(unsigned int testword)
Check if the word currently pointed to in the file matches the test word.
int BuildEventIndex_file(int max_idx=-1, bool force_rebuilt=false)
Method that builds a full event index.
int AdvanceToConfigStart_mem(off_t &conf_start_pos)
int getFileType()
Attempt to determine the type of file that is open.
int getNextEvent(daqdataformats::RawEvent &theEvent)
Retrieve the first event from the file.
int getRunTail(daqdataformats::RawRunHeader &theRunTail)
Retrieve the previous event from the file.
int getEvent(daqdataformats::RawEvent &theEvent)
Retrieve the next event from the file.
#define FALSE
int AdvanceToPreviousEvent(off_t &next_event_pos, bool index_entries=false)
Moves the current parse point to the Next event in the file.
Class to hold the data from the FEBs in correct formats.
#define FAIL
off_t rewind(off_t position)
int getFirstEvent(daqdataformats::RawEvent &theEvent)
Retrieve the configuration block from the file.
int AdvanceToEvent(off_t &event_pos, bool index_entries=false)
Moves the current parse point to the Previous event in the file.
int AdvanceToRunTail_file(off_t &tail_start_pos)
int AdvanceToNextEvent(off_t &next_event_pos, bool index_entries=false)
Moves the current parse point to the First event in the file.
bool checkRunTail(void *buff)
Check if the buffer is a valid Event.
int AdvanceToRunHeader_file(off_t &header_pos)
int getConfigBlock(daqdataformats::RawConfigurationBlock &theConfigBlock)
Retrieve the run header from the file.
off_t backup(size_t bytes)
Return the raw file descriptor of the file that has been opened by the parser.
#define DEBUGMSG(...)