File indexing completed on 2023-03-17 11:10:31
0001 #include "FileReaderDDU.h"
0002 #include <cerrno> // errno
0003 #include <cstdlib> // exit
0004 #include <cstring> // bzero, memcpy
0005 #include <fcntl.h> // open
0006 #include <iostream> // cerr
0007 #include <sys/stat.h> // open
0008 #include <sys/types.h> // open
0009 #include <unistd.h> // read, close
0010
0011 #ifndef O_LARGEFILE
0012 #define O_LARGEFILE 0
0013 #endif
0014
0015 FileReaderDDU::FileReaderDDU(void) {
0016 if (sizeof(unsigned long long) != 8 || sizeof(unsigned short) != 2)
0017 throw std::runtime_error(std::string("Wrong platform: sizeof(unsigned long long)!=8 || sizeof(unsigned short)!=2"));
0018 end = (file_buffer_end = file_buffer + sizeof(file_buffer) / sizeof(unsigned long long));
0019 bzero(raw_event, sizeof(raw_event));
0020 bzero(file_buffer, sizeof(file_buffer));
0021 word_0 = 0;
0022 word_1 = 0;
0023 word_2 = 0;
0024 eventStatus = 0;
0025 selectCriteria = Header | Trailer;
0026 rejectCriteria = DDUoversize | FFFF | Unknown;
0027 acceptCriteria = 0x3F;
0028 fd = 0;
0029 }
0030
0031 FileReaderDDU::~FileReaderDDU(void) {
0032 if (fd)
0033 close(fd);
0034 }
0035
0036 int FileReaderDDU::open(const char *filename) {
0037 if (fd)
0038 close(fd);
0039 fd = ::open(filename, O_RDONLY | O_LARGEFILE);
0040 if (fd == -1)
0041 throw(std::runtime_error(std::string("Error opening ").append(filename).append(" data file.")));
0042 return fd;
0043 }
0044
0045 size_t FileReaderDDU::read(const unsigned short *&buf) {
0046
0047 if (end > file_buffer_end || end < file_buffer)
0048 throw(std::runtime_error("Error of reading"));
0049 if (!fd)
0050 throw(std::runtime_error("Open some file first"));
0051
0052 unsigned long long *start = end;
0053 unsigned short *event = raw_event;
0054
0055 eventStatus = 0;
0056 size_t dduWordCount = 0;
0057 end = nullptr;
0058
0059 while (!end && dduWordCount < 50000) {
0060 unsigned long long *dduWord = start;
0061 unsigned long long preHeader = 0;
0062
0063
0064
0065 while (dduWord < file_buffer_end && dduWordCount < 50000) {
0066 word_0 = word_1;
0067 word_1 = word_2;
0068 word_2 = *dduWord;
0069 if ((word_2 & 0xFFFFFFFFFFFF0000LL) == 0x8000000180000000LL) {
0070 if (eventStatus & Header)
0071 {
0072 word_2 = word_1;
0073 end = dduWord;
0074 break;
0075 }
0076 if (dduWordCount > 1)
0077 {
0078 if ((word_0 & 0xFFFFFFFFFFFF0000LL) == 0xFFFFFFFFFFFF0000LL)
0079 eventStatus |= FFFF;
0080 word_2 = word_1;
0081 end = dduWord;
0082 break;
0083 }
0084 eventStatus |= Header;
0085 if (event == raw_event)
0086 preHeader = word_1;
0087 start = dduWord;
0088 }
0089 if ((word_0 & 0xFFFFFFFFFFFF0000LL) == 0x8000FFFF80000000LL) {
0090 eventStatus |= Trailer;
0091 end = ++dduWord;
0092 break;
0093 }
0094
0095 dduWord++;
0096 dduWordCount++;
0097 }
0098
0099
0100 if (preHeader) {
0101
0102 memcpy(event, &preHeader, sizeof(preHeader));
0103 event += sizeof(preHeader) / sizeof(unsigned short);
0104 }
0105
0106
0107 memcpy(event, start, (dduWord - start) * sizeof(unsigned long long));
0108 event += (dduWord - start) * sizeof(unsigned long long) / sizeof(unsigned short);
0109
0110
0111 if (dduWordCount == 50000) {
0112 end = dduWord;
0113 break;
0114 }
0115
0116 if (!end) {
0117
0118 ssize_t length = ::read(fd, file_buffer, sizeof(file_buffer));
0119 if (length == -1)
0120 throw(std::runtime_error("Error of reading"));
0121 if (length == 0) {
0122 eventStatus |= EndOfStream;
0123 end = (file_buffer_end = file_buffer + sizeof(file_buffer) / sizeof(unsigned long long));
0124 break;
0125 }
0126 file_buffer_end = file_buffer + length / sizeof(unsigned long long);
0127
0128
0129 start = file_buffer;
0130 }
0131 }
0132
0133 if (!end)
0134 eventStatus |= DDUoversize;
0135 if (!(eventStatus & Header) && !(eventStatus & Trailer) && !(eventStatus & FFFF))
0136 eventStatus |= Unknown;
0137
0138 buf = (const unsigned short *)raw_event;
0139 return (eventStatus & FFFF ? event - raw_event - 4 : event - raw_event);
0140 }
0141
0142 size_t FileReaderDDU::next(const unsigned short *&buf, int prescaling) {
0143 size_t size = 0;
0144 for (int i = 0; i < prescaling; i++) {
0145 do {
0146 if ((size = read(buf)) == 0)
0147 break;
0148 } while (rejectCriteria & eventStatus || !(acceptCriteria & eventStatus) ||
0149 (selectCriteria ? selectCriteria != eventStatus : 0));
0150 }
0151 return size;
0152 }