Simplifications and clean-ups
[invirt/third/libt4.git] / rpc / marshall.h
index 7b716e2..8592e4b 100644 (file)
@@ -10,8 +10,8 @@
 
 class marshall {
     private:
-        string buf_ = string(rpc_protocol::DEFAULT_RPC_SZ, 0); // Raw bytes buffer
-        size_t index_ = rpc_protocol::RPC_HEADER_SZ; // Read/write head position
+        string buf_ = string(rpc_protocol::DEFAULT_RPC_SZ, 0);
+        size_t index_ = rpc_protocol::RPC_HEADER_SZ;
 
     public:
         template <typename... Args>
@@ -19,10 +19,10 @@ class marshall {
             (void)pass{(*this << args)...};
         }
 
-        void rawbytes(const void *p, size_t n) {
+        void write(const void *p, size_t n) {
             if (index_+n > buf_.size())
                 buf_.resize(index_+n);
-            copy((char *)p, (char *)p+n, &buf_[index_]);
+            std::copy((char *)p, (char *)p+n, &buf_[index_]);
             index_ += n;
         }
 
@@ -35,7 +35,7 @@ class marshall {
         // delay looking up operator<<(marshall &, rpc_sz_t) until we define it
         // (i.e. we define an operator for marshalling uint32_t)
         template <class T, class S=rpc_protocol::rpc_sz_t> inline void
-        pack_header(const T & h) {
+        write_header(const T & h) {
             VERIFY(sizeof(T)+sizeof(S) <= rpc_protocol::RPC_HEADER_SZ);
             size_t saved_sz = index_;
             index_ = 0;
@@ -47,32 +47,33 @@ class marshall {
 class unmarshall {
     private:
         string buf_;
-        size_t index_ = 0;
+        size_t index_ = rpc_protocol::RPC_HEADER_SZ;
         bool ok_ = false;
 
     public:
         template <typename... Args>
         unmarshall(const string & s, bool has_header, Args && ... args)
-            : buf_(s),index_(rpc_protocol::RPC_HEADER_SZ) {
+            : buf_(s) {
             if (!has_header)
                 buf_.insert(0, rpc_protocol::RPC_HEADER_SZ, 0);
             ok_ = (buf_.size() >= rpc_protocol::RPC_HEADER_SZ);
             (void)pass{(*this >> args)...};
         }
 
-        bool ok() const { return ok_; }
-        bool okdone() const { return ok_ && index_ == buf_.size(); }
+        inline bool ok() const { return ok_; }
+        inline bool okdone() const { return ok_ && index_ == buf_.size(); }
 
-        void rawbytes(void * t, size_t n) {
+        void read(void * t, size_t n) {
             if (index_+n > buf_.size())
                 ok_ = false;
-            VERIFY(ok_);
-            copy(&buf_[index_], &buf_[index_+n], (char *)t);
-            index_ += n;
+            if (ok_) {
+                std::copy(&buf_[index_], &buf_[index_+n], (char *)t);
+                index_ += n;
+            }
         }
 
         template <class T> inline void
-        unpack_header(T & h) {
+        read_header(T & h) {
             VERIFY(sizeof(T)+sizeof(rpc_protocol::rpc_sz_t) <= rpc_protocol::RPC_HEADER_SZ);
             // first 4 bytes hold length field
             index_ = sizeof(rpc_protocol::rpc_sz_t);
@@ -88,8 +89,8 @@ class unmarshall {
 //
 
 #define MARSHALL_RAW_NETWORK_ORDER_AS(_c_, _d_) \
-inline marshall & operator<<(marshall & m, _c_ x) { _d_ y = hton((_d_)x); m.rawbytes(&y, sizeof(_d_)); return m; } \
-inline unmarshall & operator>>(unmarshall & u, _c_ & x) { _d_ y; u.rawbytes(&y, sizeof(_d_)); x = (_c_)ntoh(y); return u; }
+inline marshall & operator<<(marshall & m, _c_ x) { _d_ y = hton((_d_)x); m.write(&y, sizeof(_d_)); return m; } \
+inline unmarshall & operator>>(unmarshall & u, _c_ & x) { _d_ y; u.read(&y, sizeof(_d_)); x = (_c_)ntoh(y); return u; }
 
 #define MARSHALL_RAW_NETWORK_ORDER(_c_) MARSHALL_RAW_NETWORK_ORDER_AS(_c_, _c_)
 
@@ -125,10 +126,9 @@ tuple_marshall_imp(marshall & m, tuple<Args...> & t, tuple_indices<Indices...>)
     return m;
 }
 
-template <class... Args> marshall &
+template <class... Args> inline marshall &
 operator<<(marshall & m, tuple<Args...> && t) {
-    using Indices = typename make_tuple_indices<sizeof...(Args)>::type;
-    return tuple_marshall_imp(m, t, Indices());
+    return tuple_marshall_imp(m, t, TUPLE_INDICES(Args));
 }
 
 template <class... Args, size_t... Indices> inline unmarshall &
@@ -137,10 +137,9 @@ tuple_unmarshall_imp(unmarshall & u, tuple<Args & ...> t, tuple_indices<Indices.
     return u;
 }
 
-template <class... Args> unmarshall &
+template <class... Args> inline unmarshall &
 operator>>(unmarshall & u, tuple<Args & ...> && t) {
-    using Indices = typename make_tuple_indices<sizeof...(Args)>::type;
-    return tuple_unmarshall_imp(u, t, Indices());
+    return tuple_unmarshall_imp(u, t, TUPLE_INDICES(Args));
 }
 
 //
@@ -148,13 +147,13 @@ operator>>(unmarshall & u, tuple<Args & ...> && t) {
 //
 
 // Implements struct marshalling via tuple marshalling of members.
-#define MARSHALLABLE_STRUCT(_c_) \
-inline unmarshall & operator>>(unmarshall & u, _c_ & a) { return u >> a._tuple_(); } \
-inline marshall & operator<<(marshall & m, const _c_ a) { return m << a._tuple_(); }
+template <class T> inline typename
+enable_if<is_tuple_convertible<T>::value, unmarshall>::type &
+operator>>(unmarshall & u, T & a) { return u >> a._tuple_(); }
 
-// our first two marshallable structs...
-MARSHALLABLE_STRUCT(rpc_protocol::request_header)
-MARSHALLABLE_STRUCT(rpc_protocol::reply_header)
+template <class T> inline typename
+enable_if<is_tuple_convertible<T>::value, marshall>::type &
+operator<<(marshall & m, const T a) { return m << a._tuple_(); }
 
 //
 // Marshalling for STL containers
@@ -164,7 +163,7 @@ MARSHALLABLE_STRUCT(rpc_protocol::reply_header)
 template <class A> inline typename
 enable_if<is_const_iterable<A>::value, marshall>::type &
 operator<<(marshall & m, const A & x) {
-    m << (unsigned int)x.size();
+    m << (uint32_t)x.size();
     for (const auto & a : x)
         m << a;
     return m;
@@ -174,7 +173,7 @@ operator<<(marshall & m, const A & x) {
 template <class A> inline typename
 enable_if<supports_emplace_back<A>::value, unmarshall>::type &
 operator>>(unmarshall & u, A & x) {
-    unsigned n = u._grab<unsigned>();
+    uint32_t n = u._grab<uint32_t>();
     x.clear();
     while (n--)
         x.emplace_back(u._grab<typename A::value_type>());
@@ -195,7 +194,7 @@ operator>>(unmarshall & u, pair<A,B> & d) {
 // std::map<A, B>
 template <class A, class B> inline unmarshall &
 operator>>(unmarshall & u, map<A,B> & x) {
-    unsigned n = u._grab<unsigned>();
+    uint32_t n = u._grab<uint32_t>();
     x.clear();
     while (n--)
         x.emplace(u._grab<pair<A,B>>());
@@ -205,7 +204,7 @@ operator>>(unmarshall & u, map<A,B> & x) {
 // std::string
 inline marshall & operator<<(marshall & m, const string & s) {
     m << (uint32_t)s.size();
-    m.rawbytes(s.data(), s.size());
+    m.write(s.data(), s.size());
     return m;
 }
 
@@ -213,7 +212,7 @@ inline unmarshall & operator>>(unmarshall & u, string & s) {
     uint32_t sz = u._grab<uint32_t>();
     if (u.ok()) {
         s.resize(sz);
-        u.rawbytes(&s[0], sz);
+        u.read(&s[0], sz);
     }
     return u;
 }