Lots of clean-ups and simplifications
[invirt/third/libt4.git] / rpc / marshall.h
1 #ifndef marshall_h
2 #define marshall_h
3
4 #include <iostream>
5 #include <sstream>
6 #include <string>
7 #include <vector>
8 #include <map>
9 #include <stdlib.h>
10 #include <string.h>
11 #include <cstddef>
12 #include <inttypes.h>
13 #include "lang/verify.h"
14
15 struct req_header {
16         req_header(int x=0, int p=0, int c = 0, int s = 0, int xi = 0):
17                 xid(x), proc(p), clt_nonce(c), srv_nonce(s), xid_rep(xi) {}
18         int xid;
19         int proc;
20         unsigned int clt_nonce;
21         unsigned int srv_nonce;
22         int xid_rep;
23 };
24
25 struct reply_header {
26         reply_header(int x=0, int r=0): xid(x), ret(r) {}
27         int xid;
28         int ret;
29 };
30
31 typedef int rpc_sz_t;
32
33 //size of initial buffer allocation 
34 #define DEFAULT_RPC_SZ 1024
35 #define RPC_HEADER_SZ (std::max(sizeof(req_header), sizeof(reply_header)) + sizeof(rpc_sz_t))
36
37 class marshall {
38         private:
39                 char *_buf;     // Base of the raw bytes buffer (dynamically readjusted)
40                 int _capa;      // Capacity of the buffer
41                 int _ind;       // Read/write head position
42
43         public:
44                 marshall() {
45                         _buf = (char *) malloc(sizeof(char)*DEFAULT_RPC_SZ);
46                         VERIFY(_buf);
47                         _capa = DEFAULT_RPC_SZ;
48                         _ind = RPC_HEADER_SZ;
49                 }
50
51                 ~marshall() { 
52                         if (_buf) 
53                                 free(_buf); 
54                 }
55
56                 int size() { return _ind;}
57                 char *cstr() { return _buf;}
58
59                 void rawbyte(unsigned char);
60                 void rawbytes(const char *, int);
61
62                 // Return the current content (excluding header) as a string
63                 std::string get_content() { 
64                         return std::string(_buf+RPC_HEADER_SZ,_ind-RPC_HEADER_SZ);
65                 }
66
67                 // Return the current content (excluding header) as a string
68                 std::string str() {
69                         return get_content();
70                 }
71
72                 void pack(int i);
73
74                 void pack_req_header(const req_header &h) {
75                         int saved_sz = _ind;
76                         //leave the first 4-byte empty for channel to fill size of pdu
77                         _ind = sizeof(rpc_sz_t); 
78                         pack(h.xid);
79                         pack(h.proc);
80                         pack((int)h.clt_nonce);
81                         pack((int)h.srv_nonce);
82                         pack(h.xid_rep);
83                         _ind = saved_sz;
84                 }
85
86                 void pack_reply_header(const reply_header &h) {
87                         int saved_sz = _ind;
88                         //leave the first 4-byte empty for channel to fill size of pdu
89                         _ind = sizeof(rpc_sz_t); 
90                         pack(h.xid);
91                         pack(h.ret);
92                         _ind = saved_sz;
93                 }
94
95                 void take_buf(char **b, int *s) {
96                         *b = _buf;
97                         *s = _ind;
98                         _buf = NULL;
99                         _ind = 0;
100                         return;
101                 }
102 };
103
104 marshall& operator<<(marshall &, bool);
105 marshall& operator<<(marshall &, unsigned int);
106 marshall& operator<<(marshall &, int);
107 marshall& operator<<(marshall &, unsigned char);
108 marshall& operator<<(marshall &, char);
109 marshall& operator<<(marshall &, unsigned short);
110 marshall& operator<<(marshall &, short);
111 marshall& operator<<(marshall &, unsigned long long);
112 marshall& operator<<(marshall &, const std::string &);
113
114 template <class C> marshall &
115 operator<<(marshall &m, std::vector<C> v)
116 {
117         m << (unsigned int) v.size();
118         for(unsigned i = 0; i < v.size(); i++)
119                 m << v[i];
120         return m;
121 }
122
123 template <class A, class B> marshall &
124 operator<<(marshall &m, const std::map<A,B> &d) {
125         typename std::map<A,B>::const_iterator i;
126
127         m << (unsigned int) d.size();
128
129         for (i = d.begin(); i != d.end(); i++) {
130                 m << i->first << i->second;
131         }
132         return m;
133 }
134
135 template <class A> marshall &
136 operator<<(marshall &m, const std::list<A> &d) {
137     m << std::vector<A>(d.begin(), d.end());
138     return m;
139 }
140
141 template <class A, class B> marshall &
142 operator<<(marshall &m, const std::pair<A,B> &d) {
143     m << d.first;
144     m << d.second;
145     return m;
146 }
147
148 class unmarshall {
149         private:
150                 char *_buf;
151                 int _sz;
152                 int _ind;
153                 bool _ok;
154         public:
155                 unmarshall(): _buf(NULL),_sz(0),_ind(0),_ok(false) {}
156                 unmarshall(char *b, int sz): _buf(b),_sz(sz),_ind(),_ok(true) {}
157                 unmarshall(const std::string &s) : _buf(NULL),_sz(0),_ind(0),_ok(false) 
158                 {
159                         //take the content which does not exclude a RPC header from a string
160                         take_content(s);
161                 }
162                 ~unmarshall() {
163                         if (_buf) free(_buf);
164                 }
165
166                 //take contents from another unmarshall object
167                 void take_in(unmarshall &another);
168
169                 //take the content which does not exclude a RPC header from a string
170                 void take_content(const std::string &s) {
171                         _sz = s.size()+RPC_HEADER_SZ;
172                         _buf = (char *)realloc(_buf,_sz);
173                         VERIFY(_buf);
174                         _ind = RPC_HEADER_SZ;
175                         memcpy(_buf+_ind, s.data(), s.size());
176                         _ok = true;
177                 }
178
179                 bool ok() { return _ok; }
180                 char *cstr() { return _buf;}
181                 bool okdone();
182                 unsigned int rawbyte();
183                 void rawbytes(std::string &s, unsigned int n);
184
185                 int ind() { return _ind;}
186                 int size() { return _sz;}
187                 void unpack(int *); //non-const ref
188                 void take_buf(char **b, int *sz) {
189                         *b = _buf;
190                         *sz = _sz;
191                         _sz = _ind = 0;
192                         _buf = NULL;
193                 }
194
195                 void unpack_req_header(req_header *h) {
196                         //the first 4-byte is for channel to fill size of pdu
197                         _ind = sizeof(rpc_sz_t); 
198                         unpack(&h->xid);
199                         unpack(&h->proc);
200                         unpack((int *)&h->clt_nonce);
201                         unpack((int *)&h->srv_nonce);
202                         unpack(&h->xid_rep);
203                         _ind = RPC_HEADER_SZ;
204                 }
205
206                 void unpack_reply_header(reply_header *h) {
207                         //the first 4-byte is for channel to fill size of pdu
208                         _ind = sizeof(rpc_sz_t); 
209                         unpack(&h->xid);
210                         unpack(&h->ret);
211                         _ind = RPC_HEADER_SZ;
212                 }
213 };
214
215 unmarshall& operator>>(unmarshall &, bool &);
216 unmarshall& operator>>(unmarshall &, unsigned char &);
217 unmarshall& operator>>(unmarshall &, char &);
218 unmarshall& operator>>(unmarshall &, unsigned short &);
219 unmarshall& operator>>(unmarshall &, short &);
220 unmarshall& operator>>(unmarshall &, unsigned int &);
221 unmarshall& operator>>(unmarshall &, int &);
222 unmarshall& operator>>(unmarshall &, unsigned long long &);
223 unmarshall& operator>>(unmarshall &, std::string &);
224
225 template <class C> unmarshall &
226 operator>>(unmarshall &u, std::vector<C> &v)
227 {
228         unsigned n;
229         u >> n;
230     v.clear();
231     while (n--) {
232         C c;
233         u >> c;
234         v.push_back(c);
235     }
236         return u;
237 }
238
239 template <class A, class B> unmarshall &
240 operator>>(unmarshall &u, std::map<A,B> &d) {
241         unsigned n;
242         u >> n;
243         d.clear();
244     while (n--) {
245         A a;
246         B b;
247         u >> a >> b;
248         d[a] = b;
249     }
250         return u;
251 }
252
253 template <class C> unmarshall &
254 operator>>(unmarshall &u, std::list<C> &l) {
255     unsigned n;
256     u >> n;
257     l.clear();
258     while (n--) {
259         C c;
260         u >> c;
261         l.push_back(c);
262     }
263     return u;
264 }
265
266 template <class A, class B> unmarshall &
267 operator>>(unmarshall &u, std::pair<A,B> &d) {
268     return u >> d.first >> d.second;
269 }
270
271 #endif