summary refs log tree commit diff
path: root/nix/libutil/serialise.hh
diff options
context:
space:
mode:
authorLudovic Courtès <ludo@gnu.org>2014-12-17 23:00:42 +0100
committerLudovic Courtès <ludo@gnu.org>2014-12-19 22:47:37 +0100
commit36457566f9917dc7c0c348d012816a2ca333ef1b (patch)
tree6f1d22a195ea2483b9ce539227d65e8e2a9c137d /nix/libutil/serialise.hh
parent2c7ee1672029aa43afb509af5b5f7261244fa2d1 (diff)
downloadguix-36457566f9917dc7c0c348d012816a2ca333ef1b.tar.gz
Merge branch 'nix' into 'master'.
Diffstat (limited to 'nix/libutil/serialise.hh')
-rw-r--r--nix/libutil/serialise.hh133
1 files changed, 133 insertions, 0 deletions
diff --git a/nix/libutil/serialise.hh b/nix/libutil/serialise.hh
new file mode 100644
index 0000000000..e5a9df1d05
--- /dev/null
+++ b/nix/libutil/serialise.hh
@@ -0,0 +1,133 @@
+#pragma once
+
+#include "types.hh"
+
+
+namespace nix {
+
+
+/* Abstract destination of binary data. */
+struct Sink 
+{
+    virtual ~Sink() { }
+    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();
+
+    void operator () (const unsigned char * data, size_t len);
+    
+    void flush();
+    
+    virtual void write(const unsigned char * data, size_t len) = 0;
+};
+
+
+/* Abstract source of binary data. */
+struct Source
+{
+    virtual ~Source() { }
+    
+    /* Store exactly ‘len’ bytes in the buffer pointed to by ‘data’.
+       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;
+};
+
+
+/* A buffered abstract source. */
+struct BufferedSource : Source
+{
+    size_t bufSize, bufPosIn, bufPosOut;
+    unsigned char * buffer;
+
+    BufferedSource(size_t bufSize = 32 * 1024)
+        : bufSize(bufSize), bufPosIn(0), bufPosOut(0), buffer(0) { }
+    ~BufferedSource();
+    
+    size_t read(unsigned char * data, size_t len);
+    
+    /* Underlying read call, to be overridden. */
+    virtual size_t readUnbuffered(unsigned char * data, size_t len) = 0;
+
+    bool hasData();
+};
+
+
+/* A sink that writes data to a file descriptor. */
+struct FdSink : BufferedSink
+{
+    int fd;
+
+    FdSink() : fd(-1) { }
+    FdSink(int fd) : fd(fd) { }
+    ~FdSink();
+    
+    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) { }
+    size_t readUnbuffered(unsigned char * data, size_t len);
+};
+
+
+/* A sink that writes data to a string. */
+struct StringSink : Sink
+{
+    string s;
+    void operator () (const unsigned char * data, size_t len)
+    {
+        s.append((const char *) data, len);
+    }
+};
+
+
+/* A source that reads data from a string. */
+struct StringSource : Source
+{
+    const string & s;
+    size_t pos;
+    StringSource(const string & _s) : s(_s), pos(0) { }
+    size_t read(unsigned char * data, size_t len);    
+};
+
+
+void writePadding(size_t len, Sink & sink);
+void writeInt(unsigned int n, Sink & sink);
+void writeLongLong(unsigned long long n, Sink & sink);
+void writeString(const unsigned char * buf, size_t len, Sink & sink);
+void writeString(const string & s, Sink & sink);
+template<class T> void writeStrings(const T & ss, Sink & sink);
+
+void readPadding(size_t len, Source & source);
+unsigned int readInt(Source & source);
+unsigned long long readLongLong(Source & source);
+size_t readString(unsigned char * buf, size_t max, Source & source);
+string readString(Source & source);
+template<class T> T readStrings(Source & source);
+
+
+MakeError(SerialisationError, Error)
+
+
+}