diff options
Diffstat (limited to 'src/utils/data_src.cpp')
-rw-r--r-- | src/utils/data_src.cpp | 205 |
1 files changed, 205 insertions, 0 deletions
diff --git a/src/utils/data_src.cpp b/src/utils/data_src.cpp new file mode 100644 index 000000000..de5544885 --- /dev/null +++ b/src/utils/data_src.cpp @@ -0,0 +1,205 @@ +/************************************************* +* DataSource Source File * +* (C) 1999-2007 Jack Lloyd * +* 2005 Matthew Gregan * +*************************************************/ + +#include <botan/data_src.h> +#include <botan/exceptn.h> + +#include <fstream> +#include <algorithm> + +namespace Botan { + +/************************************************* +* Read a single byte from the DataSource * +*************************************************/ +u32bit DataSource::read_byte(byte& out) + { + return read(&out, 1); + } + +/************************************************* +* Peek a single byte from the DataSource * +*************************************************/ +u32bit DataSource::peek_byte(byte& out) const + { + return peek(&out, 1, 0); + } + +/************************************************* +* Discard the next N bytes of the data * +*************************************************/ +u32bit DataSource::discard_next(u32bit n) + { + u32bit discarded = 0; + byte dummy; + for(u32bit j = 0; j != n; ++j) + discarded = read_byte(dummy); + return discarded; + } + +/************************************************* +* Read from a memory buffer * +*************************************************/ +u32bit DataSource_Memory::read(byte out[], u32bit length) + { + u32bit got = std::min(source.size() - offset, length); + copy_mem(out, source + offset, got); + offset += got; + return got; + } + +/************************************************* +* Peek into a memory buffer * +*************************************************/ +u32bit DataSource_Memory::peek(byte out[], u32bit length, + u32bit peek_offset) const + { + const u32bit bytes_left = source.size() - offset; + if(peek_offset >= bytes_left) return 0; + + u32bit got = std::min(bytes_left - peek_offset, length); + copy_mem(out, source + offset + peek_offset, got); + return got; + } + +/************************************************* +* Check if the memory buffer is empty * +*************************************************/ +bool DataSource_Memory::end_of_data() const + { + return (offset == source.size()); + } + +/************************************************* +* DataSource_Memory Constructor * +*************************************************/ +DataSource_Memory::DataSource_Memory(const byte in[], u32bit length) + { + source.set(in, length); + offset = 0; + } + +/************************************************* +* DataSource_Memory Constructor * +*************************************************/ +DataSource_Memory::DataSource_Memory(const MemoryRegion<byte>& in) + { + source = in; + offset = 0; + } + +/************************************************* +* DataSource_Memory Constructor * +*************************************************/ +DataSource_Memory::DataSource_Memory(const std::string& in) + { + source.set(reinterpret_cast<const byte*>(in.data()), in.length()); + offset = 0; + } + +/************************************************* +* Read from a stream * +*************************************************/ +u32bit DataSource_Stream::read(byte out[], u32bit length) + { + source->read(reinterpret_cast<char*>(out), length); + if(source->bad()) + throw Stream_IO_Error("DataSource_Stream::read: Source failure"); + + u32bit got = source->gcount(); + total_read += got; + return got; + } + +/************************************************* +* Peek into a stream * +*************************************************/ +u32bit DataSource_Stream::peek(byte out[], u32bit length, u32bit offset) const + { + if(end_of_data()) + throw Invalid_State("DataSource_Stream: Cannot peek when out of data"); + + u32bit got = 0; + + if(offset) + { + SecureVector<byte> buf(offset); + source->read(reinterpret_cast<char*>(buf.begin()), buf.size()); + if(source->bad()) + throw Stream_IO_Error("DataSource_Stream::peek: Source failure"); + got = source->gcount(); + } + + if(got == offset) + { + source->read(reinterpret_cast<char*>(out), length); + if(source->bad()) + throw Stream_IO_Error("DataSource_Stream::peek: Source failure"); + got = source->gcount(); + } + + if(source->eof()) + source->clear(); + source->seekg(total_read, std::ios::beg); + + return got; + } + +/************************************************* +* Check if the stream is empty or in error * +*************************************************/ +bool DataSource_Stream::end_of_data() const + { + return (!source->good()); + } + +/************************************************* +* Return a human-readable ID for this stream * +*************************************************/ +std::string DataSource_Stream::id() const + { + return identifier; + } + +/************************************************* +* DataSource_Stream Constructor * +*************************************************/ +DataSource_Stream::DataSource_Stream(const std::string& path, + bool use_binary) : + identifier(path), owner(true) + { + if(use_binary) + source = new std::ifstream(path.c_str(), std::ios::binary); + else + source = new std::ifstream(path.c_str()); + + if(!source->good()) + throw Stream_IO_Error("DataSource: Failure opening file " + path); + + total_read = 0; + } + +/************************************************* +* DataSource_Stream Constructor * +*************************************************/ +DataSource_Stream::DataSource_Stream(std::istream& in, + const std::string& name) : + identifier(name), owner(false) + { + source = ∈ + total_read = 0; + } + +/************************************************* +* DataSource_Stream Destructor * +*************************************************/ +DataSource_Stream::~DataSource_Stream() + { + if(owner) + delete source; + } + +} |