Botan  1.11.15
src/lib/filters/data_src.cpp
Go to the documentation of this file.
00001 /*
00002 * DataSource
00003 * (C) 1999-2007 Jack Lloyd
00004 *     2005 Matthew Gregan
00005 *
00006 * Botan is released under the Simplified BSD License (see license.txt)
00007 */
00008 
00009 #include <botan/data_src.h>
00010 #include <botan/exceptn.h>
00011 #include <fstream>
00012 #include <algorithm>
00013 
00014 namespace Botan {
00015 
00016 /*
00017 * Read a single byte from the DataSource
00018 */
00019 size_t DataSource::read_byte(byte& out)
00020    {
00021    return read(&out, 1);
00022    }
00023 
00024 /*
00025 * Peek a single byte from the DataSource
00026 */
00027 size_t DataSource::peek_byte(byte& out) const
00028    {
00029    return peek(&out, 1, 0);
00030    }
00031 
00032 /*
00033 * Discard the next N bytes of the data
00034 */
00035 size_t DataSource::discard_next(size_t n)
00036    {
00037    size_t discarded = 0;
00038    byte dummy;
00039    for(size_t j = 0; j != n; ++j)
00040       discarded += read_byte(dummy);
00041    return discarded;
00042    }
00043 
00044 /*
00045 * Read from a memory buffer
00046 */
00047 size_t DataSource_Memory::read(byte out[], size_t length)
00048    {
00049    size_t got = std::min<size_t>(source.size() - offset, length);
00050    copy_mem(out, &source[offset], got);
00051    offset += got;
00052    return got;
00053    }
00054 
00055 /*
00056 * Peek into a memory buffer
00057 */
00058 size_t DataSource_Memory::peek(byte out[], size_t length,
00059                                size_t peek_offset) const
00060    {
00061    const size_t bytes_left = source.size() - offset;
00062    if(peek_offset >= bytes_left) return 0;
00063 
00064    size_t got = std::min(bytes_left - peek_offset, length);
00065    copy_mem(out, &source[offset + peek_offset], got);
00066    return got;
00067    }
00068 
00069 /*
00070 * Check if the memory buffer is empty
00071 */
00072 bool DataSource_Memory::end_of_data() const
00073    {
00074    return (offset == source.size());
00075    }
00076 
00077 /*
00078 * DataSource_Memory Constructor
00079 */
00080 DataSource_Memory::DataSource_Memory(const std::string& in) :
00081    source(reinterpret_cast<const byte*>(in.data()),
00082           reinterpret_cast<const byte*>(in.data()) + in.length()),
00083    offset(0)
00084    {
00085    offset = 0;
00086    }
00087 
00088 /*
00089 * Read from a stream
00090 */
00091 size_t DataSource_Stream::read(byte out[], size_t length)
00092    {
00093    source.read(reinterpret_cast<char*>(out), length);
00094    if(source.bad())
00095       throw Stream_IO_Error("DataSource_Stream::read: Source failure");
00096 
00097    size_t got = source.gcount();
00098    total_read += got;
00099    return got;
00100    }
00101 
00102 /*
00103 * Peek into a stream
00104 */
00105 size_t DataSource_Stream::peek(byte out[], size_t length, size_t offset) const
00106    {
00107    if(end_of_data())
00108       throw Invalid_State("DataSource_Stream: Cannot peek when out of data");
00109 
00110    size_t got = 0;
00111 
00112    if(offset)
00113       {
00114       secure_vector<byte> buf(offset);
00115       source.read(reinterpret_cast<char*>(&buf[0]), buf.size());
00116       if(source.bad())
00117          throw Stream_IO_Error("DataSource_Stream::peek: Source failure");
00118       got = source.gcount();
00119       }
00120 
00121    if(got == offset)
00122       {
00123       source.read(reinterpret_cast<char*>(out), length);
00124       if(source.bad())
00125          throw Stream_IO_Error("DataSource_Stream::peek: Source failure");
00126       got = source.gcount();
00127       }
00128 
00129    if(source.eof())
00130       source.clear();
00131    source.seekg(total_read, std::ios::beg);
00132 
00133    return got;
00134    }
00135 
00136 /*
00137 * Check if the stream is empty or in error
00138 */
00139 bool DataSource_Stream::end_of_data() const
00140    {
00141    return (!source.good());
00142    }
00143 
00144 /*
00145 * Return a human-readable ID for this stream
00146 */
00147 std::string DataSource_Stream::id() const
00148    {
00149    return identifier;
00150    }
00151 
00152 /*
00153 * DataSource_Stream Constructor
00154 */
00155 DataSource_Stream::DataSource_Stream(const std::string& path,
00156                                      bool use_binary) :
00157    identifier(path),
00158    source_p(new std::ifstream(
00159                path.c_str(),
00160                use_binary ? std::ios::binary : std::ios::in)),
00161    source(*source_p),
00162    total_read(0)
00163    {
00164    if(!source.good())
00165       {
00166       delete source_p;
00167       throw Stream_IO_Error("DataSource: Failure opening file " + path);
00168       }
00169    }
00170 
00171 /*
00172 * DataSource_Stream Constructor
00173 */
00174 DataSource_Stream::DataSource_Stream(std::istream& in,
00175                                      const std::string& name) :
00176    identifier(name),
00177    source_p(nullptr),
00178    source(in),
00179    total_read(0)
00180    {
00181    }
00182 
00183 /*
00184 * DataSource_Stream Destructor
00185 */
00186 DataSource_Stream::~DataSource_Stream()
00187    {
00188    delete source_p;
00189    }
00190 
00191 }