#include <cstddef>
#include <inttypes.h>
#include "lang/verify.h"
-#include "lang/algorithm.h"
struct req_header {
req_header(int x=0, int p=0, int c = 0, int s = 0, int xi = 0):
int ret;
};
-typedef uint64_t rpc_checksum_t;
typedef int rpc_sz_t;
-enum {
- //size of initial buffer allocation
- DEFAULT_RPC_SZ = 1024,
-#if RPC_CHECKSUMMING
- //size of rpc_header includes a 4-byte int to be filled by tcpchan and uint64_t checksum
- RPC_HEADER_SZ = static_max<sizeof(req_header), sizeof(reply_header)>::value + sizeof(rpc_sz_t) + sizeof(rpc_checksum_t)
-#else
- RPC_HEADER_SZ = static_max<sizeof(req_header), sizeof(reply_header)>::value + sizeof(rpc_sz_t)
-#endif
+//size of initial buffer allocation
+#define DEFAULT_RPC_SZ 1024
+#define RPC_HEADER_SZ (std::max(sizeof(req_header), sizeof(reply_header)) + sizeof(rpc_sz_t))
+
+struct pass {
+ template<typename... Args> inline pass(Args&&...) {}
};
class marshall {
_ind = RPC_HEADER_SZ;
}
+ template <typename... Args> marshall(const Args&... args) : marshall() {
+ (void)pass{(*this << args)...};
+ }
+
~marshall() {
if (_buf)
free(_buf);
int saved_sz = _ind;
//leave the first 4-byte empty for channel to fill size of pdu
_ind = sizeof(rpc_sz_t);
-#if RPC_CHECKSUMMING
- _ind += sizeof(rpc_checksum_t);
-#endif
pack(h.xid);
pack(h.proc);
pack((int)h.clt_nonce);
int saved_sz = _ind;
//leave the first 4-byte empty for channel to fill size of pdu
_ind = sizeof(rpc_sz_t);
-#if RPC_CHECKSUMMING
- _ind += sizeof(rpc_checksum_t);
-#endif
pack(h.xid);
pack(h.ret);
_ind = saved_sz;
return;
}
};
+
marshall& operator<<(marshall &, bool);
marshall& operator<<(marshall &, unsigned int);
marshall& operator<<(marshall &, int);
marshall& operator<<(marshall &, unsigned long long);
marshall& operator<<(marshall &, const std::string &);
+template <class C> marshall &
+operator<<(marshall &m, std::vector<C> v)
+{
+ m << (unsigned int) v.size();
+ for(unsigned i = 0; i < v.size(); i++)
+ m << v[i];
+ return m;
+}
+
+template <class A, class B> marshall &
+operator<<(marshall &m, const std::map<A,B> &d) {
+ typename std::map<A,B>::const_iterator i;
+
+ m << (unsigned int) d.size();
+
+ for (i = d.begin(); i != d.end(); i++) {
+ m << i->first << i->second;
+ }
+ return m;
+}
+
+template <class A> marshall &
+operator<<(marshall &m, const std::list<A> &d) {
+ m << std::vector<A>(d.begin(), d.end());
+ return m;
+}
+
+template <class A, class B> marshall &
+operator<<(marshall &m, const std::pair<A,B> &d) {
+ m << d.first;
+ m << d.second;
+ return m;
+}
+
class unmarshall {
private:
char *_buf;
void unpack_req_header(req_header *h) {
//the first 4-byte is for channel to fill size of pdu
_ind = sizeof(rpc_sz_t);
-#if RPC_CHECKSUMMING
- _ind += sizeof(rpc_checksum_t);
-#endif
unpack(&h->xid);
unpack(&h->proc);
unpack((int *)&h->clt_nonce);
void unpack_reply_header(reply_header *h) {
//the first 4-byte is for channel to fill size of pdu
_ind = sizeof(rpc_sz_t);
-#if RPC_CHECKSUMMING
- _ind += sizeof(rpc_checksum_t);
-#endif
unpack(&h->xid);
unpack(&h->ret);
_ind = RPC_HEADER_SZ;
}
+
+ template <class OutputIterator>
+ void iterate(OutputIterator i, int n) {
+ while (n--) {
+ typename OutputIterator::value_type t;
+ *this >> t;
+ *i++ = t;
+ }
+ }
};
unmarshall& operator>>(unmarshall &, bool &);
unmarshall& operator>>(unmarshall &, unsigned long long &);
unmarshall& operator>>(unmarshall &, std::string &);
-template <class C> marshall &
-operator<<(marshall &m, std::vector<C> v)
-{
- m << (unsigned int) v.size();
- for(unsigned i = 0; i < v.size(); i++)
- m << v[i];
- return m;
-}
-
template <class C> unmarshall &
operator>>(unmarshall &u, std::vector<C> &v)
{
unsigned n;
u >> n;
- for(unsigned i = 0; i < n; i++){
- C z;
- u >> z;
- v.push_back(z);
- }
+ v.clear();
+ while (n--) {
+ C c;
+ u >> c;
+ v.push_back(c);
+ }
return u;
}
-template <class A, class B> marshall &
-operator<<(marshall &m, const std::map<A,B> &d) {
- typename std::map<A,B>::const_iterator i;
-
- m << (unsigned int) d.size();
-
- for (i = d.begin(); i != d.end(); i++) {
- m << i->first << i->second;
- }
- return m;
-}
-
template <class A, class B> unmarshall &
operator>>(unmarshall &u, std::map<A,B> &d) {
- unsigned int n;
+ unsigned n;
u >> n;
-
d.clear();
-
- for (unsigned int lcv = 0; lcv < n; lcv++) {
- A a;
- B b;
- u >> a >> b;
- d[a] = b;
- }
+ while (n--) {
+ A a;
+ B b;
+ u >> a >> b;
+ d[a] = b;
+ }
return u;
}
+template <class C> unmarshall &
+operator>>(unmarshall &u, std::list<C> &l) {
+ unsigned n;
+ u >> n;
+ l.clear();
+ while (n--) {
+ C c;
+ u >> c;
+ l.push_back(c);
+ }
+ return u;
+}
+
+template <class A, class B> unmarshall &
+operator>>(unmarshall &u, std::pair<A,B> &d) {
+ return u >> d.first >> d.second;
+}
+
#endif