aboutsummaryrefslogtreecommitdiff
path: root/src/libutil
diff options
context:
space:
mode:
Diffstat (limited to 'src/libutil')
-rw-r--r--src/libutil/Makefile.am6
-rw-r--r--src/libutil/archive.cc88
-rw-r--r--src/libutil/archive.hh23
-rw-r--r--src/libutil/hash.cc2
-rw-r--r--src/libutil/serialise.cc87
-rw-r--r--src/libutil/serialise.hh71
6 files changed, 177 insertions, 100 deletions
diff --git a/src/libutil/Makefile.am b/src/libutil/Makefile.am
index cf75be8a8..bd0996543 100644
--- a/src/libutil/Makefile.am
+++ b/src/libutil/Makefile.am
@@ -1,10 +1,12 @@
pkglib_LTLIBRARIES = libutil.la
-libutil_la_SOURCES = util.cc hash.cc archive.cc aterm.cc aterm-map.cc xml-writer.cc
+libutil_la_SOURCES = util.cc hash.cc serialise.cc \
+ archive.cc aterm.cc aterm-map.cc xml-writer.cc
libutil_la_LIBADD = ../boost/format/libformat.la
-pkginclude_HEADERS = util.hh hash.hh archive.hh aterm.hh aterm-map.hh xml-writer.hh types.hh
+pkginclude_HEADERS = util.hh hash.hh serialise.hh \
+ archive.hh aterm.hh aterm-map.hh xml-writer.hh types.hh
if !HAVE_OPENSSL
libutil_la_SOURCES += \
diff --git a/src/libutil/archive.cc b/src/libutil/archive.cc
index 32c75fee5..e3bd63db0 100644
--- a/src/libutil/archive.cc
+++ b/src/libutil/archive.cc
@@ -18,41 +18,10 @@ namespace nix {
static string archiveVersion1 = "nix-archive-1";
-static void writePadding(unsigned int len, DumpSink & sink)
-{
- if (len % 8) {
- unsigned char zero[8];
- memset(zero, 0, sizeof(zero));
- sink(zero, 8 - (len % 8));
- }
-}
-
-
-static void writeInt(unsigned int n, DumpSink & sink)
-{
- unsigned char buf[8];
- memset(buf, 0, sizeof(buf));
- buf[0] = n & 0xff;
- buf[1] = (n >> 8) & 0xff;
- buf[2] = (n >> 16) & 0xff;
- buf[3] = (n >> 24) & 0xff;
- sink(buf, sizeof(buf));
-}
-
-
-static void writeString(const string & s, DumpSink & sink)
-{
- unsigned int len = s.length();
- writeInt(len, sink);
- sink((const unsigned char *) s.c_str(), len);
- writePadding(len, sink);
-}
-
-
-static void dump(const string & path, DumpSink & sink);
+static void dump(const string & path, Sink & sink);
-static void dumpEntries(const Path & path, DumpSink & sink)
+static void dumpEntries(const Path & path, Sink & sink)
{
Strings names = readDirectory(path);
vector<string> names2(names.begin(), names.end());
@@ -73,7 +42,7 @@ static void dumpEntries(const Path & path, DumpSink & sink)
static void dumpContents(const Path & path, unsigned int size,
- DumpSink & sink)
+ Sink & sink)
{
writeString("contents", sink);
writeInt(size, sink);
@@ -95,7 +64,7 @@ static void dumpContents(const Path & path, unsigned int size,
}
-static void dump(const Path & path, DumpSink & sink)
+static void dump(const Path & path, Sink & sink)
{
struct stat st;
if (lstat(path.c_str(), &st))
@@ -132,7 +101,7 @@ static void dump(const Path & path, DumpSink & sink)
}
-void dumpPath(const Path & path, DumpSink & sink)
+void dumpPath(const Path & path, Sink & sink)
{
writeString(archiveVersion1, sink);
dump(path, sink);
@@ -145,42 +114,7 @@ static Error badArchive(string s)
}
-static void readPadding(unsigned int len, RestoreSource & source)
-{
- if (len % 8) {
- unsigned char zero[8];
- unsigned int n = 8 - (len % 8);
- source(zero, n);
- for (unsigned int i = 0; i < n; i++)
- if (zero[i]) throw badArchive("non-zero padding");
- }
-}
-
-static unsigned int readInt(RestoreSource & source)
-{
- unsigned char buf[8];
- source(buf, sizeof(buf));
- if (buf[4] || buf[5] || buf[6] || buf[7])
- throw Error("implementation cannot deal with > 32-bit integers");
- return
- buf[0] |
- (buf[1] << 8) |
- (buf[2] << 16) |
- (buf[3] << 24);
-}
-
-
-static string readString(RestoreSource & source)
-{
- unsigned int len = readInt(source);
- char buf[len];
- source((unsigned char *) buf, len);
- readPadding(len, source);
- return string(buf, len);
-}
-
-
-static void skipGeneric(RestoreSource & source)
+static void skipGeneric(Source & source)
{
if (readString(source) == "(") {
while (readString(source) != ")")
@@ -189,10 +123,10 @@ static void skipGeneric(RestoreSource & source)
}
-static void restore(const Path & path, RestoreSource & source);
+static void restore(const Path & path, Source & source);
-static void restoreEntry(const Path & path, RestoreSource & source)
+static void restoreEntry(const Path & path, Source & source)
{
string s, name;
@@ -219,7 +153,7 @@ static void restoreEntry(const Path & path, RestoreSource & source)
}
-static void restoreContents(int fd, const Path & path, RestoreSource & source)
+static void restoreContents(int fd, const Path & path, Source & source)
{
unsigned int size = readInt(source);
unsigned int left = size;
@@ -238,7 +172,7 @@ static void restoreContents(int fd, const Path & path, RestoreSource & source)
}
-static void restore(const Path & path, RestoreSource & source)
+static void restore(const Path & path, Source & source)
{
string s;
@@ -315,7 +249,7 @@ static void restore(const Path & path, RestoreSource & source)
}
-void restorePath(const Path & path, RestoreSource & source)
+void restorePath(const Path & path, Source & source)
{
if (readString(source) != archiveVersion1)
throw badArchive("expected Nix archive");
diff --git a/src/libutil/archive.hh b/src/libutil/archive.hh
index f85d589c6..c70ef3f1c 100644
--- a/src/libutil/archive.hh
+++ b/src/libutil/archive.hh
@@ -2,6 +2,7 @@
#define __ARCHIVE_H
#include "types.hh"
+#include "serialise.hh"
namespace nix {
@@ -44,27 +45,9 @@ namespace nix {
`+' denotes string concatenation. */
-struct DumpSink
-{
- virtual ~DumpSink() { }
- virtual void operator () (const unsigned char * data, unsigned int len) = 0;
-};
+void dumpPath(const Path & path, Sink & sink);
-void dumpPath(const Path & path, DumpSink & sink);
-
-
-struct RestoreSource
-{
- virtual ~RestoreSource() { }
-
- /* The callee should store exactly *len bytes in the buffer
- pointed to by data. It should block if that much data is not
- yet available, or throw an error if it is not going to be
- available. */
- virtual void operator () (unsigned char * data, unsigned int len) = 0;
-};
-
-void restorePath(const Path & path, RestoreSource & source);
+void restorePath(const Path & path, Source & source);
}
diff --git a/src/libutil/hash.cc b/src/libutil/hash.cc
index 7381948f2..8dc33f5d0 100644
--- a/src/libutil/hash.cc
+++ b/src/libutil/hash.cc
@@ -282,7 +282,7 @@ Hash hashFile(HashType ht, const Path & path)
}
-struct HashSink : DumpSink
+struct HashSink : Sink
{
HashType ht;
Ctx ctx;
diff --git a/src/libutil/serialise.cc b/src/libutil/serialise.cc
new file mode 100644
index 000000000..aa11c590a
--- /dev/null
+++ b/src/libutil/serialise.cc
@@ -0,0 +1,87 @@
+#include "serialise.hh"
+#include "util.hh"
+
+
+namespace nix {
+
+
+void FdSink::operator () (const unsigned char * data, unsigned int len)
+{
+ writeFull(fd, data, len);
+}
+
+
+void FdSource::operator () (unsigned char * data, unsigned int len)
+{
+ readFull(fd, data, len);
+}
+
+
+void writePadding(unsigned int len, Sink & sink)
+{
+ if (len % 8) {
+ unsigned char zero[8];
+ memset(zero, 0, sizeof(zero));
+ sink(zero, 8 - (len % 8));
+ }
+}
+
+
+void writeInt(unsigned int n, Sink & sink)
+{
+ unsigned char buf[8];
+ memset(buf, 0, sizeof(buf));
+ buf[0] = n & 0xff;
+ buf[1] = (n >> 8) & 0xff;
+ buf[2] = (n >> 16) & 0xff;
+ buf[3] = (n >> 24) & 0xff;
+ sink(buf, sizeof(buf));
+}
+
+
+void writeString(const string & s, Sink & sink)
+{
+ unsigned int len = s.length();
+ writeInt(len, sink);
+ sink((const unsigned char *) s.c_str(), len);
+ writePadding(len, sink);
+}
+
+
+void readPadding(unsigned int len, Source & source)
+{
+ if (len % 8) {
+ unsigned char zero[8];
+ unsigned int n = 8 - (len % 8);
+ source(zero, n);
+ for (unsigned int i = 0; i < n; i++)
+ if (zero[i]) throw Error("non-zero padding");
+ }
+}
+
+
+unsigned int readInt(Source & source)
+{
+ unsigned char buf[8];
+ source(buf, sizeof(buf));
+ if (buf[4] || buf[5] || buf[6] || buf[7])
+ throw Error("implementation cannot deal with > 32-bit integers");
+ return
+ buf[0] |
+ (buf[1] << 8) |
+ (buf[2] << 16) |
+ (buf[3] << 24);
+}
+
+
+string readString(Source & source)
+{
+ unsigned int len = readInt(source);
+ char buf[len];
+ source((unsigned char *) buf, len);
+ readPadding(len, source);
+ return string(buf, len);
+}
+
+
+}
diff --git a/src/libutil/serialise.hh b/src/libutil/serialise.hh
new file mode 100644
index 000000000..459a693ee
--- /dev/null
+++ b/src/libutil/serialise.hh
@@ -0,0 +1,71 @@
+#ifndef __SERIALISE_H
+#define __SERIALISE_H
+
+#include "types.hh"
+
+
+namespace nix {
+
+
+/* Abstract destination of binary data. */
+struct Sink
+{
+ virtual ~Sink() { }
+ virtual void operator () (const unsigned char * data, unsigned int len) = 0;
+};
+
+
+/* Abstract source of binary data. */
+struct Source
+{
+ virtual ~Source() { }
+
+ /* The callee should store exactly *len bytes in the buffer
+ pointed to by data. It should block if that much data is not
+ yet available, or throw an error if it is not going to be
+ available. */
+ virtual void operator () (unsigned char * data, unsigned int len) = 0;
+};
+
+
+/* A sink that writes data to a file descriptor. */
+struct FdSink : Sink
+{
+ int fd;
+
+ FdSink(int fd)
+ {
+ this->fd = fd;
+ }
+
+ void operator () (const unsigned char * data, unsigned int len);
+};
+
+
+/* A source that reads data from a file descriptor. */
+struct FdSource : Source
+{
+ int fd;
+
+ FdSource(int fd)
+ {
+ this->fd = fd;
+ }
+
+ void operator () (unsigned char * data, unsigned int len);
+};
+
+
+void writePadding(unsigned int len, Sink & sink);
+void writeInt(unsigned int n, Sink & sink);
+void writeString(const string & s, Sink & sink);
+
+void readPadding(unsigned int len, Source & source);
+unsigned int readInt(Source & source);
+string readString(Source & source);
+
+
+}
+
+
+#endif /* !__SERIALISE_H */