11#ifndef FRAMEWORK_UTILS_RAWPARSER_H
12#define FRAMEWORK_UTILS_RAWPARSER_H
107template <
typename HeaderType,
size_t MAX_SIZE,
bool BOUNDS_CHECKS>
120 template <
typename T>
124 static_assert(
sizeof(T) ==
sizeof(
buffer_type),
"buffer required to be byte-type");
126 std::runtime_error(
"buffer too small to fit at least the page header");
140 return *
reinterpret_cast<header_type const*
>(mPosition);
146 if (mPosition == mRawBuffer + mSize) {
150 if (
h.memorySize >=
h.headerSize) {
151 return h.memorySize -
h.headerSize;
159 if (mPosition == mRawBuffer + mSize) {
163 if (
h.memorySize >=
h.headerSize) {
177 return mPosition +
h.headerSize;
183 if (mPosition < mRawBuffer + mSize) {
192 if (mPosition < mRawBuffer + mSize) {
201 if (mPosition +
sizeof(
header_type) > mRawBuffer + mSize) {
205 if (
h.memorySize > MAX_SIZE ||
h.headerSize > MAX_SIZE) {
208 size_t pageSize =
h.memorySize >=
h.headerSize ?
h.memorySize : MAX_SIZE;
209 return mPosition + pageSize <= mRawBuffer + mSize;
216 template <
typename Processor>
222 if constexpr (BOUNDS_CHECKS) {
225 throw std::runtime_error(
"Corrupt RDH - RDH parsing ran out of raw data buffer");
228 LOG(error) <<
"RAWPARSER: Corrupt RDH - RDH parsing ran out of raw data buffer (" <<
RawParserHelper::sErrors <<
" total RawParser errors)";
242 int lastPacketCounter = -1;
243 int lastHBFPacketCounter = -1;
244 unsigned int lastFEEID = -1;
245 if (mPosition ==
nullptr) {
246 mPosition = mRawBuffer;
253 mPosition = mRawBuffer + mSize;
257 lastPacketCounter =
header().packetCounter;
258 lastHBFPacketCounter =
header().pageCnt;
259 lastFEEID =
header().feeId;
263 if constexpr (BOUNDS_CHECKS) {
266 throw std::runtime_error(
"Corrupt RDH - RDH parsing ran out of raw data buffer");
269 LOG(error) <<
"RAWPARSER: Corrupt RDH - RDH parsing ran out of raw data buffer (" <<
RawParserHelper::sErrors <<
" total RawParser errors)";
271 mPosition = mRawBuffer + mSize;
278 throw std::runtime_error(
"Corrupt RDH - Invalid RDH version");
281 LOG(error) <<
"RAWPARSER: Corrupt RDH - Invalid RDH Version " <<
header().version <<
" (expected " << HeaderType().version <<
") (" <<
RawParserHelper::sErrors <<
" total RawParser errors)";
283 mPosition = mRawBuffer + mSize;
287 if (lastPacketCounter != -1 && lastFEEID ==
header().feeId && ((
unsigned char)(lastPacketCounter + 1) !=
header().packetCounter && (
unsigned short)(lastHBFPacketCounter + 1) !=
header().pageCnt)) {
289 throw std::runtime_error(
"Incomplete HBF - jump in packet counter");
292 LOG(error) <<
"RAWPARSER: Incomplete HBF - jump in packet counter " << lastPacketCounter <<
" to " <<
header().packetCounter <<
" (" <<
RawParserHelper::sErrors <<
" total RawParser errors)";
294 mPosition = mRawBuffer + mSize;
304 mPosition = mRawBuffer;
316 mPosition = mRawBuffer + mSize;
318 while ((step-- > 0) &&
next()) {
330 template <
typename T = self_type>
333 if constexpr (std::is_same<T, self_type>::value ==
true) {
334 return mRawBuffer ==
other.mRawBuffer && mPosition ==
other.mPosition;
336 throw std::runtime_error(std::string(
"incompatible types for comparison ") +
typeid(T).
name() +
"/" +
typeid(
self_type).
name());
360template <
size_t N,
bool BOUNDS_CHECKS>
362template <
size_t N,
bool BOUNDS_CHECKS>
364template <
size_t N,
bool BOUNDS_CHECKS>
366template <
size_t N,
bool BOUNDS_CHECKS>
373template <
size_t N,
bool BOUNDS_CHECKS>
377template <
size_t PageSize,
bool BOUNDS_CHECKS,
typename T>
382 throw std::runtime_error(
"can not create RawParser: invalid buffer");
385 V5 const* v5 =
reinterpret_cast<V5 const*
>(
buffer);
397 throw std::runtime_error(
"can not create RawParser: invalid version " +
std::to_string(v5->
version));
402template <
size_t N,
typename T,
typename P>
405 if constexpr (N > 0) {
406 if (
index == N - 1) {
407 std::get<N - 1>(instances).parse(processor);
414template <
typename U,
typename T,
size_t N = std::variant_size_v<T>>
417 if constexpr (N > 0) {
418 auto* parser = std::get_if<N - 1>(&instances);
421 using parser_type =
typename std::variant_alternative<N - 1, T>
::type;
422 using header_type =
typename parser_type::header_type;
423 if constexpr (std::is_same<U, header_type>::value ==
true) {
424 return &(parser->header());
428 return get_if<U, T, N - 1>(instances);
464template <
size_t MAX_SIZE = 8192,
bool BOUNDS_CHECKS = true>
475 template <
typename T>
477 : mParser(raw_parser::create<MAX_SIZE, BOUNDS_CHECKS>(
buffer,
size))
479 static_assert(
sizeof(T) ==
sizeof(
buffer_type),
"buffer required to be byte-type");
484 template <
typename Processor>
487 constexpr size_t NofAlternatives = std::variant_size_v<
decltype(mParser)>;
488 static_assert(NofAlternatives == 4);
489 raw_parser::walk_parse<NofAlternatives>(mParser, processor, mParser.index());
497 return std::visit([](
auto& parser) {
return parser.reset(); }, mParser);
514 template <
typename T,
typename ParentType>
530 std::visit([&
start](
auto& parser) {parser.reset(); parser.advance(
start); }, mParser);
537 std::visit([](
auto& parser) { parser.next(); }, mParser);
550 return std::visit([](
auto& parser) {
return static_cast<reference>(parser.header()); }, mParser);
555 return std::visit([&
other](
auto& parser) {
return std::visit([&parser](
auto& otherParser) {
return parser == otherParser; },
568 return std::visit([](
auto& parser) {
return parser.raw(); }, mParser);
574 return std::visit([](
auto& parser) {
return parser.data(); }, mParser);
580 return std::visit([](
auto& parser) {
return parser.offset(); }, mParser);
586 return std::visit([](
auto& parser) {
return parser.size(); }, mParser);
592 return std::visit([](
auto& parser) {
return parser.sizeTotal(); }, mParser);
599 template <
typename U>
600 U
const*
get_if(U
const* =
nullptr)
const
602 return raw_parser::get_if<U>(mParser);
644 return std::visit([](
auto& parser) {
return parser.getNErrors(); }, mParser);
Class for time synchronization of RawReader instances.
size_t offset() const
offset of payload at current position
buffer_type const * raw() const
get pointer to raw block at current position, rdh starts here
size_t size() const
get size of payload at current position
size_t sizeTotal() const
get size of payload + header at current position
std::forward_iterator_tag iterator_category
friend std::ostream & operator<<(std::ostream &os, self_type const &it)
self_type operator++(int)
bool operator!=(const self_type &rh) const
buffer_type const * data() const
get pointer to payload at current position
bool operator==(const self_type &other) const
U const * get_if(U const *=nullptr) const
Iterator(parent_type parser, int start=0)
size_t getNErrors() const
unsigned char buffer_type
RawParser(T const *buffer, size_t size)
Constructor, raw buffer provided by pointer and size.
const_iterator begin() const
bool reset()
Reset parser and set position to beginning of buffer.
const_iterator end() const
static size_t const max_size
Iterator< RawDataHeaderInfo const, raw_parser::ConcreteParserVariants< MAX_SIZE, BOUNDS_CHECKS > > const_iterator
void parse(Processor &&processor)
Parse complete raw buffer and call processor on payload data for each page.
static void setCheckIncompleteHBF(bool v)
friend std::ostream & operator<<(std::ostream &os, self_type const &parser)
buffer_type const * data() const
Get pointer to payload data at current position.
buffer_type const * raw() const
Get pointer to raw buffer at current position.
bool next()
Move to next page start.
void format(std::ostream &os, FormatSpec choice=FormatSpec::Entry, const char *delimiter="\n") const
void parse(Processor &&processor)
ConcreteRawParser()=delete
size_t getNErrors() const
header_type const & header() const
Get header at current position.
unsigned char buffer_type
bool operator==(T const &other) const
static constexpr size_t max_size
size_t size() const
Get size of payload at current position.
ConcreteRawParser(ConcreteRawParser const &other)=default
size_t offset() const
Get offset of payload in the raw buffer at current position.
ConcreteRawParser(T const *buffer, size_t size)
bool checkPageInBuffer() const
size_t sizeTotal() const
Get size of header + payload at current position.
bool reset()
Reset the parser, set position to beginning of buffer.
GLuint const GLchar * name
GLint GLint GLsizei GLint GLenum GLenum type
ConcreteParserVariants< PageSize, BOUNDS_CHECKS > create(T const *buffer, size_t size)
create a raw parser depending on version of RAWDataHeader found at beginning of data
std::variant< V7Parser< N, BOUNDS_CHECKS >, V6Parser< N, BOUNDS_CHECKS >, V5Parser< N, BOUNDS_CHECKS >, V4Parser< N, BOUNDS_CHECKS > > ConcreteParserVariants
U const * get_if(T &instances)
FormatSpec
specifier for printout
void walk_parse(T &instances, P &&processor, size_t index)
Defining PrimaryVertex explicitly as messageable.
std::string to_string(gsl::span< T, Size > span)
static unsigned long sErrorLimit
static void warnDeadBeef(const o2::header::DataHeader *dh)
static bool checkPrintError(size_t &localCounter)
static int sCheckIncompleteHBF
static unsigned long sErrorScale
static unsigned long sErrors
VectorOfTObjectPtrs other
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"