1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178
|
/*************************************************
* DataSource Source File *
* (C) 1999-2005 The Botan Project *
*************************************************/
#include <botan/data_src.h>
#include <fstream>
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;
}
/*************************************************
* Read from a stream *
*************************************************/
u32bit DataSource_Stream::read(byte out[], u32bit length)
{
source->read((char*)out, length);
if(source->bad())
throw Stream_IO_Error("DataSource_Stream::read: Source failure");
u32bit got = source->gcount();
total_read += got;
return (u32bit)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((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((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 fsname;
}
/*************************************************
* DataSource_Stream Constructor *
*************************************************/
DataSource_Stream::DataSource_Stream(const std::string& file,
bool use_binary) : fsname(file)
{
if(use_binary)
source = new std::ifstream(fsname.c_str(), std::ios::binary);
else
source = new std::ifstream(fsname.c_str());
if(!source->good())
throw Stream_IO_Error("DataSource_Stream: Failure opening " + fsname);
total_read = 0;
}
/*************************************************
* DataSource_Stream Destructor *
*************************************************/
DataSource_Stream::~DataSource_Stream()
{
delete source;
}
}
|