2012-07-18 21:59:03 +03:00
|
|
|
|
#pragma once
|
2006-11-30 21:19:59 +02:00
|
|
|
|
|
|
|
|
|
#include "types.hh"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
namespace nix {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Abstract destination of binary data. */
|
|
|
|
|
struct Sink
|
|
|
|
|
{
|
|
|
|
|
virtual ~Sink() { }
|
2011-12-15 18:19:53 +02:00
|
|
|
|
virtual void operator () (const unsigned char * data, size_t len) = 0;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* A buffered abstract sink. */
|
|
|
|
|
struct BufferedSink : Sink
|
|
|
|
|
{
|
|
|
|
|
size_t bufSize, bufPos;
|
|
|
|
|
unsigned char * buffer;
|
|
|
|
|
|
|
|
|
|
BufferedSink(size_t bufSize = 32 * 1024)
|
|
|
|
|
: bufSize(bufSize), bufPos(0), buffer(0) { }
|
|
|
|
|
~BufferedSink();
|
2011-12-16 21:44:13 +02:00
|
|
|
|
|
2011-12-15 18:19:53 +02:00
|
|
|
|
void operator () (const unsigned char * data, size_t len);
|
|
|
|
|
|
|
|
|
|
void flush();
|
|
|
|
|
|
|
|
|
|
virtual void write(const unsigned char * data, size_t len) = 0;
|
2006-11-30 21:19:59 +02:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Abstract source of binary data. */
|
|
|
|
|
struct Source
|
|
|
|
|
{
|
|
|
|
|
virtual ~Source() { }
|
|
|
|
|
|
2011-12-15 18:19:53 +02:00
|
|
|
|
/* Store exactly ‘len’ bytes in the buffer pointed to by ‘data’.
|
2011-12-16 21:44:13 +02:00
|
|
|
|
It blocks until all the requested data is available, or throws
|
|
|
|
|
an error if it is not going to be available. */
|
|
|
|
|
void operator () (unsigned char * data, size_t len);
|
|
|
|
|
|
|
|
|
|
/* Store up to ‘len’ in the buffer pointed to by ‘data’, and
|
|
|
|
|
return the number of bytes stored. If blocks until at least
|
|
|
|
|
one byte is available. */
|
|
|
|
|
virtual size_t read(unsigned char * data, size_t len) = 0;
|
2006-11-30 21:19:59 +02:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
2011-12-15 18:19:53 +02:00
|
|
|
|
/* A buffered abstract source. */
|
|
|
|
|
struct BufferedSource : Source
|
2006-11-30 21:19:59 +02:00
|
|
|
|
{
|
2011-12-15 18:19:53 +02:00
|
|
|
|
size_t bufSize, bufPosIn, bufPosOut;
|
2011-12-15 01:30:06 +02:00
|
|
|
|
unsigned char * buffer;
|
2006-11-30 21:19:59 +02:00
|
|
|
|
|
2011-12-15 18:19:53 +02:00
|
|
|
|
BufferedSource(size_t bufSize = 32 * 1024)
|
|
|
|
|
: bufSize(bufSize), bufPosIn(0), bufPosOut(0), buffer(0) { }
|
|
|
|
|
~BufferedSource();
|
2011-12-15 01:30:06 +02:00
|
|
|
|
|
2011-12-16 21:44:13 +02:00
|
|
|
|
size_t read(unsigned char * data, size_t len);
|
2006-11-30 21:19:59 +02:00
|
|
|
|
|
2013-08-11 00:36:16 +03:00
|
|
|
|
/* Underlying read call, to be overridden. */
|
2011-12-16 21:44:13 +02:00
|
|
|
|
virtual size_t readUnbuffered(unsigned char * data, size_t len) = 0;
|
2013-06-07 16:02:14 +03:00
|
|
|
|
|
|
|
|
|
bool hasData();
|
2006-11-30 21:19:59 +02:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
2011-12-15 18:19:53 +02:00
|
|
|
|
/* A sink that writes data to a file descriptor. */
|
|
|
|
|
struct FdSink : BufferedSink
|
2006-11-30 21:19:59 +02:00
|
|
|
|
{
|
|
|
|
|
int fd;
|
2014-06-12 14:15:35 +03:00
|
|
|
|
bool warn = false;
|
|
|
|
|
size_t written = 0;
|
2006-11-30 21:19:59 +02:00
|
|
|
|
|
2011-12-15 18:19:53 +02:00
|
|
|
|
FdSink() : fd(-1) { }
|
|
|
|
|
FdSink(int fd) : fd(fd) { }
|
2011-12-16 17:45:42 +02:00
|
|
|
|
~FdSink();
|
2006-11-30 21:19:59 +02:00
|
|
|
|
|
2011-12-15 18:19:53 +02:00
|
|
|
|
void write(const unsigned char * data, size_t len);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* A source that reads data from a file descriptor. */
|
|
|
|
|
struct FdSource : BufferedSource
|
|
|
|
|
{
|
|
|
|
|
int fd;
|
|
|
|
|
FdSource() : fd(-1) { }
|
|
|
|
|
FdSource(int fd) : fd(fd) { }
|
2011-12-16 21:44:13 +02:00
|
|
|
|
size_t readUnbuffered(unsigned char * data, size_t len);
|
2006-11-30 21:19:59 +02:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
2006-12-13 01:05:01 +02:00
|
|
|
|
/* A sink that writes data to a string. */
|
|
|
|
|
struct StringSink : Sink
|
|
|
|
|
{
|
|
|
|
|
string s;
|
2014-06-10 14:30:09 +03:00
|
|
|
|
void operator () (const unsigned char * data, size_t len);
|
2006-12-13 01:05:01 +02:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* A source that reads data from a string. */
|
|
|
|
|
struct StringSource : Source
|
|
|
|
|
{
|
2008-12-03 19:30:32 +02:00
|
|
|
|
const string & s;
|
2011-12-15 18:19:53 +02:00
|
|
|
|
size_t pos;
|
2008-12-03 19:30:32 +02:00
|
|
|
|
StringSource(const string & _s) : s(_s), pos(0) { }
|
2011-12-16 21:44:13 +02:00
|
|
|
|
size_t read(unsigned char * data, size_t len);
|
2006-12-13 01:05:01 +02:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
2011-12-15 18:19:53 +02:00
|
|
|
|
void writePadding(size_t len, Sink & sink);
|
2006-11-30 21:19:59 +02:00
|
|
|
|
void writeInt(unsigned int n, Sink & sink);
|
2008-06-18 12:34:17 +03:00
|
|
|
|
void writeLongLong(unsigned long long n, Sink & sink);
|
2011-12-16 23:29:46 +02:00
|
|
|
|
void writeString(const unsigned char * buf, size_t len, Sink & sink);
|
2006-11-30 21:19:59 +02:00
|
|
|
|
void writeString(const string & s, Sink & sink);
|
2011-12-17 00:31:25 +02:00
|
|
|
|
template<class T> void writeStrings(const T & ss, Sink & sink);
|
2006-11-30 21:19:59 +02:00
|
|
|
|
|
2011-12-15 18:19:53 +02:00
|
|
|
|
void readPadding(size_t len, Source & source);
|
2006-11-30 21:19:59 +02:00
|
|
|
|
unsigned int readInt(Source & source);
|
2008-06-18 12:34:17 +03:00
|
|
|
|
unsigned long long readLongLong(Source & source);
|
2011-12-16 23:29:46 +02:00
|
|
|
|
size_t readString(unsigned char * buf, size_t max, Source & source);
|
2006-11-30 21:19:59 +02:00
|
|
|
|
string readString(Source & source);
|
2011-12-17 00:31:25 +02:00
|
|
|
|
template<class T> T readStrings(Source & source);
|
2006-12-01 00:43:55 +02:00
|
|
|
|
|
2006-11-30 21:19:59 +02:00
|
|
|
|
|
2009-03-22 19:36:43 +02:00
|
|
|
|
MakeError(SerialisationError, Error)
|
|
|
|
|
|
|
|
|
|
|
2006-11-30 21:19:59 +02:00
|
|
|
|
}
|