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
|
/*************************************************
* Pipe Reading/Writing Source File *
* (C) 1999-2005 The Botan Project *
*************************************************/
#include <botan/pipe.h>
#include <botan/out_buf.h>
#include <botan/secqueue.h>
namespace Botan {
/*************************************************
* Look up the canonical ID for a queue *
*************************************************/
u32bit Pipe::get_message_no(const std::string& func_name, u32bit msg) const
{
if(msg == DEFAULT_MESSAGE)
msg = default_msg();
else if(msg == LAST_MESSAGE)
msg = message_count() - 1;
if(msg >= message_count())
throw Invalid_Message_Number(func_name, msg);
return msg;
}
/*************************************************
* Write into a Pipe *
*************************************************/
void Pipe::write(const byte input[], u32bit length)
{
if(!inside_msg)
throw Exception("Cannot write to a Pipe while it is not processing");
pipe->write(input, length);
}
/*************************************************
* Write into a Pipe *
*************************************************/
void Pipe::write(const MemoryRegion<byte>& input)
{
write(input.begin(), input.size());
}
/*************************************************
* Write a string into a Pipe *
*************************************************/
void Pipe::write(const std::string& str)
{
write((const byte*)str.c_str(), str.size());
}
/*************************************************
* Write a single byte into a Pipe *
*************************************************/
void Pipe::write(byte input)
{
write(&input, 1);
}
/*************************************************
* Write the contents of a DataSource into a Pipe *
*************************************************/
void Pipe::write(DataSource& source)
{
SecureVector<byte> buffer(DEFAULT_BUFFERSIZE);
while(!source.end_of_data())
{
u32bit got = source.read(buffer, buffer.size());
write(buffer, got);
}
}
/*************************************************
* Read some data from the pipe *
*************************************************/
u32bit Pipe::read(byte output[], u32bit length, u32bit msg)
{
return outputs->read(output, length, get_message_no("read", msg));
}
/*************************************************
* Read some data from the pipe *
*************************************************/
u32bit Pipe::read(byte output[], u32bit length)
{
return read(output, length, DEFAULT_MESSAGE);
}
/*************************************************
* Read a single byte from the pipe *
*************************************************/
u32bit Pipe::read(byte& out, u32bit msg)
{
return read(&out, 1, msg);
}
/*************************************************
* Return all data in the pipe *
*************************************************/
SecureVector<byte> Pipe::read_all(u32bit msg)
{
msg = ((msg != DEFAULT_MESSAGE) ? msg : default_msg());
SecureVector<byte> buffer(remaining(msg));
read(buffer, buffer.size(), msg);
return buffer;
}
/*************************************************
* Return all data in the pipe as a string *
*************************************************/
std::string Pipe::read_all_as_string(u32bit msg)
{
msg = ((msg != DEFAULT_MESSAGE) ? msg : default_msg());
SecureVector<byte> buffer(DEFAULT_BUFFERSIZE);
std::string str;
str.reserve(remaining(msg));
while(true)
{
u32bit got = read(buffer, buffer.size(), msg);
if(got == 0)
break;
str.append((const char*)buffer.begin(), got);
}
return str;
}
/*************************************************
* Find out how many bytes are ready to read *
*************************************************/
u32bit Pipe::remaining(u32bit msg) const
{
return outputs->remaining(get_message_no("remaining", msg));
}
/*************************************************
* Peek at some data in the pipe *
*************************************************/
u32bit Pipe::peek(byte output[], u32bit length,
u32bit offset, u32bit msg) const
{
return outputs->peek(output, length, offset, get_message_no("peek", msg));
}
/*************************************************
* Peek at some data in the pipe *
*************************************************/
u32bit Pipe::peek(byte output[], u32bit length, u32bit offset) const
{
return peek(output, length, offset, DEFAULT_MESSAGE);
}
/*************************************************
* Peek at a byte in the pipe *
*************************************************/
u32bit Pipe::peek(byte& out, u32bit offset, u32bit msg) const
{
return peek(&out, 1, offset, msg);
}
}
|