Below is the file 'botan/pipe_rw.cpp' from this revision. You can also download the file.

/*************************************************
* Pipe Reading/Writing Source File               *
* (C) 1999-2005 The Botan Project                *
*************************************************/

#include <botan/pipe.h>
#include <botan/secqueue.h>

namespace Botan {

/*************************************************
* Write into a Pipe                              *
*************************************************/
SecureQueue* Pipe::get_message(const std::string& func_name, u32bit msg) const
   {
   if(msg == MAX_MESSAGES)
      throw Invalid_State("Pipe::get_message: overflow of message counter");

   if(msg == DEFAULT_MESSAGE)   msg = default_msg();
   else if(msg == LAST_MESSAGE) msg = message_count() - 1;

   if(msg >= messages.size())
      throw Invalid_Message_Number(func_name, msg);
   if(messages[msg])
      return messages[msg];
   else
      throw Internal_Error("Pipe:get_message: got NULL for message #" +
                           to_string(msg));
   }

/*************************************************
* Write into a Pipe                              *
*************************************************/
void Pipe::write(const byte input[], u32bit length)
   {
   if(!locked)
      throw Exception("Cannot write to a Pipe while it is unlocked");
   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)
   {
   SecureQueue* msg_queue = get_message("read", msg);
   if(msg_queue)
      return msg_queue->read(output, length);
   else
      return 0;
   }

/*************************************************
* 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
   {
   SecureQueue* msg_queue = get_message("remaining", msg);
   if(msg_queue)
      return msg_queue->size();
   else
      return 0;
   }

/*************************************************
* Peek at some data in the pipe                  *
*************************************************/
u32bit Pipe::peek(byte output[], u32bit length,
                  u32bit offset, u32bit msg) const
   {
   SecureQueue* msg_queue = get_message("peek", msg);
   if(msg_queue)
      return msg_queue->peek(output, length, offset);
   else
      return 0;
   }

/*************************************************
* 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);
   }

}