Revert "daemon: Fix possible use-after-free."
[jackhill/guix/guix.git] / nix / libutil / serialise.hh
CommitLineData
36457566
LC
1#pragma once
2
3#include "types.hh"
4
5
6namespace nix {
7
8
9/* Abstract destination of binary data. */
10struct Sink
11{
12 virtual ~Sink() { }
13 virtual void operator () (const unsigned char * data, size_t len) = 0;
14};
15
16
17/* A buffered abstract sink. */
18struct BufferedSink : Sink
19{
20 size_t bufSize, bufPos;
21 unsigned char * buffer;
22
23 BufferedSink(size_t bufSize = 32 * 1024)
24 : bufSize(bufSize), bufPos(0), buffer(0) { }
25 ~BufferedSink();
26
27 void operator () (const unsigned char * data, size_t len);
28
29 void flush();
30
31 virtual void write(const unsigned char * data, size_t len) = 0;
32};
33
34
35/* Abstract source of binary data. */
36struct Source
37{
38 virtual ~Source() { }
39
40 /* Store exactly ‘len’ bytes in the buffer pointed to by ‘data’.
41 It blocks until all the requested data is available, or throws
42 an error if it is not going to be available. */
43 void operator () (unsigned char * data, size_t len);
44
45 /* Store up to ‘len’ in the buffer pointed to by ‘data’, and
46 return the number of bytes stored. If blocks until at least
47 one byte is available. */
48 virtual size_t read(unsigned char * data, size_t len) = 0;
49};
50
51
52/* A buffered abstract source. */
53struct BufferedSource : Source
54{
55 size_t bufSize, bufPosIn, bufPosOut;
56 unsigned char * buffer;
57
58 BufferedSource(size_t bufSize = 32 * 1024)
59 : bufSize(bufSize), bufPosIn(0), bufPosOut(0), buffer(0) { }
60 ~BufferedSource();
61
62 size_t read(unsigned char * data, size_t len);
63
64 /* Underlying read call, to be overridden. */
65 virtual size_t readUnbuffered(unsigned char * data, size_t len) = 0;
66
67 bool hasData();
68};
69
70
71/* A sink that writes data to a file descriptor. */
72struct FdSink : BufferedSink
73{
74 int fd;
75
76 FdSink() : fd(-1) { }
77 FdSink(int fd) : fd(fd) { }
78 ~FdSink();
79
80 void write(const unsigned char * data, size_t len);
81};
82
83
84/* A source that reads data from a file descriptor. */
85struct FdSource : BufferedSource
86{
87 int fd;
88 FdSource() : fd(-1) { }
89 FdSource(int fd) : fd(fd) { }
90 size_t readUnbuffered(unsigned char * data, size_t len);
91};
92
93
94/* A sink that writes data to a string. */
95struct StringSink : Sink
96{
97 string s;
98 void operator () (const unsigned char * data, size_t len)
99 {
100 s.append((const char *) data, len);
101 }
102};
103
104
105/* A source that reads data from a string. */
106struct StringSource : Source
107{
108 const string & s;
109 size_t pos;
110 StringSource(const string & _s) : s(_s), pos(0) { }
111 size_t read(unsigned char * data, size_t len);
112};
113
114
115void writePadding(size_t len, Sink & sink);
116void writeInt(unsigned int n, Sink & sink);
117void writeLongLong(unsigned long long n, Sink & sink);
118void writeString(const unsigned char * buf, size_t len, Sink & sink);
119void writeString(const string & s, Sink & sink);
120template<class T> void writeStrings(const T & ss, Sink & sink);
121
122void readPadding(size_t len, Source & source);
123unsigned int readInt(Source & source);
124unsigned long long readLongLong(Source & source);
125size_t readString(unsigned char * buf, size_t max, Source & source);
126string readString(Source & source);
127template<class T> T readStrings(Source & source);
128
129
130MakeError(SerialisationError, Error)
131
132
133}