/
githubmirror
/
cmssw
Обзор
Документация
Войти
/
githubmirror
/
cmssw
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
IORawData/CSCCommissioning/src/FileReaderDDU.cc
152 строки
5 KB
Victor
code-checks and code-format applied
15 апр 2021, 06:42
15 апр 2021, 06:42
1d646ba
Код
Авторство
О чём код?
#include "FileReaderDDU.h" #include <cerrno> // errno #include <cstdlib> // exit #include <cstring> // bzero, memcpy #include <fcntl.h> // open #include <iostream> // cerr #include <sys/stat.h> // open #include <sys/types.h> // open #include <unistd.h> // read, close #ifndef O_LARGEFILE //for OSX #define O_LARGEFILE 0 #endif FileReaderDDU::FileReaderDDU(void) { if (sizeof(unsigned long long) != 8 || sizeof(unsigned short) != 2) throw std::runtime_error(std::string("Wrong platform: sizeof(unsigned long long)!=8 || sizeof(unsigned short)!=2")); end = (file_buffer_end = file_buffer + sizeof(file_buffer) / sizeof(unsigned long long)); bzero(raw_event, sizeof(raw_event)); bzero(file_buffer, sizeof(file_buffer)); word_0 = 0; word_1 = 0; word_2 = 0; eventStatus = 0; selectCriteria = Header | Trailer; rejectCriteria = DDUoversize | FFFF | Unknown; acceptCriteria = 0x3F; // Everything fd = 0; } FileReaderDDU::~FileReaderDDU(void) { if (fd) close(fd); } int FileReaderDDU::open(const char *filename) { if (fd) close(fd); fd = ::open(filename, O_RDONLY | O_LARGEFILE); if (fd == -1) throw(std::runtime_error(std::string("Error opening ").append(filename).append(" data file."))); return fd; } size_t FileReaderDDU::read(const unsigned short *&buf) { // Check for ubnormal situation if (end > file_buffer_end || end < file_buffer) throw(std::runtime_error("Error of reading")); if (!fd) throw(std::runtime_error("Open some file first")); unsigned long long *start = end; unsigned short *event = raw_event; eventStatus = 0; size_t dduWordCount = 0; end = nullptr; while (!end && dduWordCount < 50000) { unsigned long long *dduWord = start; unsigned long long preHeader = 0; // Did we reach end of current buffer and want to read next block? // If it was first time and we don't have file buffer then we won't get inside while (dduWord < file_buffer_end && dduWordCount < 50000) { word_0 = word_1; // delay by 2 DDU words word_1 = word_2; // delay by 1 DDU word word_2 = *dduWord; // current DDU word if ((word_2 & 0xFFFFFFFFFFFF0000LL) == 0x8000000180000000LL) { if (eventStatus & Header) // Second header { word_2 = word_1; // Fall back to get rigth preHeader next time end = dduWord; // Even if we end with preHeader of next evet put it to the end of this event too break; } if (dduWordCount > 1) // Extra words between trailer and header { if ((word_0 & 0xFFFFFFFFFFFF0000LL) == 0xFFFFFFFFFFFF0000LL) eventStatus |= FFFF; word_2 = word_1; // Fall back to get rigth preHeader next time end = dduWord; break; } eventStatus |= Header; if (event == raw_event) preHeader = word_1; // If preHeader not yet in event then put it there start = dduWord; } if ((word_0 & 0xFFFFFFFFFFFF0000LL) == 0x8000FFFF80000000LL) { eventStatus |= Trailer; end = ++dduWord; break; } // Increase counters by one DDU word dduWord++; dduWordCount++; } // If have DDU Header if (preHeader) { // Need to account first word of DDU Header memcpy(event, &preHeader, sizeof(preHeader)); event += sizeof(preHeader) / sizeof(unsigned short); } // Take care of the rest memcpy(event, start, (dduWord - start) * sizeof(unsigned long long)); event += (dduWord - start) * sizeof(unsigned long long) / sizeof(unsigned short); // If reach max length if (dduWordCount == 50000) { end = dduWord; break; } if (!end) { // Need to read next block for the rest of this event ssize_t length = ::read(fd, file_buffer, sizeof(file_buffer)); if (length == -1) throw(std::runtime_error("Error of reading")); if (length == 0) { eventStatus |= EndOfStream; end = (file_buffer_end = file_buffer + sizeof(file_buffer) / sizeof(unsigned long long)); break; } file_buffer_end = file_buffer + length / sizeof(unsigned long long); // Will start from the beginning of new buffer next time we read it start = file_buffer; } } if (!end) eventStatus |= DDUoversize; if (!(eventStatus & Header) && !(eventStatus & Trailer) && !(eventStatus & FFFF)) eventStatus |= Unknown; buf = (const unsigned short *)raw_event; return (eventStatus & FFFF ? event - raw_event - 4 : event - raw_event); } size_t FileReaderDDU::next(const unsigned short *&buf, int prescaling) { size_t size = 0; for (int i = 0; i < prescaling; i++) { do { if ((size = read(buf)) == 0) break; } while (rejectCriteria & eventStatus || !(acceptCriteria & eventStatus) || (selectCriteria ? selectCriteria != eventStatus : 0)); } return size; }