#ifndef __JDAQFRAME__ #define __JDAQFRAME__ #include #include #include #include #include "JIO/JSerialisable.hh" #include "JDAQ/JDAQHit.hh" #include "JDAQ/JDAQRoot.hh" #include "JDAQ/JDAQException.hh" namespace KM3NETDAQ { namespace { using JIO::JReader; using JIO::JWriter; } /** * Subset of data frame. **/ class JDAQFrameSubset { public: typedef const JDAQHit* const_iterator; typedef std::reverse_iterator const_reverse_iterator; /** * Constructor. * * \param number_of_hits number of hits * \param data pointer to data */ JDAQFrameSubset(const int number_of_hits, const JDAQHit* data) : numberOfHits(number_of_hits), buffer(data) {} const_iterator begin() const { return buffer; } const_iterator end() const { return buffer + numberOfHits; } const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); } const_reverse_iterator rend() const { return const_reverse_iterator(begin()); } bool empty() const { return numberOfHits == 0; } int size() const { return numberOfHits; } const JDAQHit* data() const { return buffer; } private: const int numberOfHits; const JDAQHit* buffer; }; /** * Data frame. */ class JDAQFrame { public: typedef const JDAQHit* const_iterator; typedef JDAQHit* iterator; typedef std::reverse_iterator const_reverse_iterator; typedef std::reverse_iterator reverse_iterator; /** * Default constructor. */ JDAQFrame() : numberOfHits(0), buffer(NULL) {} /** * Copy constructor. * * \param frame JDAQ frame */ JDAQFrame(const JDAQFrame& frame) : numberOfHits(0), buffer(NULL) { add(frame); } /** * Constructor. * * \param number_of_hits number of hits * \param data pointer to data */ JDAQFrame(const int number_of_hits, const JDAQHit* data) : numberOfHits(0), buffer(NULL) { add(number_of_hits, data); } /** * Destructor. */ virtual ~JDAQFrame() { clear(); } /** * Clear data. */ void clear() { if (buffer != NULL) free(buffer); numberOfHits = 0; buffer = NULL; } const_iterator begin() const { return buffer; } const_iterator end() const { return buffer + numberOfHits; } iterator begin() { return buffer; } iterator end() { return buffer + numberOfHits; } const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); } const_reverse_iterator rend() const { return const_reverse_iterator(begin()); } reverse_iterator rbegin() { return reverse_iterator(end()); } reverse_iterator rend() { return reverse_iterator(begin()); } bool empty() const { return numberOfHits == 0; } int size() const { return numberOfHits; } const JDAQHit* data() const { return buffer; } JDAQHit* data() { return buffer; } /** * Get subset of data. * * \param i1 first hit * \param i2 last hit * \return JDAQ frame */ JDAQFrameSubset subset(const int i1, const int i2) const { return JDAQFrameSubset(i2 - i1, buffer + i1); } /** * Add data. * * \param frame JDAQ frame * \return this JDAQ frame */ JDAQFrame& add(const JDAQFrame& frame) { return add(frame.numberOfHits, frame.buffer); } /** * Add data. * * \param number_of_hits number of hits * \param data pointer to data * \return this data frame */ JDAQFrame& add(const int number_of_hits, const JDAQHit* data) { if (number_of_hits > 0) { resize(numberOfHits + number_of_hits); memcpy(buffer + numberOfHits - number_of_hits, data, number_of_hits * sizeof(JDAQHit)); } return *this; } /** * Swap data. * * \param frame JDAQ frame */ void swap(JDAQFrame& frame) { std::swap(numberOfHits, frame.numberOfHits); std::swap(buffer, frame.buffer); } /** * Read DAQ frame from input. * * \param in JReader * \param frame JDAQFrame * \return JReader */ friend inline JReader& operator>>(JReader& in, JDAQFrame& frame) { frame.clear(); int number_of_hits; in >> number_of_hits; frame.resize(number_of_hits); in.read((char*) frame.buffer, frame.numberOfHits * sizeof(JDAQHit)); return in; } /** * Write DAQ frame to output. * * \param out JWriter * \param frame JDAQFrame * \return JWriter */ friend inline JWriter& operator<<(JWriter& out, const JDAQFrame& frame) { out << frame.numberOfHits; out.write((char*) frame.buffer, frame.numberOfHits * sizeof(JDAQHit)); return out; } int numberOfHits; // following comment line is used by rootcint JDAQHit* buffer; // [numberOfHits] ClassDef(JDAQFrame,1); protected: /** * Resize internal buffer. * * This method increases the size of the buffer if necessary. * Otherwise, the current size is maintained. * * \param number_of_hits total number of hits to allocate */ void resize(const int number_of_hits) { if (number_of_hits > numberOfHits) { const int number_of_bytes = number_of_hits * sizeof(JDAQHit); if (buffer == NULL) buffer = (JDAQHit*) malloc(number_of_bytes); else buffer = (JDAQHit*) realloc(buffer, number_of_bytes); if (buffer == NULL) throw JDAQException("JDAQFrame::resize(): Memory exception."); numberOfHits = number_of_hits; } } }; } #endif