Cleanups
[invirt/third/libt4.git] / rpc / marshall.h
index 7a85d6b..676a682 100644 (file)
 #include "lang/verify.h"
 
 struct request_header {
-    request_header(int x=0, int p=0, int c=0, int s=0, int xi=0) :
+    request_header(int x=0, int p=0, unsigned c=0, unsigned s=0, int xi=0) :
         xid(x), proc(p), clt_nonce(c), srv_nonce(s), xid_rep(xi) {}
     int xid;
     int proc;
     unsigned int clt_nonce;
     unsigned int srv_nonce;
     int xid_rep;
-    request_header hton() const {
-        return {
-            htonl(xid), htonl(proc), htonl(clt_nonce), htonl(srv_nonce), htonl(xid_rep)
-        };
-    }
 };
 
 struct reply_header {
     reply_header(int x=0, int r=0): xid(x), ret(r) {}
     int xid;
     int ret;
-    reply_header hton() const {
-        return {
-            htonl(xid), htonl(ret)
-        };
-    }
 };
 
+template<class T> inline T hton(T t);
+
+constexpr union { uint32_t i; uint8_t is_little_endian; } endianness{1};
+
+template<> inline uint8_t hton(uint8_t t) { return t; }
+template<> inline int8_t hton(int8_t t) { return t; }
+template<> inline uint16_t hton(uint16_t t) { return htons(t); }
+template<> inline int16_t hton(int16_t t) { return (int16_t)htons((uint16_t)t); }
+template<> inline uint32_t hton(uint32_t t) { return htonl(t); }
+template<> inline int32_t hton(int32_t t) { return (int32_t)htonl((uint32_t)t); }
+template<> inline uint64_t hton(uint64_t t) {
+    if (!endianness.is_little_endian)
+        return t;
+    return (uint64_t)htonl((uint32_t)(t >> 32)) | ((uint64_t)htonl((uint32_t)t) << 32);
+}
+template<> inline int64_t hton(int64_t t) { return (int64_t)hton((uint64_t)t); }
+template<> inline request_header hton(request_header h) { return {hton(h.xid), hton(h.proc), hton(h.clt_nonce), hton(h.srv_nonce), hton(h.xid_rep)}; }
+template<> inline reply_header hton(reply_header h) { return {hton(h.xid), hton(h.ret)}; }
+
+template <class T> inline T ntoh(T t) { return hton(t); }
+
 typedef int rpc_sz_t;
 
 //size of initial buffer allocation
@@ -76,16 +87,16 @@ class marshall {
                 free(buf_);
         }
 
-        int size() { return index_;}
+        size_t size() { return index_;}
         char *cstr() { return buf_;}
         const char *cstr() const { return buf_;}
 
-        void rawbyte(unsigned char x) {
+        void rawbyte(uint8_t x) {
             reserve(1);
-            buf_[index_++] = x;
+            buf_[index_++] = (int8_t)x;
         }
 
-        void rawbytes(const char *p, int n) {
+        void rawbytes(const char *p, size_t n) {
             reserve(n);
             memcpy(buf_+index_, p, n);
             index_ += n;
@@ -104,7 +115,7 @@ class marshall {
         void pack_req_header(const request_header &h);
         void pack_reply_header(const reply_header &h);
 
-        void take_buf(char **b, int *s) {
+        void take_buf(char **b, size_t *s) {
             *b = buf_;
             *s = index_;
             buf_ = NULL;
@@ -114,13 +125,13 @@ class marshall {
 };
 
 marshall& operator<<(marshall &, bool);
-marshall& operator<<(marshall &, unsigned int);
-marshall& operator<<(marshall &, int);
-marshall& operator<<(marshall &, unsigned char);
-marshall& operator<<(marshall &, char);
-marshall& operator<<(marshall &, unsigned short);
-marshall& operator<<(marshall &, short);
-marshall& operator<<(marshall &, unsigned long long);
+marshall& operator<<(marshall &, uint32_t);
+marshall& operator<<(marshall &, int32_t);
+marshall& operator<<(marshall &, uint8_t);
+marshall& operator<<(marshall &, int8_t);
+marshall& operator<<(marshall &, uint16_t);
+marshall& operator<<(marshall &, int16_t);
+marshall& operator<<(marshall &, uint64_t);
 marshall& operator<<(marshall &, const std::string &);
 
 template <class A> marshall &
@@ -138,17 +149,31 @@ operator<<(marshall &m, const std::pair<A,B> &d) {
     return m;
 }
 
+class unmarshall;
+
+unmarshall& operator>>(unmarshall &, bool &);
+unmarshall& operator>>(unmarshall &, uint8_t &);
+unmarshall& operator>>(unmarshall &, int8_t &);
+unmarshall& operator>>(unmarshall &, uint16_t &);
+unmarshall& operator>>(unmarshall &, int16_t &);
+unmarshall& operator>>(unmarshall &, uint32_t &);
+unmarshall& operator>>(unmarshall &, int32_t &);
+unmarshall& operator>>(unmarshall &, size_t &);
+unmarshall& operator>>(unmarshall &, uint64_t &);
+unmarshall& operator>>(unmarshall &, int64_t &);
+unmarshall& operator>>(unmarshall &, std::string &);
+
 class unmarshall {
     private:
         char *buf_;
-        int sz_;
-        int index_;
+        size_t sz_;
+        size_t index_;
         bool ok_;
 
         inline bool ensure(size_t n);
     public:
         unmarshall(): buf_(NULL),sz_(0),index_(0),ok_(false) {}
-        unmarshall(char *b, int sz): buf_(b),sz_(sz),index_(),ok_(true) {}
+        unmarshall(char *b, size_t sz): buf_(b),sz_(sz),index_(),ok_(true) {}
         unmarshall(const std::string &s) : buf_(NULL),sz_(0),index_(0),ok_(false)
         {
             //take the content which does not exclude a RPC header from a string
@@ -175,13 +200,13 @@ class unmarshall {
         char *cstr() { return buf_;}
         bool okdone() const { return ok_ && index_ == sz_; }
 
-        unsigned int rawbyte();
+        uint8_t rawbyte();
         void rawbytes(std::string &s, size_t n);
+        template <class T> void rawbytes(T &t);
 
-        int ind() { return index_;}
-        int size() { return sz_;}
-        void unpack(int *); //non-const ref
-        void take_buf(char **b, int *sz) {
+        size_t ind() { return index_;}
+        size_t size() { return sz_;}
+        void take_buf(char **b, size_t *sz) {
             *b = buf_;
             *sz = sz_;
             sz_ = index_ = 0;
@@ -191,19 +216,14 @@ class unmarshall {
         void unpack_req_header(request_header *h) {
             //the first 4-byte is for channel to fill size of pdu
             index_ = sizeof(rpc_sz_t);
-            unpack(&h->xid);
-            unpack(&h->proc);
-            unpack((int *)&h->clt_nonce);
-            unpack((int *)&h->srv_nonce);
-            unpack(&h->xid_rep);
+            *this >> h->xid >> h->proc >> h->clt_nonce >> h->srv_nonce >> h->xid_rep;
             index_ = RPC_HEADER_SZ;
         }
 
         void unpack_reply_header(reply_header *h) {
             //the first 4-byte is for channel to fill size of pdu
             index_ = sizeof(rpc_sz_t);
-            unpack(&h->xid);
-            unpack(&h->ret);
+            *this >> h->xid >> h->ret;
             index_ = RPC_HEADER_SZ;
         }