Botan  1.11.26
data_src.cpp
Go to the documentation of this file.
1 /*
2 * DataSource
3 * (C) 1999-2007 Jack Lloyd
4 * 2005 Matthew Gregan
5 *
6 * Botan is released under the Simplified BSD License (see license.txt)
7 */
8 
9 #include <botan/data_src.h>
10 #include <botan/exceptn.h>
11 #include <fstream>
12 #include <algorithm>
13 
14 namespace Botan {
15 
16 /*
17 * Read a single byte from the DataSource
18 */
20  {
21  return read(&out, 1);
22  }
23 
24 /*
25 * Peek a single byte from the DataSource
26 */
27 size_t DataSource::peek_byte(byte& out) const
28  {
29  return peek(&out, 1, 0);
30  }
31 
32 /*
33 * Discard the next N bytes of the data
34 */
35 size_t DataSource::discard_next(size_t n)
36  {
37  byte buf[64] = { 0 };
38  size_t discarded = 0;
39 
40  while(n)
41  {
42  const size_t got = this->read(buf, std::min(n, sizeof(buf)));
43  discarded += got;
44  n -= got;
45 
46  if(got == 0)
47  break;
48  }
49 
50  return discarded;
51  }
52 
53 /*
54 * Read from a memory buffer
55 */
56 size_t DataSource_Memory::read(byte out[], size_t length)
57  {
58  size_t got = std::min<size_t>(m_source.size() - m_offset, length);
59  copy_mem(out, m_source.data() + m_offset, got);
60  m_offset += got;
61  return got;
62  }
63 
65  {
66  return (n <= (m_source.size() - m_offset));
67  }
68 
69 /*
70 * Peek into a memory buffer
71 */
72 size_t DataSource_Memory::peek(byte out[], size_t length,
73  size_t peek_offset) const
74  {
75  const size_t bytes_left = m_source.size() - m_offset;
76  if(peek_offset >= bytes_left) return 0;
77 
78  size_t got = std::min(bytes_left - peek_offset, length);
79  copy_mem(out, &m_source[m_offset + peek_offset], got);
80  return got;
81  }
82 
83 /*
84 * Check if the memory buffer is empty
85 */
87  {
88  return (m_offset == m_source.size());
89  }
90 
91 /*
92 * DataSource_Memory Constructor
93 */
94 DataSource_Memory::DataSource_Memory(const std::string& in) :
95  m_source(reinterpret_cast<const byte*>(in.data()),
96  reinterpret_cast<const byte*>(in.data()) + in.length()),
97  m_offset(0)
98  {
99  m_offset = 0;
100  }
101 
102 /*
103 * Read from a stream
104 */
105 size_t DataSource_Stream::read(byte out[], size_t length)
106  {
107  m_source.read(reinterpret_cast<char*>(out), length);
108  if(m_source.bad())
109  throw Stream_IO_Error("DataSource_Stream::read: Source failure");
110 
111  size_t got = m_source.gcount();
112  m_total_read += got;
113  return got;
114  }
115 
117  {
118  const std::streampos orig_pos = m_source.tellg();
119  m_source.seekg(0, std::ios::end);
120  const size_t avail = m_source.tellg() - orig_pos;
121  m_source.seekg(orig_pos);
122  return (avail >= n);
123  }
124 
125 /*
126 * Peek into a stream
127 */
128 size_t DataSource_Stream::peek(byte out[], size_t length, size_t offset) const
129  {
130  if(end_of_data())
131  throw Invalid_State("DataSource_Stream: Cannot peek when out of data");
132 
133  size_t got = 0;
134 
135  if(offset)
136  {
137  secure_vector<byte> buf(offset);
138  m_source.read(reinterpret_cast<char*>(buf.data()), buf.size());
139  if(m_source.bad())
140  throw Stream_IO_Error("DataSource_Stream::peek: Source failure");
141  got = m_source.gcount();
142  }
143 
144  if(got == offset)
145  {
146  m_source.read(reinterpret_cast<char*>(out), length);
147  if(m_source.bad())
148  throw Stream_IO_Error("DataSource_Stream::peek: Source failure");
149  got = m_source.gcount();
150  }
151 
152  if(m_source.eof())
153  m_source.clear();
154  m_source.seekg(m_total_read, std::ios::beg);
155 
156  return got;
157  }
158 
159 /*
160 * Check if the stream is empty or in error
161 */
163  {
164  return (!m_source.good());
165  }
166 
167 /*
168 * Return a human-readable ID for this stream
169 */
170 std::string DataSource_Stream::id() const
171  {
172  return m_identifier;
173  }
174 
175 /*
176 * DataSource_Stream Constructor
177 */
178 DataSource_Stream::DataSource_Stream(const std::string& path,
179  bool use_binary) :
180  m_identifier(path),
181  m_source_p(new std::ifstream(path,
182  use_binary ? std::ios::binary : std::ios::in)),
183  m_source(*m_source_p),
184  m_total_read(0)
185  {
186  if(!m_source.good())
187  {
188  delete m_source_p;
189  throw Stream_IO_Error("DataSource: Failure opening file " + path);
190  }
191  }
192 
193 /*
194 * DataSource_Stream Constructor
195 */
197  const std::string& name) :
198  m_identifier(name),
199  m_source_p(nullptr),
200  m_source(in),
201  m_total_read(0)
202  {
203  }
204 
205 /*
206 * DataSource_Stream Destructor
207 */
209  {
210  delete m_source_p;
211  }
212 
213 }
size_t peek(byte[], size_t, size_t) const override
Definition: data_src.cpp:72
virtual size_t read(byte out[], size_t length)=0
bool check_available(size_t n) override
Definition: data_src.cpp:116
size_t peek(byte[], size_t, size_t) const override
Definition: data_src.cpp:128
size_t peek_byte(byte &out) const
Definition: data_src.cpp:27
size_t discard_next(size_t N)
Definition: data_src.cpp:35
size_t read(byte[], size_t) override
Definition: data_src.cpp:56
Definition: bigint.h:610
std::string id() const override
Definition: data_src.cpp:170
std::vector< T, secure_allocator< T >> secure_vector
Definition: secmem.h:96
virtual size_t peek(byte out[], size_t length, size_t peek_offset) const =0
DataSource_Stream(std::istream &, const std::string &id="<std::istream>")
Definition: data_src.cpp:196
bool end_of_data() const override
Definition: data_src.cpp:86
size_t read(byte[], size_t) override
Definition: data_src.cpp:105
size_t read_byte(byte &out)
Definition: data_src.cpp:19
void copy_mem(T *out, const T *in, size_t n)
Definition: mem_ops.h:43
Definition: alg_id.cpp:13
bool end_of_data() const override
Definition: data_src.cpp:162
T min(T a, T b)
Definition: ct_utils.h:148
DataSource_Memory(const std::string &in)
Definition: data_src.cpp:94
bool check_available(size_t n) override
Definition: data_src.cpp:64
std::uint8_t byte
Definition: types.h:31