aboutsummaryrefslogtreecommitdiff
path: root/src/libutil/serialise.hh
diff options
context:
space:
mode:
authorEelco Dolstra <edolstra@gmail.com>2017-03-01 13:52:54 +0100
committerEelco Dolstra <edolstra@gmail.com>2017-03-01 13:52:54 +0100
commitc4a40949d945b4a3be85ad68b8cfb449843f34a6 (patch)
tree535f9679b01e677114e5ac947d7d4a7c88917cab /src/libutil/serialise.hh
parent07808052461e9534dc42f7f98e83a7b58565fd13 (diff)
Handle importing NARs containing files greater than 4 GiB
Also templatize readInt() to work for various integer types.
Diffstat (limited to 'src/libutil/serialise.hh')
-rw-r--r--src/libutil/serialise.hh54
1 files changed, 50 insertions, 4 deletions
diff --git a/src/libutil/serialise.hh b/src/libutil/serialise.hh
index 5646d08c1..3072f422e 100644
--- a/src/libutil/serialise.hh
+++ b/src/libutil/serialise.hh
@@ -177,18 +177,64 @@ Sink & operator << (Sink & sink, const Strings & s);
Sink & operator << (Sink & sink, const StringSet & s);
+MakeError(SerialisationError, Error)
+
+
+template<typename T>
+T readNum(Source & source)
+{
+ unsigned char buf[8];
+ source(buf, sizeof(buf));
+
+ uint64_t n =
+ ((unsigned long long) buf[0]) |
+ ((unsigned long long) buf[1] << 8) |
+ ((unsigned long long) buf[2] << 16) |
+ ((unsigned long long) buf[3] << 24) |
+ ((unsigned long long) buf[4] << 32) |
+ ((unsigned long long) buf[5] << 40) |
+ ((unsigned long long) buf[6] << 48) |
+ ((unsigned long long) buf[7] << 56);
+
+ if (n > std::numeric_limits<T>::max())
+ throw SerialisationError("serialised integer %d is too large for type ā€˜%sā€™", n, typeid(T).name());
+
+ return n;
+}
+
+
+inline unsigned int readInt(Source & source)
+{
+ return readNum<unsigned int>(source);
+}
+
+
+inline uint64_t readLongLong(Source & source)
+{
+ return readNum<uint64_t>(source);
+}
+
+
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);
Source & operator >> (Source & in, string & s);
-Source & operator >> (Source & in, unsigned int & n);
+template<typename T>
+Source & operator >> (Source & in, T & n)
+{
+ n = readNum<T>(in);
+ return in;
+}
-MakeError(SerialisationError, Error)
+template<typename T>
+Source & operator >> (Source & in, bool & b)
+{
+ b = readNum<uint64_t>(in);
+ return in;
+}
}