24 #ifndef __TPIE_STREAM_CRTP_H__
25 #define __TPIE_STREAM_CRTP_H__
34 template <
typename child_t>
51 assert(
self().get_file().is_open());
53 offset +=
self().
size();
54 else if (whence == current) {
56 if (offset >= 0 || static_cast<stream_size_type>(-offset) <=
m_index) {
57 stream_size_type new_index =
static_cast<stream_offset_type
>(offset+
m_index);
59 if (new_index <
self().get_file().block_items()) {
61 m_index =
static_cast<memory_size_type
>(new_index);
68 if (0 > offset || (stream_size_type)offset >
self().
size())
71 stream_size_type b =
static_cast<stream_size_type
>(
offset) /
self().get_file().block_items();
72 m_index =
static_cast<memory_size_type
>(offset - b*
self().get_file().block_items());
73 if (b ==
self().get_block().number) {
74 m_nextBlock = std::numeric_limits<stream_size_type>::max();
75 m_nextIndex = std::numeric_limits<memory_size_type>::max();
76 assert(
self().
offset() == (stream_size_type)offset);
81 m_index = std::numeric_limits<memory_size_type>::max();
82 assert(
self().
offset() == (stream_size_type)offset);
90 inline stream_size_type
offset()
const throw() {
91 assert(
self().get_file().is_open());
92 if (
m_nextBlock == std::numeric_limits<stream_size_type>::max())
109 assert(
self().get_file().is_open());
110 if (
m_index <
self().get_block().
size )
return true;
120 assert(
self().get_file().is_open());
121 if (
m_nextBlock == std::numeric_limits<stream_size_type>::max())
132 inline stream_size_type
size()
const throw() {
136 const_cast<child_t&
>(
self()).update_vars();
137 return self().get_file().file_size();
141 inline void initialize() {
142 m_nextBlock = std::numeric_limits<stream_size_type>::max();
143 m_nextIndex = std::numeric_limits<memory_size_type>::max();
144 m_index = std::numeric_limits<memory_size_type>::max();
164 template <
typename IT,
typename Stream>
166 typedef typename Stream::item_type T;
169 if (stream.m_index >= stream.block_items()) {
171 stream_size_type offs = stream.offset();
172 if (offs >= stream.size()
173 || offs + (end-i) > stream.size()) {
179 stream.update_block();
182 T * src =
reinterpret_cast<T*
>(stream.get_block().data) + stream.m_index;
185 memory_size_type count = std::min(stream.block_items()-stream.m_index,
static_cast<memory_size_type
>(end-i));
187 std::copy(src, src + count, i);
193 stream.m_index += count;
210 template <
typename IT,
typename Stream>
212 typedef typename Stream::item_type T;
215 if (stream.m_index >= stream.block_items()) stream.update_block();
217 size_t streamRemaining = end - i;
218 size_t blockRemaining = stream.block_items()-stream.m_index;
220 IT till = (blockRemaining < streamRemaining) ? (i + blockRemaining) : end;
222 T * dest =
reinterpret_cast<T*
>(stream.get_block().data) + stream.m_index;
224 std::copy(i, till, dest);
226 stream.m_index += till - i;
227 stream.write_update();
258 inline child_t &
self() {
return *
static_cast<child_t*
>(
this);}
259 inline const child_t &
self()
const {
return *
static_cast<const child_t*
>(
this);}
264 #endif // __TPIE_STREAM_CRTP_H__
stream_size_type m_nextBlock
After a cross-block seek: Block index of next block, or maxint if the current block is good enough OR...
static void write_array(Stream &stream, const IT &start, const IT &end)
Write several items to the stream.
static void read_array(Stream &stream, const IT &start, const IT &end)
Reads several items from the stream.
stream_size_type offset() const
Calculate the current offset in the stream.
offset_type
Type describing how we should interpret the offset supplied to seek.
memory_size_type m_index
Item index into the current block, or maxint if we don't have a block.
memory_size_type m_nextIndex
After a cross-block seek: Item index into next block.
void seek(stream_offset_type offset, offset_type whence=beginning)
Moves the logical offset in the stream.
bool can_read_back() const
Check if we can read an item with read_back().
bool can_read() const
Check if we can read an item with read().
void update_block()
Fetch block from disk as indicated by m_nextBlock, writing old block to disk if needed.
stream_size_type m_blockStartIndex
The file-level item index of the first item in the current block.
stream_size_type size() const
Get the size of the file measured in items.