00001
00002
00003
00004
00005
00006
00007
00008
00009 #include <botan/data_src.h>
00010 #include <botan/exceptn.h>
00011
00012 #include <fstream>
00013 #include <algorithm>
00014
00015 namespace Botan {
00016
00017
00018
00019
00020 u32bit DataSource::read_byte(byte& out)
00021 {
00022 return read(&out, 1);
00023 }
00024
00025
00026
00027
00028 u32bit DataSource::peek_byte(byte& out) const
00029 {
00030 return peek(&out, 1, 0);
00031 }
00032
00033
00034
00035
00036 u32bit DataSource::discard_next(u32bit n)
00037 {
00038 u32bit discarded = 0;
00039 byte dummy;
00040 for(u32bit j = 0; j != n; ++j)
00041 discarded += read_byte(dummy);
00042 return discarded;
00043 }
00044
00045
00046
00047
00048 u32bit DataSource_Memory::read(byte out[], u32bit length)
00049 {
00050 u32bit got = std::min(source.size() - offset, length);
00051 copy_mem(out, source + offset, got);
00052 offset += got;
00053 return got;
00054 }
00055
00056
00057
00058
00059 u32bit DataSource_Memory::peek(byte out[], u32bit length,
00060 u32bit peek_offset) const
00061 {
00062 const u32bit bytes_left = source.size() - offset;
00063 if(peek_offset >= bytes_left) return 0;
00064
00065 u32bit got = std::min(bytes_left - peek_offset, length);
00066 copy_mem(out, source + offset + peek_offset, got);
00067 return got;
00068 }
00069
00070
00071
00072
00073 bool DataSource_Memory::end_of_data() const
00074 {
00075 return (offset == source.size());
00076 }
00077
00078
00079
00080
00081 DataSource_Memory::DataSource_Memory(const byte in[], u32bit length)
00082 {
00083 source.set(in, length);
00084 offset = 0;
00085 }
00086
00087
00088
00089
00090 DataSource_Memory::DataSource_Memory(const MemoryRegion<byte>& in)
00091 {
00092 source = in;
00093 offset = 0;
00094 }
00095
00096
00097
00098
00099 DataSource_Memory::DataSource_Memory(const std::string& in)
00100 {
00101 source.set(reinterpret_cast<const byte*>(in.data()), in.length());
00102 offset = 0;
00103 }
00104
00105
00106
00107
00108 u32bit DataSource_Stream::read(byte out[], u32bit length)
00109 {
00110 source->read(reinterpret_cast<char*>(out), length);
00111 if(source->bad())
00112 throw Stream_IO_Error("DataSource_Stream::read: Source failure");
00113
00114 u32bit got = source->gcount();
00115 total_read += got;
00116 return got;
00117 }
00118
00119
00120
00121
00122 u32bit DataSource_Stream::peek(byte out[], u32bit length, u32bit offset) const
00123 {
00124 if(end_of_data())
00125 throw Invalid_State("DataSource_Stream: Cannot peek when out of data");
00126
00127 u32bit got = 0;
00128
00129 if(offset)
00130 {
00131 SecureVector<byte> buf(offset);
00132 source->read(reinterpret_cast<char*>(buf.begin()), buf.size());
00133 if(source->bad())
00134 throw Stream_IO_Error("DataSource_Stream::peek: Source failure");
00135 got = source->gcount();
00136 }
00137
00138 if(got == offset)
00139 {
00140 source->read(reinterpret_cast<char*>(out), length);
00141 if(source->bad())
00142 throw Stream_IO_Error("DataSource_Stream::peek: Source failure");
00143 got = source->gcount();
00144 }
00145
00146 if(source->eof())
00147 source->clear();
00148 source->seekg(total_read, std::ios::beg);
00149
00150 return got;
00151 }
00152
00153
00154
00155
00156 bool DataSource_Stream::end_of_data() const
00157 {
00158 return (!source->good());
00159 }
00160
00161
00162
00163
00164 std::string DataSource_Stream::id() const
00165 {
00166 return identifier;
00167 }
00168
00169
00170
00171
00172 DataSource_Stream::DataSource_Stream(const std::string& path,
00173 bool use_binary) :
00174 identifier(path), owner(true)
00175 {
00176 if(use_binary)
00177 source = new std::ifstream(path.c_str(), std::ios::binary);
00178 else
00179 source = new std::ifstream(path.c_str());
00180
00181 if(!source->good())
00182 throw Stream_IO_Error("DataSource: Failure opening file " + path);
00183
00184 total_read = 0;
00185 }
00186
00187
00188
00189
00190 DataSource_Stream::DataSource_Stream(std::istream& in,
00191 const std::string& name) :
00192 identifier(name), owner(false)
00193 {
00194 source = ∈
00195 total_read = 0;
00196 }
00197
00198
00199
00200
00201 DataSource_Stream::~DataSource_Stream()
00202 {
00203 if(owner)
00204 delete source;
00205 }
00206
00207 }