Skip to content

Commit 9955ab9

Browse files
committed
OrcLib: Stream: add StreamUtils.h containing generic stream helpers
1 parent a7b0b20 commit 9955ab9

File tree

6 files changed

+201
-182
lines changed

6 files changed

+201
-182
lines changed

src/OrcLib/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -584,6 +584,7 @@ set(SRC_STREAM
584584
"Stream/SpanStreamConcept.h"
585585
"Stream/Stream.h"
586586
"Stream/StreamConcept.h"
587+
"Stream/StreamUtils.h"
587588
)
588589

589590
source_group(Stream

src/OrcLib/Filesystem/Ntfs/Compression/WofStreamConcept.h

+3-2
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
#include "Filesystem/Ntfs/Compression/WofChunks.h"
1616
#include "Stream/SeekDirection.h"
17+
#include "Stream/StreamUtils.h"
1718
#include "Utils/MetaPtr.h"
1819

1920
namespace Orc {
@@ -199,7 +200,7 @@ class WofStreamConcept
199200
fmt::basic_memory_buffer<uint8_t, 8192> buffer;
200201
buffer.resize(m_chunks.GetChunkTableSize());
201202

202-
Orc::ReadChunkAt(*m_stream, m_startOffset, buffer, ec);
203+
Orc::Stream::ReadChunkAt(*m_stream, m_startOffset, buffer, ec);
203204
if (ec)
204205
{
205206
Log::Debug("Failed to read chunk table [{}]", ec);
@@ -237,7 +238,7 @@ class WofStreamConcept
237238
// Use 'ReadChunk' to do as many 'Read()' on the stream as necessary to fill the 'chunk' buffer.
238239
const auto& chunk = m_locations[chunkIndex];
239240
output.resize(chunk.size);
240-
return Orc::ReadChunkAt(*m_stream, chunk.offset, output, ec);
241+
return Orc::Stream::ReadChunkAt(*m_stream, chunk.offset, output, ec);
241242
}
242243

243244
// Decompress a chunk and shift the output to 'uncompressedOffset'. Uses an internal buffer if needed.

src/OrcLib/Stream/BufferStreamConcept.h

-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
#include <cstdint>
1212
#include <system_error>
1313

14-
#include "Stream/Stream.h"
1514
#include "Stream/SeekDirection.h"
1615
#include "Utils/BufferView.h"
1716
#include "Utils/MetaPtr.h"

src/OrcLib/Stream/FileStreamConcept.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@
1010

1111
#include <system_error>
1212

13-
#include "Stream/StreamConcept.h"
13+
#include "Stream/SeekDirection.h"
14+
#include "Utils/BufferView.h"
1415
#include "Utils/Guard.h"
1516

1617
namespace Orc {

src/OrcLib/Stream/StreamConcept.h

+1-178
Original file line numberDiff line numberDiff line change
@@ -8,20 +8,10 @@
88

99
#pragma once
1010

11-
#include <system_error>
12-
13-
#include <gsl/span>
14-
15-
#include "Text/Fmt/Offset.h"
16-
#include "Log/Log.h"
17-
#include "Utils/BufferView.h"
18-
#include "Utils/TypeTraits.h"
19-
#include "Stream/SeekDirection.h"
20-
2111
namespace Orc {
2212

2313
/*
24-
* StreamConcept interface
14+
* Stream concept
2515
*
2616
* class StreamConcept
2717
* {
@@ -30,174 +20,7 @@ namespace Orc {
3020
* size_t Write(BufferView& input, std::error_code& ec);
3121
* uint64_t Seek(SeekDirection direction, int64_t value, std::error_code& ec);
3222
* };
33-
*/
34-
35-
/*!
36-
* \brief Read 'stream' and shrink output to read size.
37-
*/
38-
template <typename InputStreamT, typename CharT>
39-
size_t Read(InputStreamT& stream, gsl::span<CharT> output, std::error_code& ec)
40-
{
41-
gsl::span<uint8_t> span(reinterpret_cast<uint8_t*>(output.data()), output.size() * sizeof(CharT));
42-
return stream.Read(span, ec);
43-
}
44-
45-
/*!
46-
* \brief Read 'stream' until 'output' is completely filled.
47-
*/
48-
template <typename InputStreamT, typename CharT>
49-
size_t ReadChunk(InputStreamT& stream, gsl::span<CharT> output, std::error_code& ec)
50-
{
51-
uint64_t processed = 0;
52-
53-
while (processed != output.size())
54-
{
55-
// TODO: subview
56-
gsl::span<uint8_t> span(
57-
reinterpret_cast<uint8_t*>(output.data() + processed), output.size() * sizeof(CharT) - processed);
58-
59-
const auto lastReadSize = stream.Read(span, ec);
60-
if (ec)
61-
{
62-
return processed;
63-
}
64-
65-
if (lastReadSize == 0)
66-
{
67-
Log::Debug("Input stream does not provide enough bytes to fill buffer");
68-
ec = std::make_error_code(std::errc::message_size);
69-
return processed;
70-
}
71-
72-
processed += lastReadSize;
73-
}
74-
75-
return processed;
76-
}
77-
78-
/*!
79-
* \brief Read 'stream' until 'output' is completely filled.
80-
*/
81-
template <typename InputStreamT, typename ContainerT>
82-
size_t Read(InputStreamT& stream, ContainerT& output, std::error_code& ec)
83-
{
84-
gsl::span<uint8_t> span(reinterpret_cast<uint8_t*>(output.data()), output.size() * sizeof(ContainerT::value_type));
85-
86-
size_t processed = stream.Read(span, ec);
87-
if (ec)
88-
{
89-
return processed;
90-
}
91-
92-
output.resize(processed / sizeof(ContainerT::value_type));
93-
return processed;
94-
}
95-
96-
/*!
97-
* \brief Read 'stream' until 'output' is completely filled.
9823
*
99-
* TODO: C++20: use std::is_contiguous_iterator
10024
*/
101-
template <typename InputStreamT, typename ContainerT>
102-
size_t ReadChunk(InputStreamT& stream, ContainerT& output, std::error_code& ec)
103-
{
104-
gsl::span<uint8_t> span(reinterpret_cast<uint8_t*>(output.data()), output.size() * sizeof(ContainerT::value_type));
105-
return ReadChunk(stream, span, ec);
106-
}
107-
108-
/*!
109-
* \brief Read at specified position the available bytes and store them in container of type ContainerT
110-
*
111-
* TODO: C++20: use std::is_contiguous_iterator
112-
*/
113-
template <typename InputStreamT, typename ContainerT>
114-
size_t ReadAt(InputStreamT& stream, uint64_t offset, ContainerT& output, std::error_code& ec)
115-
{
116-
stream.Seek(SeekDirection::kBegin, offset, ec);
117-
if (ec)
118-
{
119-
Log::Debug("Failed to seek to position: {} [{}]", Traits::Offset(offset), ec);
120-
return 0;
121-
}
122-
123-
return Read(stream, output, ec);
124-
}
125-
126-
/*!
127-
* \brief Read at specified position in 'stream' until 'output' is completely filled.
128-
*
129-
* TODO: C++20: use std::is_contiguous_iterator
130-
*/
131-
template <typename InputStreamT, typename ContainerT>
132-
size_t ReadChunkAt(InputStreamT& stream, uint64_t offset, ContainerT& output, std::error_code& ec)
133-
{
134-
stream.Seek(SeekDirection::kBegin, offset, ec);
135-
if (ec)
136-
{
137-
Log::Debug("Failed to seek to position: {} [{}]", Traits::Offset(offset), ec);
138-
return 0;
139-
}
140-
141-
gsl::span<uint8_t> span(reinterpret_cast<uint8_t*>(output.data()), output.size() * sizeof(ContainerT::value_type));
142-
return ReadChunk(stream, span, ec);
143-
}
144-
145-
/*!
146-
* \brief Read at specified position in 'stream' until 'output' is completely filled.
147-
*
148-
* TODO: C++20: use std::is_contiguous_iterator
149-
*/
150-
template <typename InputStreamT, typename CharT>
151-
size_t
152-
ReadChunkAt(InputStreamT& stream, uint64_t offset, size_t chunkSizeCb, gsl::span<CharT> output, std::error_code& ec)
153-
{
154-
stream.Seek(SeekDirection::kBegin, offset, ec);
155-
if (ec)
156-
{
157-
Log::Debug("Failed to seek to position: {} [{}]", Traits::Offset(offset), ec);
158-
return 0;
159-
}
160-
161-
assert(chunkSizeCb < output.size() * sizeof(CharT) && "Buffer 'output' overflow");
162-
163-
gsl::span<uint8_t> span(reinterpret_cast<uint8_t*>(output.data()), chunkSizeCb);
164-
return ReadChunk(stream, span, ec);
165-
}
166-
167-
/*!
168-
* \brief Fill an item of type 'T' and fail if there is not enough data to read.
169-
*/
170-
template <typename InputStreamT, typename ItemT>
171-
void ReadItem(InputStreamT& stream, ItemT& output, std::error_code& ec)
172-
{
173-
uint64_t processed = stream.Read(gsl::span<uint8_t>(reinterpret_cast<uint8_t*>(&output), sizeof(output)), ec);
174-
if (ec)
175-
{
176-
return;
177-
}
178-
179-
if (processed != sizeof(output))
180-
{
181-
ec = std::make_error_code(std::errc::interrupted);
182-
Log::Debug("Failed to read expected size ({}/{})", processed, sizeof(ItemT));
183-
return;
184-
}
185-
}
186-
187-
/*!
188-
* \brief Fill an item of type 'T' and fail if there is not enough data to read.
189-
*/
190-
template <typename InputStreamT, typename ItemT>
191-
void ReadItemAt(InputStreamT& stream, uint64_t offset, ItemT& output, std::error_code& ec)
192-
{
193-
stream.Seek(SeekDirection::kBegin, offset, ec);
194-
if (ec)
195-
{
196-
Log::Debug("Failed to seek to position: {} [{}]", Traits::Offset(offset), ec);
197-
return;
198-
}
199-
200-
ReadItem(stream, output, ec);
201-
}
20225

20326
} // namespace Orc

0 commit comments

Comments
 (0)