|
@@ -7,15 +7,76 @@
|
|
|
#include "eclrtl.hpp"
|
|
|
#include "eclhelper.hpp"
|
|
|
|
|
|
+//The CContiguousRowBuffer is a buffer used for reading ahead into a file, and unsuring there is a contiguous
|
|
|
+//block of data available to the reader. Fixed size files could use this directly.
|
|
|
+class ECLRTL_API CContiguousRowBuffer
|
|
|
+{
|
|
|
+public:
|
|
|
+ CContiguousRowBuffer() = default;
|
|
|
+ CContiguousRowBuffer(ISerialStream * _in);
|
|
|
+
|
|
|
+ void setStream(ISerialStream *_in);
|
|
|
+ const byte * peekBytes(size32_t maxSize);
|
|
|
+ const byte * peekFirstByte();
|
|
|
+ void skipBytes(size32_t size)
|
|
|
+ {
|
|
|
+ cur += size;
|
|
|
+ available -= size;
|
|
|
+ // call eos() to ensure stream->eos() is true if this class has got to the end of the stream
|
|
|
+ eos();
|
|
|
+ }
|
|
|
+
|
|
|
+ inline bool eos()
|
|
|
+ {
|
|
|
+ if (likely(available))
|
|
|
+ return false;
|
|
|
+ return checkInputEos();
|
|
|
+ }
|
|
|
+ inline offset_t tell() const { return in->tell() + (cur - buffer); }
|
|
|
+ inline const byte * queryRow() const { return cur; }
|
|
|
+ inline size_t maxAvailable() const { return available; }
|
|
|
+ inline void clearStream() { setStream(nullptr); }
|
|
|
+
|
|
|
+ inline void reset(offset_t offset, offset_t flen = (offset_t)-1)
|
|
|
+ {
|
|
|
+ in->reset(offset, flen);
|
|
|
+ clearBuffer();
|
|
|
+ }
|
|
|
+
|
|
|
+protected:
|
|
|
+ void peekBytesDirect(size32_t size); // skip any consumed data and directly peek bytes from the input
|
|
|
+
|
|
|
+private:
|
|
|
+ bool checkInputEos();
|
|
|
+ void clearBuffer()
|
|
|
+ {
|
|
|
+ buffer = nullptr;
|
|
|
+ cur = nullptr;
|
|
|
+ available = 0;
|
|
|
+ }
|
|
|
+
|
|
|
+protected:
|
|
|
+ const byte * cur = nullptr;
|
|
|
+private:
|
|
|
+ ISerialStream* in = nullptr;
|
|
|
+ const byte * buffer = nullptr;
|
|
|
+ size32_t available = 0;
|
|
|
+};
|
|
|
+
|
|
|
+
|
|
|
//The CThorContiguousRowBuffer is the source for a readAhead call to ensure the entire row
|
|
|
//is in a contiguous block of memory. The read() and skip() functions must be implemented
|
|
|
-class ECLRTL_API CThorContiguousRowBuffer : implements IRowPrefetcherSource
|
|
|
+class ECLRTL_API CThorContiguousRowBuffer : public CContiguousRowBuffer, implements IRowPrefetcherSource
|
|
|
{
|
|
|
public:
|
|
|
- CThorContiguousRowBuffer() {};
|
|
|
+ CThorContiguousRowBuffer() = default;
|
|
|
CThorContiguousRowBuffer(ISerialStream * _in);
|
|
|
|
|
|
- inline void setStream(ISerialStream *_in) { in = _in; maxOffset = 0; readOffset = 0; }
|
|
|
+ inline void setStream(ISerialStream *_in)
|
|
|
+ {
|
|
|
+ CContiguousRowBuffer::setStream(_in);
|
|
|
+ readOffset = 0;
|
|
|
+ }
|
|
|
|
|
|
virtual const byte * peek(size32_t maxSize) override;
|
|
|
virtual offset_t beginNested() override;
|
|
@@ -35,46 +96,24 @@ public:
|
|
|
virtual void skipVStr() override;
|
|
|
virtual void skipVUni() override;
|
|
|
|
|
|
- virtual const byte * querySelf() override;
|
|
|
+ virtual const byte * querySelf() override; // Dubious - used from ifblocks
|
|
|
virtual void noteStartChild() override;
|
|
|
virtual void noteFinishChild() override;
|
|
|
|
|
|
- inline bool eos()
|
|
|
- {
|
|
|
- return in->eos();
|
|
|
- }
|
|
|
-
|
|
|
- inline offset_t tell() const
|
|
|
- {
|
|
|
- return in->tell();
|
|
|
- }
|
|
|
-
|
|
|
- inline void clearStream()
|
|
|
- {
|
|
|
- in = nullptr;
|
|
|
- maxOffset = 0;
|
|
|
- readOffset = 0;
|
|
|
- }
|
|
|
-
|
|
|
- inline const byte * queryRow() const { return buffer; }
|
|
|
+ inline const byte * queryRow() const { return cur; }
|
|
|
inline size32_t queryRowSize() const { return readOffset; }
|
|
|
inline void finishedRow()
|
|
|
{
|
|
|
- if (readOffset)
|
|
|
- in->skip(readOffset);
|
|
|
- maxOffset = 0;
|
|
|
+ skipBytes(readOffset);
|
|
|
readOffset = 0;
|
|
|
}
|
|
|
|
|
|
inline void reset(offset_t offset, offset_t flen = (offset_t)-1)
|
|
|
{
|
|
|
- in->reset(offset, flen);
|
|
|
- buffer = nullptr;
|
|
|
- maxOffset = 0;
|
|
|
+ CContiguousRowBuffer::reset(offset, flen);
|
|
|
readOffset = 0;
|
|
|
}
|
|
|
|
|
|
-
|
|
|
protected:
|
|
|
size32_t sizePackedInt();
|
|
|
size32_t sizeUtf8(size32_t len);
|
|
@@ -83,27 +122,20 @@ protected:
|
|
|
void reportReadFail();
|
|
|
|
|
|
private:
|
|
|
- inline void doPeek(size32_t maxSize)
|
|
|
- {
|
|
|
- buffer = static_cast<const byte *>(in->peek(maxSize, maxOffset));
|
|
|
- }
|
|
|
|
|
|
void doRead(size32_t len, void * ptr);
|
|
|
|
|
|
inline void ensureAccessible(size32_t required)
|
|
|
{
|
|
|
- if (required > maxOffset)
|
|
|
+ if (required > maxAvailable())
|
|
|
{
|
|
|
- doPeek(required);
|
|
|
- assertex(required <= maxOffset);
|
|
|
+ peekBytesDirect(required);
|
|
|
+ assertex(required <= maxAvailable());
|
|
|
}
|
|
|
}
|
|
|
|
|
|
protected:
|
|
|
- ISerialStream* in = nullptr;
|
|
|
- const byte * buffer = nullptr;
|
|
|
- size32_t maxOffset = 0;
|
|
|
- size32_t readOffset = 0;
|
|
|
+ size32_t readOffset = 0; // Offset within the current row
|
|
|
UnsignedArray childStartOffsets;
|
|
|
};
|
|
|
|