Split out marshall code into a new file
[invirt/third/libt4.git] / rpc / marshall.cc
1 #include "types.h"
2 #include "marshall.h"
3
4 marshall &
5 operator<<(marshall &m, uint8_t x) {
6     m.rawbyte(x);
7     return m;
8 }
9
10 marshall &
11 operator<<(marshall &m, uint16_t x) {
12     x = hton(x);
13     m.rawbytes((char *)&x, 2);
14     return m;
15 }
16
17 marshall &
18 operator<<(marshall &m, uint32_t x) {
19     x = hton(x);
20     m.rawbytes((char *)&x, 4);
21     return m;
22 }
23
24 marshall & operator<<(marshall &m, int32_t x) { return m << (uint32_t) x; }
25 marshall & operator<<(marshall &m, int8_t x) { return m << (uint8_t)x; }
26 marshall & operator<<(marshall &m, bool x) { return m << (uint8_t)x; }
27 marshall & operator<<(marshall &m, int16_t x) { return m << (uint16_t)x; }
28 marshall & operator<<(marshall &m, uint64_t x) { return m << (uint32_t)(x>>32) << (uint32_t)x; }
29
30 marshall &
31 operator<<(marshall &m, const string &s) {
32     m << (unsigned int) s.size();
33     m.rawbytes(s.data(), s.size());
34     return m;
35 }
36
37 void marshall::pack_req_header(const request_header &h) {
38     size_t saved_sz = index_;
39     //leave the first 4-byte empty for channel to fill size of pdu
40     index_ = sizeof(rpc_sz_t);
41     *this << h.xid << h.proc << h.clt_nonce << h.srv_nonce << h.xid_rep;
42     index_ = saved_sz;
43 }
44
45 void marshall::pack_reply_header(const reply_header &h) {
46     size_t saved_sz = index_;
47     //leave the first 4-byte empty for channel to fill size of pdu
48     index_ = sizeof(rpc_sz_t);
49     *this << h.xid << h.ret;
50     index_ = saved_sz;
51 }
52
53 // take the contents from another unmarshall object
54 void
55 unmarshall::take_in(unmarshall &another)
56 {
57     if(buf_)
58         free(buf_);
59     another.take_buf(&buf_, &sz_);
60     index_ = RPC_HEADER_SZ;
61     ok_ = sz_ >= RPC_HEADER_SZ?true:false;
62 }
63
64 inline bool
65 unmarshall::ensure(size_t n) {
66     if (index_+n > sz_)
67         ok_ = false;
68     return ok_;
69 }
70
71 inline uint8_t
72 unmarshall::rawbyte()
73 {
74     if (!ensure(1))
75         return 0;
76     return (uint8_t)buf_[index_++];
77 }
78
79 void
80 unmarshall::rawbytes(string &ss, size_t n)
81 {
82     VERIFY(ensure(n));
83     ss.assign(buf_+index_, n);
84     index_ += n;
85 }
86
87 template <class T>
88 void
89 unmarshall::rawbytes(T &t)
90 {
91     const size_t n = sizeof(T);
92     VERIFY(ensure(n));
93     memcpy(&t, buf_+index_, n);
94     t = ntoh(t);
95     index_ += n;
96 }
97
98 unmarshall & operator>>(unmarshall &u, bool &x) { x = (bool)u.rawbyte(); return u; }
99 unmarshall & operator>>(unmarshall &u, uint8_t &x) { x = u.rawbyte(); return u; }
100 unmarshall & operator>>(unmarshall &u, int8_t &x) { x = (int8_t)u.rawbyte(); return u; }
101 unmarshall & operator>>(unmarshall &u, uint16_t &x) { u.rawbytes<uint16_t>(x); return u; }
102 unmarshall & operator>>(unmarshall &u, int16_t &x) { u.rawbytes<int16_t>(x); return u; }
103 unmarshall & operator>>(unmarshall &u, uint32_t &x) { u.rawbytes<uint32_t>(x); return u; }
104 unmarshall & operator>>(unmarshall &u, int32_t &x) { u.rawbytes<int32_t>(x); return u; }
105 unmarshall & operator>>(unmarshall &u, size_t &x) { uint32_t xx; u.rawbytes<uint32_t>(xx); x = xx; return u; }
106 unmarshall & operator>>(unmarshall &u, uint64_t &x) { u.rawbytes<uint64_t>(x); return u; }
107 unmarshall & operator>>(unmarshall &u, int64_t &x) { u.rawbytes<int64_t>(x); return u; }
108
109 unmarshall & operator>>(unmarshall &u, string &s) {
110     unsigned sz = u.grab<unsigned>();
111     if(u.ok())
112         u.rawbytes(s, sz);
113     return u;
114 }