More logging clean-ups. Static type-checking for RPC calls and
[invirt/third/libt4.git] / rpc / marshall.h
index 0fcbfaf..6412612 100644 (file)
@@ -13,8 +13,8 @@ class unmarshall;
 
 class marshall {
     private:
-        string buf_ = string(DEFAULT_RPC_SZ, 0); // Raw bytes buffer
-        size_t index_ = RPC_HEADER_SZ; // Read/write head position
+        string buf_ = string(rpc_protocol::DEFAULT_RPC_SZ, 0); // Raw bytes buffer
+        size_t index_ = rpc_protocol::RPC_HEADER_SZ; // Read/write head position
 
     public:
         template <typename... Args>
@@ -32,14 +32,14 @@ class marshall {
         // with header
         inline operator string() const { return buf_.substr(0,index_); }
         // without header
-        inline string content() { return buf_.substr(RPC_HEADER_SZ,index_-RPC_HEADER_SZ); }
+        inline string content() const { return buf_.substr(rpc_protocol::RPC_HEADER_SZ,index_-rpc_protocol::RPC_HEADER_SZ); }
 
         // letting S be a defaulted template parameter forces the compiler to
         // 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_sz_t> inline void
+        template <class T, class S=rpc_protocol::rpc_sz_t> inline void
         pack_header(const T & h) {
-            VERIFY(sizeof(T)+sizeof(S) <= RPC_HEADER_SZ);
+            VERIFY(sizeof(T)+sizeof(S) <= rpc_protocol::RPC_HEADER_SZ);
             size_t saved_sz = index_;
             index_ = 0;
             *this << (S)(saved_sz - sizeof(S)) << (T)h;
@@ -55,10 +55,10 @@ class unmarshall {
 
     public:
         unmarshall(const string &s, bool has_header)
-            : buf_(s),index_(RPC_HEADER_SZ) {
+            : buf_(s),index_(rpc_protocol::RPC_HEADER_SZ) {
             if (!has_header)
-                buf_.insert(0, RPC_HEADER_SZ, 0);
-            ok_ = (buf_.size() >= RPC_HEADER_SZ);
+                buf_.insert(0, rpc_protocol::RPC_HEADER_SZ, 0);
+            ok_ = (buf_.size() >= rpc_protocol::RPC_HEADER_SZ);
         }
 
         bool ok() const { return ok_; }
@@ -72,16 +72,16 @@ class unmarshall {
             index_ += n;
         }
 
-        template <class T> void
+        template <class T> inline void
         unpack_header(T & h) {
-            VERIFY(sizeof(T)+sizeof(rpc_sz_t) <= RPC_HEADER_SZ);
+            VERIFY(sizeof(T)+sizeof(rpc_protocol::rpc_sz_t) <= rpc_protocol::RPC_HEADER_SZ);
             // first 4 bytes hold length field
-            index_ = sizeof(rpc_sz_t);
+            index_ = sizeof(rpc_protocol::rpc_sz_t);
             *this >> h;
-            index_ = RPC_HEADER_SZ;
+            index_ = rpc_protocol::RPC_HEADER_SZ;
         }
 
-        template <class T> inline T grab() { T t; *this >> t; return t; }
+        template <class T> inline T _grab() { T t; *this >> t; return t; }
 };
 
 //
@@ -154,8 +154,8 @@ inline unmarshall & operator>>(unmarshall &u, _c_ &a) { return u >> a._tuple_();
 inline marshall & operator<<(marshall &m, const _c_ a) { return m << a._tuple_(); }
 
 // our first two marshallable structs...
-MARSHALLABLE(request_header)
-MARSHALLABLE(reply_header)
+MARSHALLABLE(rpc_protocol::request_header)
+MARSHALLABLE(rpc_protocol::reply_header)
 
 //
 // Marshalling for STL containers
@@ -175,10 +175,10 @@ 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>();
+    unsigned n = u._grab<unsigned>();
     x.clear();
     while (n--)
-        x.emplace_back(u.grab<typename A::value_type>());
+        x.emplace_back(u._grab<typename A::value_type>());
     return u;
 }
 
@@ -196,10 +196,10 @@ 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>();
+    unsigned n = u._grab<unsigned>();
     x.clear();
     while (n--)
-        x.emplace(u.grab<pair<A,B>>());
+        x.emplace(u._grab<pair<A,B>>());
     return u;
 }
 
@@ -211,7 +211,7 @@ inline marshall & operator<<(marshall &m, const string &s) {
 }
 
 inline unmarshall & operator>>(unmarshall &u, string &s) {
-    uint32_t sz = u.grab<uint32_t>();
+    uint32_t sz = u._grab<uint32_t>();
     if (u.ok()) {
         s.resize(sz);
         u.rawbytes(&s[0], sz);
@@ -230,7 +230,20 @@ operator<<(marshall &m, E e) {
 
 template <class E> typename enable_if<is_enum<E>::value, unmarshall>::type &
 operator>>(unmarshall &u, E &e) {
-    e = to_enum<E>(u.grab<enum_type_t<E>>());
+    e = to_enum<E>(u._grab<enum_type_t<E>>());
+    return u;
+}
+
+//
+// Recursive marshalling
+//
+
+inline marshall & operator<<(marshall &m, marshall &n) {
+    return m << n.content();
+}
+
+inline unmarshall & operator>>(unmarshall &u, unmarshall &v) {
+    v = unmarshall(u._grab<string>(), false);
     return u;
 }