@@ -27,6 +27,10 @@ template <typename T>
2727unsigned int RawBuffer<T>::next(unsigned int nBits)
2828{
2929 // / Reads the next nBits
30+ if (mNextHeaderIndex == 0 ) {
31+ // This is the first entry
32+ nextPayload ();
33+ }
3034 unsigned int value = 0 ;
3135 for (int ibit = 0 ; ibit < nBits; ++ibit) {
3236 if (mBitIndex == mElementSizeInBits ) {
@@ -51,31 +55,42 @@ T RawBuffer<T>::next()
5155 return mBytes [mElementIndex ++];
5256}
5357
58+ template <typename T>
59+ bool RawBuffer<T>::nextHeader()
60+ {
61+ // / Goes to next RDH
62+ if (mNextHeaderIndex >= mBytes .size ()) {
63+ // This is the end of the buffer
64+ if (mUnconsumed .empty ()) {
65+ mElementIndex = mNextHeaderIndex ;
66+ mEndOfPayloadIndex = mNextHeaderIndex ;
67+ return false ;
68+ }
69+ // We were reading the unconsumed part: switch to new buffer
70+ mUnconsumed .clear ();
71+ reset ();
72+ mBytes = mCurrentBuffer ;
73+ }
74+ mHeaderIndex = mNextHeaderIndex ;
75+ mRDH = reinterpret_cast <const header::RAWDataHeader*>(&mBytes [mHeaderIndex ]);
76+ mEndOfPayloadIndex = mHeaderIndex + (mRDH ->memorySize / mElementSizeInBytes );
77+ // Go to end of header, i.e. beginning of payload
78+ mElementIndex = mHeaderIndex + (mRDH ->headerSize / mElementSizeInBytes );
79+ mNextHeaderIndex = mHeaderIndex + mRDH ->offsetToNext / mElementSizeInBytes ;
80+ mBitIndex = 0 ;
81+
82+ return true ;
83+ }
84+
5485template <typename T>
5586bool RawBuffer<T>::nextPayload()
5687{
5788 // / Goes to next payload
5889 while (mElementIndex == mEndOfPayloadIndex ) {
59- if (mNextHeaderIndex == mBytes .size ()) {
60- // This is the end of the buffer
61- if (mUnconsumed .empty ()) {
62- mElementIndex = mNextHeaderIndex ;
63- mEndOfPayloadIndex = mNextHeaderIndex ;
64- return false ;
65- }
66- // We were reading the unconsumed part: switch to new buffer
67- mUnconsumed .clear ();
68- reset ();
69- mBytes = mCurrentBuffer ;
90+ if (!nextHeader ()) {
91+ return false ;
7092 }
71- mRDH = reinterpret_cast <const header::RAWDataHeader*>(&mBytes [mNextHeaderIndex ]);
72- mEndOfPayloadIndex = mNextHeaderIndex + (mRDH ->memorySize / mElementSizeInBytes );
73- // Go to end of header, i.e. beginning of payload
74- mElementIndex = mNextHeaderIndex + (mRDH ->headerSize / mElementSizeInBytes );
75- mNextHeaderIndex += mRDH ->offsetToNext / mElementSizeInBytes ;
76- mBitIndex = 0 ;
7793 }
78-
7994 return true ;
8095}
8196
@@ -84,6 +99,7 @@ void RawBuffer<T>::reset()
8499{
85100 // / Rewind bytes
86101 mElementIndex = 0 ;
102+ mHeaderIndex = 0 ;
87103 mNextHeaderIndex = 0 ;
88104 mEndOfPayloadIndex = 0 ;
89105 mBitIndex = 0 ;
@@ -92,21 +108,23 @@ void RawBuffer<T>::reset()
92108}
93109
94110template <typename T>
95- void RawBuffer<T>::setBuffer(gsl::span<const T> bytes, bool keepUnconsumed )
111+ void RawBuffer<T>::setBuffer(gsl::span<const T> bytes, ResetMode resetMode )
96112{
97113 // / Sets the buffer and reset the internal indexes
98- if (keepUnconsumed && !mUnconsumed .empty ()) {
114+ if (resetMode == ResetMode:: keepUnconsumed && !mUnconsumed .empty ()) {
99115 // There are some unconsumed bytes from the previous buffer
100- mNextHeaderIndex = mUnconsumed .size ();
101- mEndOfPayloadIndex -= mElementIndex ;
102- mElementIndex = 0 ;
116+ mNextHeaderIndex -= mHeaderIndex ;
117+ mEndOfPayloadIndex -= mHeaderIndex ;
118+ mElementIndex -= mHeaderIndex ;
119+ mHeaderIndex = 0 ;
103120 mBytes = gsl::span<const T>(mUnconsumed );
104121 } else {
105122 mBytes = bytes;
106- reset ();
123+ if (resetMode != ResetMode::bufferOnly) {
124+ reset ();
125+ }
107126 }
108127 mCurrentBuffer = bytes;
109- nextPayload ();
110128}
111129
112130template <typename T>
@@ -144,29 +162,16 @@ bool RawBuffer<T>::hasNext(unsigned int nBytes)
144162 // With lot of memory left in the buffer but no payload
145163 nextPayload ();
146164 bool isOk = mCurrentBuffer .size () + mUnconsumed .size () - mNextHeaderIndex + mEndOfPayloadIndex - mElementIndex >= nBytes / mElementSizeInBytes ;
147- if (!isOk) {
165+ if (!isOk && mElementIndex != mCurrentBuffer . size () ) {
148166 // Store the remaining bits for further use
149- // We need to do it here because we know that the vector of which the mBytes is just a spas, is valid
150- // If we do it in set buffer, this might not be the case anymore
151- std::copy (mBytes .begin () + mElementIndex , mBytes .end (), std::back_inserter (mUnconsumed ));
167+ // We need to do it here because the vector of which the mBytes is just a span might not be valid afterwards
168+ // (e.g. when we do the next setBuffer)
169+ // If we do not want to invalidate the mRDH pointer, we need to copy bytes from the last header
170+ mUnconsumed .insert (mUnconsumed .end (), mBytes .begin () + mHeaderIndex , mBytes .end ());
152171 }
153172 return isOk;
154173}
155174
156- template <typename T>
157- bool RawBuffer<T>::nextHeader(gsl::span<const T> bytes)
158- {
159- // / Go to next header
160- // / This is only useful when one reads from file
161- // / and wants to read up to the next header to find out how many bytes to read next
162- mBytes = bytes;
163- if (mElementIndex >= mBytes .size ()) {
164- reset ();
165- }
166- mEndOfPayloadIndex = mElementIndex ;
167- return nextPayload ();
168- }
169-
170175template class RawBuffer <raw::RawUnit>;
171176template class RawBuffer <uint8_t >;
172177
0 commit comments