Botan  1.10.10
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 */
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 
45  if(got == 0)
46  break;
47  }
48 
49  return discarded;
50  }
51 
52 /*
53 * Read from a memory buffer
54 */
55 size_t DataSource_Memory::read(byte out[], size_t length)
56  {
57  size_t got = std::min<size_t>(source.size() - offset, length);
58  copy_mem(out, source.data() + offset, got);
59  offset += got;
60  return got;
61  }
62 
64  {
65  return (n <= (source.size() - offset));
66  }
67 
68 /*
69 * Peek into a memory buffer
70 */
71 size_t DataSource_Memory::peek(byte out[], size_t length,
72  size_t peek_offset) const
73  {
74  const size_t bytes_left = source.size() - offset;
75  if(peek_offset >= bytes_left) return 0;
76 
77  size_t got = std::min(bytes_left - peek_offset, length);
78  copy_mem(out, &source[offset + peek_offset], got);
79  return got;
80  }
81 
82 /*
83 * Check if the memory buffer is empty
84 */
86  {
87  return (offset == source.size());
88  }
89 
90 /*
91 * DataSource_Memory Constructor
92 */
93 DataSource_Memory::DataSource_Memory(const std::string& in) :
94  source(reinterpret_cast<const byte*>(in.data()),
95  reinterpret_cast<const byte*>(in.data()) + in.length()),
96  offset(0)
97  {
98  offset = 0;
99  }
100 
101 /*
102 * Read from a stream
103 */
104 size_t DataSource_Stream::read(byte out[], size_t length)
105  {
106  source.read(reinterpret_cast<char*>(out), length);
107  if(source.bad())
108  throw Stream_IO_Error("DataSource_Stream::read: Source failure");
109 
110  size_t got = source.gcount();
111  total_read += got;
112  return got;
113  }
114 
116  {
117  const std::streampos orig_pos = source.tellg();
118  source.seekg(0, std::ios::end);
119  const size_t avail = source.tellg() - orig_pos;
120  source.seekg(orig_pos);
121  return (avail >= n);
122  }
123 
124 /*
125 * Peek into a stream
126 */
127 size_t DataSource_Stream::peek(byte out[], size_t length, size_t offset) const
128  {
129  if(end_of_data())
130  throw Invalid_State("DataSource_Stream: Cannot peek when out of data");
131 
132  size_t got = 0;
133 
134  if(offset)
135  {
136  secure_vector<byte> buf(offset);
137  source.read(reinterpret_cast<char*>(buf.data()), buf.size());
138  if(source.bad())
139  throw Stream_IO_Error("DataSource_Stream::peek: Source failure");
140  got = source.gcount();
141  }
142 
143  if(got == offset)
144  {
145  source.read(reinterpret_cast<char*>(out), length);
146  if(source.bad())
147  throw Stream_IO_Error("DataSource_Stream::peek: Source failure");
148  got = source.gcount();
149  }
150 
151  if(source.eof())
152  source.clear();
153  source.seekg(total_read, std::ios::beg);
154 
155  return got;
156  }
157 
158 /*
159 * Check if the stream is empty or in error
160 */
162  {
163  return (!source.good());
164  }
165 
166 /*
167 * Return a human-readable ID for this stream
168 */
169 std::string DataSource_Stream::id() const
170  {
171  return identifier;
172  }
173 
174 /*
175 * DataSource_Stream Constructor
176 */
177 DataSource_Stream::DataSource_Stream(const std::string& path,
178  bool use_binary) :
179  identifier(path),
180  source_p(new std::ifstream(path,
181  use_binary ? std::ios::binary : std::ios::in)),
182  source(*source_p),
183  total_read(0)
184  {
185  if(!source.good())
186  {
187  delete source_p;
188  throw Stream_IO_Error("DataSource: Failure opening file " + path);
189  }
190  }
191 
192 /*
193 * DataSource_Stream Constructor
194 */
196  const std::string& name) :
197  identifier(name),
198  source_p(nullptr),
199  source(in),
200  total_read(0)
201  {
202  }
203 
204 /*
205 * DataSource_Stream Destructor
206 */
208  {
209  delete source_p;
210  }
211 
212 }
size_t peek(byte[], size_t, size_t) const override
Definition: data_src.cpp:71
virtual size_t read(byte out[], size_t length)=0
bool check_available(size_t n) override
Definition: data_src.cpp:115
size_t peek(byte[], size_t, size_t) const override
Definition: data_src.cpp:127
const BigInt & n
Definition: rsa.cpp:107
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:55
Definition: bigint.h:610
std::string id() const override
Definition: data_src.cpp:169
std::vector< T, secure_allocator< T >> secure_vector
Definition: secmem.h:93
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:195
bool end_of_data() const override
Definition: data_src.cpp:85
size_t read(byte[], size_t) override
Definition: data_src.cpp:104
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:39
bool end_of_data() const override
Definition: data_src.cpp:161
DataSource_Memory(const std::string &in)
Definition: data_src.cpp:93
bool check_available(size_t n) override
Definition: data_src.cpp:63
std::uint8_t byte
Definition: types.h:31