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