Botan  1.11.15
src/lib/filters/pipe_rw.cpp
Go to the documentation of this file.
00001 /*
00002 * Pipe Reading/Writing
00003 * (C) 1999-2007 Jack Lloyd
00004 *     2012 Markus Wanner
00005 *
00006 * Botan is released under the Simplified BSD License (see license.txt)
00007 */
00008 
00009 #include <botan/pipe.h>
00010 #include <botan/internal/out_buf.h>
00011 #include <botan/secqueue.h>
00012 
00013 namespace Botan {
00014 
00015 /*
00016 * Look up the canonical ID for a queue
00017 */
00018 Pipe::message_id Pipe::get_message_no(const std::string& func_name,
00019                                       message_id msg) const
00020    {
00021    if(msg == DEFAULT_MESSAGE)
00022       msg = default_msg();
00023    else if(msg == LAST_MESSAGE)
00024       msg = message_count() - 1;
00025 
00026    if(msg >= message_count())
00027       throw Invalid_Message_Number(func_name, msg);
00028 
00029    return msg;
00030    }
00031 
00032 /*
00033 * Write into a Pipe
00034 */
00035 void Pipe::write(const byte input[], size_t length)
00036    {
00037    if(!inside_msg)
00038       throw Invalid_State("Cannot write to a Pipe while it is not processing");
00039    pipe->write(input, length);
00040    }
00041 
00042 /*
00043 * Write a string into a Pipe
00044 */
00045 void Pipe::write(const std::string& str)
00046    {
00047    write(reinterpret_cast<const byte*>(str.data()), str.size());
00048    }
00049 
00050 /*
00051 * Write a single byte into a Pipe
00052 */
00053 void Pipe::write(byte input)
00054    {
00055    write(&input, 1);
00056    }
00057 
00058 /*
00059 * Write the contents of a DataSource into a Pipe
00060 */
00061 void Pipe::write(DataSource& source)
00062    {
00063    secure_vector<byte> buffer(DEFAULT_BUFFERSIZE);
00064    while(!source.end_of_data())
00065       {
00066       size_t got = source.read(&buffer[0], buffer.size());
00067       write(&buffer[0], got);
00068       }
00069    }
00070 
00071 /*
00072 * Read some data from the pipe
00073 */
00074 size_t Pipe::read(byte output[], size_t length, message_id msg)
00075    {
00076    return outputs->read(output, length, get_message_no("read", msg));
00077    }
00078 
00079 /*
00080 * Read some data from the pipe
00081 */
00082 size_t Pipe::read(byte output[], size_t length)
00083    {
00084    return read(output, length, DEFAULT_MESSAGE);
00085    }
00086 
00087 /*
00088 * Read a single byte from the pipe
00089 */
00090 size_t Pipe::read(byte& out, message_id msg)
00091    {
00092    return read(&out, 1, msg);
00093    }
00094 
00095 /*
00096 * Return all data in the pipe
00097 */
00098 secure_vector<byte> Pipe::read_all(message_id msg)
00099    {
00100    msg = ((msg != DEFAULT_MESSAGE) ? msg : default_msg());
00101    secure_vector<byte> buffer(remaining(msg));
00102    size_t got = read(&buffer[0], buffer.size(), msg);
00103    buffer.resize(got);
00104    return buffer;
00105    }
00106 
00107 /*
00108 * Return all data in the pipe as a string
00109 */
00110 std::string Pipe::read_all_as_string(message_id msg)
00111    {
00112    msg = ((msg != DEFAULT_MESSAGE) ? msg : default_msg());
00113    secure_vector<byte> buffer(DEFAULT_BUFFERSIZE);
00114    std::string str;
00115    str.reserve(remaining(msg));
00116 
00117    while(true)
00118       {
00119       size_t got = read(&buffer[0], buffer.size(), msg);
00120       if(got == 0)
00121          break;
00122       str.append(reinterpret_cast<const char*>(&buffer[0]), got);
00123       }
00124 
00125    return str;
00126    }
00127 
00128 /*
00129 * Find out how many bytes are ready to read
00130 */
00131 size_t Pipe::remaining(message_id msg) const
00132    {
00133    return outputs->remaining(get_message_no("remaining", msg));
00134    }
00135 
00136 /*
00137 * Peek at some data in the pipe
00138 */
00139 size_t Pipe::peek(byte output[], size_t length,
00140                   size_t offset, message_id msg) const
00141    {
00142    return outputs->peek(output, length, offset, get_message_no("peek", msg));
00143    }
00144 
00145 /*
00146 * Peek at some data in the pipe
00147 */
00148 size_t Pipe::peek(byte output[], size_t length, size_t offset) const
00149    {
00150    return peek(output, length, offset, DEFAULT_MESSAGE);
00151    }
00152 
00153 /*
00154 * Peek at a byte in the pipe
00155 */
00156 size_t Pipe::peek(byte& out, size_t offset, message_id msg) const
00157    {
00158    return peek(&out, 1, offset, msg);
00159    }
00160 
00161 size_t Pipe::get_bytes_read() const
00162    {
00163    return outputs->get_bytes_read(DEFAULT_MESSAGE);
00164    }
00165 
00166 size_t Pipe::get_bytes_read(message_id msg) const
00167    {
00168    return outputs->get_bytes_read(msg);
00169    }
00170 
00171 }