Botan 3.13.0
Crypto and TLS for C&
data_src.h
Go to the documentation of this file.
1/*
2* DataSource
3* (C) 1999-2007 Jack Lloyd
4* 2012 Markus Wanner
5*
6* Botan is released under the Simplified BSD License (see license.txt)
7*/
8
9#ifndef BOTAN_DATA_SRC_H_
10#define BOTAN_DATA_SRC_H_
11
12#include <botan/secmem.h>
13#include <iosfwd>
14#include <memory>
15#include <optional>
16#include <span>
17#include <string>
18#include <string_view>
19
20namespace Botan {
21
22/**
23* This class represents an abstract data source object.
24*/
26 public:
27 /**
28 * Read from the source. Moves the internal offset so that every
29 * call to read will return a new portion of the source.
30 *
31 * @param out the byte array to write the result to
32 * @param length the length of the byte array out
33 * @return length in bytes that was actually read and put
34 * into out
35 */
36 [[nodiscard]] virtual size_t read(uint8_t out[], size_t length) = 0;
37
38 /**
39 * Test whether at least n further bytes can be read
40 * @param n the number of bytes required
41 * @return true if at least n bytes remain
42 */
43 virtual bool check_available(size_t n) = 0;
44
45 /**
46 * Read from the source but do not modify the internal
47 * offset. Consecutive calls to peek() will return portions of
48 * the source starting at the same position.
49 *
50 * @param out the byte array to write the output to
51 * @param length the length of the byte array out
52 * @param peek_offset the offset into the stream to read at
53 * @return length in bytes that was actually read and put
54 * into out
55 */
56 [[nodiscard]] virtual size_t peek(uint8_t out[], size_t length, size_t peek_offset) const = 0;
57
58 /**
59 * Test whether the source still has data that can be read.
60 * @return true if there is no more data to read, false otherwise
61 */
62 virtual bool end_of_data() const = 0;
63
64 /**
65 * return the id of this data source
66 * @return std::string representing the id of this data source
67 */
68 virtual std::string id() const { return ""; }
69
70 /**
71 * Read one byte.
72 * @param out the byte to read to
73 * @return length in bytes that was actually read and put
74 * into out
75 */
76 size_t read_byte(uint8_t& out);
77
78 /**
79 * Read one byte.
80 *
81 * Returns nullopt if no further bytes are available
82 */
83 std::optional<uint8_t> read_byte();
84
85 /**
86 * Peek at one byte.
87 * @param out an output byte
88 * @return length in bytes that was actually read and put
89 * into out
90 */
91 size_t peek_byte(uint8_t& out) const;
92
93 /**
94 * Discard the next N bytes of the data
95 * @param N the number of bytes to discard
96 * @return number of bytes actually discarded
97 */
98 size_t discard_next(size_t N);
99
100 /**
101 * Count the bytes consumed from this source so far
102 * @return number of bytes read so far
103 */
104 virtual size_t get_bytes_read() const = 0;
105
106 /// Default constructor
107 DataSource() = default;
108
109 virtual ~DataSource() = default;
110
111 // No copy available
112 DataSource(const DataSource&) = delete;
113 DataSource& operator=(const DataSource&) = delete;
114
115 /// Move constructor
116 DataSource(DataSource&&) = default;
117
118 /// Move assignment
119 /// @return reference to this
121};
122
123/**
124* This class represents a Memory-Based DataSource
125*/
127 public:
128 /**
129 * Read from the source, advancing the internal offset
130 * @param buf the byte array to write the result to
131 * @param length the length of the byte array buf
132 * @return length in bytes that was actually read and put into buf
133 */
134 size_t read(uint8_t buf[], size_t length) override;
135
136 /**
137 * Read from the source without modifying the internal offset
138 * @param buf the byte array to write the result to
139 * @param length the length of the byte array buf
140 * @param offset the offset into the stream to read at
141 * @return length in bytes that was actually read and put into buf
142 */
143 size_t peek(uint8_t buf[], size_t length, size_t offset) const override;
144
145 /**
146 * Test whether at least n further bytes can be read
147 * @param n the number of bytes required
148 * @return true if at least n bytes remain
149 */
150 bool check_available(size_t n) override;
151
152 /**
153 * Test whether the source still has data that can be read
154 * @return true if there is no more data to read, false otherwise
155 */
156 bool end_of_data() const override;
157
158 /**
159 * Construct a memory source that reads from a string
160 * @param in the string to read from
161 */
162 explicit DataSource_Memory(std::string_view in);
163
164 /**
165 * Construct a memory source that reads from a byte array
166 * @param in the byte array to read from
167 * @param length the length of the byte array
168 */
169 DataSource_Memory(const uint8_t in[], size_t length) : DataSource_Memory(std::span<const uint8_t>(in, length)) {}
170
171 /**
172 * Construct a memory source that reads from a secure_vector
173 * @param in the MemoryRegion to read from
174 */
175 explicit DataSource_Memory(secure_vector<uint8_t> in) : m_source(std::move(in)), m_offset(0) {}
176
177 /**
178 * Construct a memory source that reads from an arbitrary byte buffer
179 * @param in the MemoryRegion to read from
180 */
181 explicit DataSource_Memory(std::span<const uint8_t> in) : m_offset(0) {
182 // Guard against forming a range from a null pointer (eg an empty span)
183 if(!in.empty()) {
184 m_source.assign(in.begin(), in.end());
185 }
186 }
187
188 /**
189 * Construct a memory source that reads from a std::vector
190 * @param in the MemoryRegion to read from
191 */
192 explicit DataSource_Memory(const std::vector<uint8_t>& in) : DataSource_Memory(std::span<const uint8_t>(in)) {}
193
194 /**
195 * Count the bytes consumed from this source so far
196 * @return number of bytes read so far
197 */
198 size_t get_bytes_read() const override { return m_offset; }
199
200 private:
201 secure_vector<uint8_t> m_source;
202 size_t m_offset;
203};
204
205/**
206* This class represents a Stream-Based DataSource.
207*/
209 public:
210 /**
211 * Read from the source, advancing the internal offset
212 * @param buf the byte array to write the result to
213 * @param length the length of the byte array buf
214 * @return length in bytes that was actually read and put into buf
215 */
216 size_t read(uint8_t buf[], size_t length) override;
217
218 /**
219 * Read from the source without modifying the internal offset
220 * @param buf the byte array to write the result to
221 * @param length the length of the byte array buf
222 * @param offset the offset into the stream to read at
223 * @return length in bytes that was actually read and put into buf
224 */
225 size_t peek(uint8_t buf[], size_t length, size_t offset) const override;
226
227 /**
228 * Test whether at least n further bytes can be read
229 * @param n the number of bytes required
230 * @return true if at least n bytes remain
231 */
232 bool check_available(size_t n) override;
233
234 /**
235 * Test whether the source still has data that can be read
236 * @return true if there is no more data to read, false otherwise
237 */
238 bool end_of_data() const override;
239
240 /**
241 * Return the id of this data source
242 * @return a string representing the id of this data source
243 */
244 std::string id() const override;
245
246 /**
247 * Construct a Stream-Based DataSource from an istream
248 * @param in the stream to read from
249 * @param id an identifier for this source, used in error messages
250 */
251 BOTAN_FUTURE_EXPLICIT DataSource_Stream(std::istream& in, std::string_view id = "<std::istream>");
252
253#if defined(BOTAN_TARGET_OS_HAS_FILESYSTEM)
254 /**
255 * Construct a Stream-Based DataSource from filesystem path
256 * @param filename the path to the file
257 * @param use_binary whether to treat the file as binary or not
258 */
259 BOTAN_FUTURE_EXPLICIT DataSource_Stream(std::string_view filename, bool use_binary = false);
260#endif
261
262 // Stream data sources are not copyable or moveable
267
269
270 /**
271 * Count the bytes consumed from this source so far
272 * @return number of bytes read so far
273 */
274 size_t get_bytes_read() const override { return m_total_read; }
275
276 private:
277 const std::string m_identifier;
278
279 std::unique_ptr<std::istream> m_source_memory;
280 std::istream& m_source;
281 size_t m_total_read;
282};
283
284} // namespace Botan
285
286#endif
#define BOTAN_PUBLIC_API(maj, min)
Definition api.h:21
#define BOTAN_FUTURE_EXPLICIT
Definition api.h:52
DataSource_Memory(const std::vector< uint8_t > &in)
Definition data_src.h:192
DataSource_Memory(secure_vector< uint8_t > in)
Definition data_src.h:175
DataSource_Memory(std::string_view in)
Definition data_src.cpp:108
size_t read(uint8_t buf[], size_t length) override
Definition data_src.cpp:73
bool check_available(size_t n) override
Definition data_src.cpp:80
DataSource_Memory(std::span< const uint8_t > in)
Definition data_src.h:181
size_t peek(uint8_t buf[], size_t length, size_t offset) const override
Definition data_src.cpp:87
DataSource_Memory(const uint8_t in[], size_t length)
Definition data_src.h:169
size_t get_bytes_read() const override
Definition data_src.h:198
bool end_of_data() const override
Definition data_src.cpp:101
bool end_of_data() const override
Definition data_src.cpp:168
BOTAN_FUTURE_EXPLICIT DataSource_Stream(std::istream &in, std::string_view id="<std::istream>")
Definition data_src.cpp:204
size_t get_bytes_read() const override
Definition data_src.h:274
DataSource_Stream & operator=(DataSource_Stream &&)=delete
DataSource_Stream(const DataSource_Stream &)=delete
size_t read(uint8_t buf[], size_t length) override
Definition data_src.cpp:113
size_t peek(uint8_t buf[], size_t length, size_t offset) const override
Definition data_src.cpp:135
DataSource_Stream(DataSource_Stream &&)=delete
bool check_available(size_t n) override
Definition data_src.cpp:124
DataSource_Stream & operator=(const DataSource_Stream &)=delete
std::string id() const override
Definition data_src.cpp:180
virtual std::string id() const
Definition data_src.h:68
DataSource & operator=(DataSource &&)=default
DataSource(DataSource &&)=default
Move constructor.
DataSource(const DataSource &)=delete
virtual size_t get_bytes_read() const =0
virtual ~DataSource()=default
DataSource()=default
Default constructor.
virtual size_t peek(uint8_t out[], size_t length, size_t peek_offset) const =0
virtual size_t read(uint8_t out[], size_t length)=0
virtual bool check_available(size_t n)=0
virtual bool end_of_data() const =0
DataSource & operator=(const DataSource &)=delete
std::vector< T, secure_allocator< T > > secure_vector
Definition secmem.h:128