#include "TrbBridgeTrbNetHeaders.hpp" #include template < typename MAJOR, typename MINOR = uint8_t > static MAJOR _swapEndianess(MAJOR a) { MAJOR b; MINOR* src = reinterpret_cast(&a); MINOR* dest = reinterpret_cast(&b); constexpr unsigned int steps = sizeof(MAJOR)/sizeof(MINOR); for(unsigned int i=0; itm_year & 0xff) << 16) | (parts->tm_mon << 8) | (parts->tm_mday << 0); buffer[5] = (parts->tm_hour << 16) | (parts->tm_min << 8) | (parts->tm_sec << 0); buffer[6] = runNumber; buffer[7] = 0; if (swappedEndianess) for(unsigned int i=0; i<8; i++) buffer[i] = _swapEndianess(buffer[i]); } void TrbBridgeTrbNetEventHeader::loadFromBuffer(const uint32_t* buffer) { uint32_t* src = const_cast(buffer); struct tm parts; if (buffer[1] > 0x100000) { // need to swap endianess src = new uint32_t[8]; for(unsigned int i = 0; i < 8; i++) src[i] = _swapEndianess(buffer[i]); swappedEndianess = true; } else { swappedEndianess = false; } size = src[0]; triggerType = uint16_t(src[2]); eventNumberPerFile = src[3]; runNumber = src[6]; parts.tm_year = (src[4] >> 16) & 0xff; parts.tm_mon = (src[4] >> 8) & 0xff; parts.tm_mday = (src[4] >> 0) & 0xff; parts.tm_hour = (src[5] >> 16) & 0xff; parts.tm_min = (src[5] >> 8) & 0xff; parts.tm_sec = (src[5] >> 0) & 0xff; timestamp = std::mktime(&parts); if (src != buffer) delete[] src; } TrbBridgeTrbNetEventHeader TrbBridgeTrbNetEventHeader::operator<<(const uint32_t* buffer) { loadFromBuffer(buffer); return *this; } uint32_t* operator<<(uint32_t* buffer, const TrbBridgeTrbNetEventHeader & evtHdr) { evtHdr.writeToBuffer(buffer); return buffer; } /************************************************* * SubEventHeader *************************************************/ void TrbBridgeTrbNetSubEventHeader::writeToBuffer(uint32_t *buffer) const { buffer[0] = size; buffer[1] = 0x00020001 | ((triggerType & 0xf) << 4); buffer[2] = subEventId; buffer[3] = (triggerNumber << 8) | triggerCode; if (swappedEndianess) for(unsigned int i=0; i<4; i++) buffer[i] = _swapEndianess(buffer[i]); } void TrbBridgeTrbNetSubEventHeader::loadFromBuffer(const uint32_t* buffer) { uint32_t* src = const_cast(buffer); if (buffer[1] > 0x100000) { // need to swap endianess src = new uint32_t[4]; for(unsigned int i = 0; i < 4; i++) src[i] = _swapEndianess(buffer[i]); swappedEndianess = true; } else { swappedEndianess = false; } size = src[0]; triggerType = (src[1] >> 4) & 0xf; subEventId = src[2]; triggerCode = uint8_t(src[3]); triggerNumber = src[3] >> 8; if (src != buffer) delete[] src; } TrbBridgeTrbNetSubEventHeader TrbBridgeTrbNetSubEventHeader::operator<<(const uint32_t* buffer) { loadFromBuffer(buffer); return *this; } uint32_t* operator<<(uint32_t* buffer, const TrbBridgeTrbNetSubEventHeader & subEvtHdr) { subEvtHdr.writeToBuffer(buffer); return buffer; } /************************************************* * SubEventHeader *************************************************/ TrbBridgeTrbNetSubSubEventHeader::TrbBridgeTrbNetSubSubEventHeader(unsigned int ssEvtId, unsigned int sze, uint32_t* buf) : subSubEventId(ssEvtId) , size(sze) , payload(buf) {} std::list TrbBridgeTrbNetSubSubEventHeader::extractSubSubEvents( const TrbBridgeTrbNetSubEventHeader & subEventHeader, uint32_t* buffer) throw (TrbBridgeTrbNetHeaderException) { std::list result; unsigned int wordIdx = 4; // skip sub-event header while(wordIdx < subEventHeader.size/4) { uint16_t id = buffer[wordIdx] & 0xffff; unsigned int sseSize = 4 + 4*(buffer[wordIdx]>>16); // length (excl. header in words) -> size (incl. header in bytes) result.push_back( TrbBridgeTrbNetSubSubEventHeader( id, sseSize, &buffer[wordIdx+1]) ); wordIdx += sseSize / 4; } if (wordIdx != subEventHeader.size/4) throw TrbBridgeTrbNetHeaderException("Sum of sub-sub-event length exceeds sub-event size"); return result; }