-// encoder/decode helpers
+// ----------------------------------------------------------
+// new encoders
-// -- basic types --
-// string
-inline void _encode(const std::string& s, bufferlist& bl)
-{
- bl.append(s.c_str(), s.length()+1);
-}
-inline void _decode(std::string& s, bufferlist& bl, int& off)
-{
- s = bl.c_str() + off;
- off += s.length() + 1;
-}
-
-// bufferptr (encapsulated)
-inline void _encode(bufferptr& bp, bufferlist& bl)
-{
- size_t len = bp.length();
- bl.append((char*)&len, sizeof(len));
- bl.append(bp);
-}
-inline void _decode(bufferptr& bp, bufferlist& bl, int& off)
-{
- size_t len;
- bl.copy(off, sizeof(len), (char*)&len);
- off += sizeof(len);
- bufferlist s;
- s.substr_of(bl, off, len);
- off += len;
-
- if (s.buffers().size() == 1)
- bp = s.buffers().front();
- else
- bp = buffer::copy(s.c_str(), s.length());
-}
-
-// bufferlist (encapsulated)
-inline void _encode(const bufferlist& s, bufferlist& bl)
+// raw
+template<class T>
+inline void _encoderaw(const T& t, bufferlist& bl)
{
- size_t len = s.length();
- bl.append((char*)&len, sizeof(len));
- bl.append(s);
+ bl.append((char*)&t, sizeof(t));
}
-inline void _decode(bufferlist& s, bufferlist& bl, int& off)
+template<class T>
+inline void _decoderaw(T& t, bufferlist& bl, int& off)
{
- size_t len;
- bl.copy(off, sizeof(len), (char*)&len);
- off += sizeof(len);
- s.substr_of(bl, off, len);
- off += len;
+ bl.copy(off, sizeof(t), (char*)&t);
+ off += sizeof(t);
}
-
#include <set>
#include <map>
+#include <deque>
#include <vector>
#include <string>
#include <ext/hash_map>
-// set<string>
-inline void _encode(const std::set<std::string>& s, bufferlist& bl)
-{
- int n = s.size();
- bl.append((char*)&n, sizeof(n));
- for (std::set<std::string>::const_iterator it = s.begin();
- it != s.end();
- it++) {
- ::_encode(*it, bl);
- n--;
- }
- assert(n==0);
-}
-inline void _decode(std::set<std::string>& s, bufferlist& bl, int& off)
-{
- s.clear();
- int n;
- bl.copy(off, sizeof(n), (char*)&n);
- off += sizeof(n);
- for (int i=0; i<n; i++) {
- std::string v;
- ::_decode(v, bl, off);
- s.insert(v);
- }
- assert(s.size() == (unsigned)n);
-}
-// vector<string>
-inline void _encode(std::vector<std::string>& s, bufferlist& bl)
-{
- int n = s.size();
- bl.append((char*)&n, sizeof(n));
- for (std::vector<std::string>::const_iterator it = s.begin();
- it != s.end();
- it++) {
- ::_encode(*it, bl);
- n--;
- }
- assert(n==0);
-}
-inline void _decode(std::vector<std::string>& s, bufferlist& bl, int& off)
-{
- s.clear();
- int n;
- bl.copy(off, sizeof(n), (char*)&n);
- off += sizeof(n);
- s = std::vector<std::string>(n);
- for (int i=0; i<n; i++) {
- ::_decode(s[i], bl, off);
- }
- assert(s.size() == (unsigned)n);
-}
-
-// list<bufferlist>
-inline void _encode(const std::list<bufferlist>& s, bufferlist& bl)
+// list
+template<class T>
+inline void _encode(const std::list<T>& ls, bufferlist& bl)
{
- int n = s.size();
- bl.append((char*)&n, sizeof(n));
- for (std::list<bufferlist>::const_iterator it = s.begin();
- it != s.end();
- it++) {
- ::_encode(*it, bl);
- n--;
- }
- assert(n==0);
+ __uint32_t n = ls.size();
+ _encoderaw(n, bl);
+ for (typename std::list<T>::const_iterator p = ls.begin(); p != ls.end(); ++p)
+ _encode(*p, bl);
}
-inline void _decode(std::list<bufferlist>& s, bufferlist& bl, int& off)
+template<class T>
+inline void _decode(std::list<T>& ls, bufferlist& bl, int& off)
{
- s.clear();
- int n;
- bl.copy(off, sizeof(n), (char*)&n);
- off += sizeof(n);
- for (int i=0; i<n; i++) {
- bufferlist v;
- s.push_back(v);
- ::_decode(s.back(), bl, off);
+ __uint32_t n;
+ _decoderaw(n, bl, off);
+ ls.clear();
+ while (n--) {
+ T v;
+ _decode(v, bl, off);
+ ls.push_back(v);
}
- //assert(s.size() == (unsigned)n);
}
-
-// set<T>
+// deque
template<class T>
-inline void _encode(const std::set<T>& s, bufferlist& bl)
+inline void _encode(const std::deque<T>& ls, bufferlist& bl)
{
- int n = s.size();
- bl.append((char*)&n, sizeof(n));
- for (typename std::set<T>::const_iterator it = s.begin();
- it != s.end();
- it++) {
- T v = *it;
- bl.append((char*)&v, sizeof(v));
- n--;
- }
- assert(n==0);
+ __uint32_t n = ls.size();
+ _encoderaw(n, bl);
+ for (typename std::deque<T>::const_iterator p = ls.begin(); p != ls.end(); ++p)
+ _encode(*p, bl);
}
template<class T>
-inline void _decode(std::set<T>& s, bufferlist& bl, int& off)
+inline void _decode(std::deque<T>& ls, bufferlist& bl, int& off)
{
- s.clear();
- int n;
- bl.copy(off, sizeof(n), (char*)&n);
- off += sizeof(n);
- for (int i=0; i<n; i++) {
+ __uint32_t n;
+ _decoderaw(n, bl, off);
+ ls.clear();
+ while (n--) {
T v;
- bl.copy(off, sizeof(v), (char*)&v);
- off += sizeof(v);
- s.insert(v);
+ _decode(v, bl, off);
+ ls.push_back(v);
}
- assert(s.size() == (unsigned)n);
}
-// vector<T>
+// set
template<class T>
-inline void _encode(std::vector<T>& s, bufferlist& bl)
+inline void _encode(const std::set<T>& s, bufferlist& bl)
{
- int n = s.size();
- bl.append((char*)&n, sizeof(n));
- for (typename std::vector<T>::iterator it = s.begin();
- it != s.end();
- it++) {
- T v = *it;
- bl.append((char*)&v, sizeof(v));
- n--;
- }
- assert(n==0);
+ __uint32_t n = s.size();
+ _encoderaw(n, bl);
+ for (typename std::set<T>::const_iterator p = s.begin(); p != s.end(); ++p)
+ _encode(*p, bl);
}
template<class T>
-inline void _decode(std::vector<T>& s, bufferlist& bl, int& off)
+inline void _decode(std::set<T>& s, bufferlist& bl, int& off)
{
+ __uint32_t n;
+ _decoderaw(n, bl, off);
s.clear();
- int n;
- bl.copy(off, sizeof(n), (char*)&n);
- off += sizeof(n);
- s = std::vector<T>(n);
- for (int i=0; i<n; i++) {
+ while (n--) {
T v;
- bl.copy(off, sizeof(v), (char*)&v);
- off += sizeof(v);
- s[i] = v;
+ _decode(v, bl, off);
+ s.insert(v);
}
- assert(s.size() == (unsigned)n);
}
-// list<T>
+// vector
template<class T>
-inline void _encode(const std::list<T>& s, bufferlist& bl)
+inline void _encode(const std::vector<T>& v, bufferlist& bl)
{
- int n = s.size();
- bl.append((char*)&n, sizeof(n));
- for (typename std::list<T>::const_iterator it = s.begin();
- it != s.end();
- it++) {
- T v = *it;
- bl.append((char*)&v, sizeof(v));
- n--;
- }
- assert(n==0);
+ __uint32_t n = v.size();
+ _encoderaw(n, bl);
+ for (typename std::vector<T>::const_iterator p = v.begin(); p != v.end(); ++p)
+ _encode(*p, bl);
}
template<class T>
-inline void _decode(std::list<T>& s, bufferlist& bl, int& off)
+inline void _decode(std::vector<T>& v, bufferlist& bl, int& off)
{
- s.clear();
- int n;
- bl.copy(off, sizeof(n), (char*)&n);
- off += sizeof(n);
- for (int i=0; i<n; i++) {
- T v;
- bl.copy(off, sizeof(v), (char*)&v);
- off += sizeof(v);
- s.push_back(v);
- }
- assert(s.size() == (unsigned)n);
+ __uint32_t n;
+ _decoderaw(n, bl, off);
+ v.resize(n);
+ for (__uint32_t i=0; i<n; i++)
+ _decode(v[i], bl, off);
}
-
-// map<string,bufferptr>
-inline void _encode(std::map<std::string, bufferptr>& s, bufferlist& bl)
+// map
+template<class T, class U>
+inline void _encode(const std::map<T,U>& m, bufferlist& bl)
{
- int n = s.size();
- bl.append((char*)&n, sizeof(n));
- for (std::map<std::string, bufferptr>::iterator it = s.begin();
- it != s.end();
- it++) {
- _encode(it->first, bl);
- _encode(it->second, bl);
- n--;
+ __uint32_t n = m.size();
+ _encoderaw(n, bl);
+ for (typename std::map<T,U>::const_iterator p = m.begin(); p != m.end(); ++p) {
+ _encode(p->first, bl);
+ _encode(p->second, bl);
}
- assert(n==0);
}
-inline void _decode(std::map<std::string,bufferptr>& s, bufferlist& bl, int& off)
+template<class T, class U>
+inline void _decode(std::map<T,U>& m, bufferlist& bl, int& off)
{
- s.clear();
- int n;
- bl.copy(off, sizeof(n), (char*)&n);
- off += sizeof(n);
- for (int i=0; i<n; i++) {
- std::string k;
+ __uint32_t n;
+ _decoderaw(n, bl, off);
+ m.clear();
+ while (n--) {
+ T k;
_decode(k, bl, off);
- _decode(s[k], bl, off);
+ _decode(m[k], bl, off);
}
- assert(s.size() == (unsigned)n);
}
-
-// map<T,bufferlist>
-template<class T>
-inline void _encode(const std::map<T, bufferlist>& s, bufferlist& bl)
+// hash_map
+template<class T, class U>
+inline void _encode(const __gnu_cxx::hash_map<T,U>& m, bufferlist& bl)
{
- int n = s.size();
- bl.append((char*)&n, sizeof(n));
- //std::cout << "n = " << n << std::endl;
- for (typename std::map<T, bufferlist>::const_iterator it = s.begin();
- it != s.end();
- it++) {
- T k = it->first;
- bl.append((char*)&k, sizeof(k));
- _encode(it->second, bl);
- n--;
- //std::cout << "--n = " << n << " after k " << k << std::endl;
+ __uint32_t n = m.size();
+ _encoderaw(n, bl);
+ for (typename __gnu_cxx::hash_map<T,U>::const_iterator p = m.begin(); p != m.end(); ++p) {
+ _encode(p->first, bl);
+ _encode(p->second, bl);
}
- assert(n==0);
}
-template<class T>
-inline void _decode(std::map<T,bufferlist>& s, bufferlist& bl, int& off)
+template<class T, class U>
+inline void _decode(__gnu_cxx::hash_map<T,U>& m, bufferlist& bl, int& off)
{
- s.clear();
- int n;
- bl.copy(off, sizeof(n), (char*)&n);
- off += sizeof(n);
- for (int i=0; i<n; i++) {
+ __uint32_t n;
+ _decoderaw(n, bl, off);
+ m.clear();
+ while (n--) {
T k;
- bl.copy(off, sizeof(k), (char*)&k);
- off += sizeof(k);
- bufferlist b;
- _decode(b, bl, off);
- s[k] = b;
+ _decode(k, bl, off);
+ _decode(m[k], bl, off);
}
- assert(s.size() == (unsigned)n);
}
-// map<string,U>
-template<class U>
-inline void _encode(const std::map<std::string, U>& s, bufferlist& bl)
+// string
+inline void _encode(const std::string& s, bufferlist& bl)
{
- int n = s.size();
- bl.append((char*)&n, sizeof(n));
- for (typename std::map<std::string, U>::const_iterator it = s.begin();
- it != s.end();
- it++) {
- ::_encode(it->first, bl);
- U v = it->second;
- bl.append((char*)&v, sizeof(v));
- n--;
- }
- assert(n==0);
+ __uint32_t len = s.length();
+ _encoderaw(len, bl);
+ bl.append(s.data(), len);
}
-template<class U>
-inline void _decode(std::map<std::string,U>& s, bufferlist& bl, int& off)
+inline void _decode(std::string& s, bufferlist& bl, int& off)
{
- s.clear();
- int n;
- bl.copy(off, sizeof(n), (char*)&n);
- off += sizeof(n);
- for (int i=0; i<n; i++) {
- std::string k;
- U v;
- ::_decode(k, bl, off);
- bl.copy(off, sizeof(v), (char*)&v);
- off += sizeof(v);
- s[k] = v;
- }
- assert(s.size() == (unsigned)n);
+ __uint32_t len;
+ _decoderaw(len, bl, off);
+ s = bl.c_str() + off; // FIXME someday to avoid a huge buffer copy?
+ off += len;
}
-// map<T,set<U>>
-template<class T, class U>
-inline void _encode(const std::map<T, std::set<U> >& s, bufferlist& bl)
-{
- int n = s.size();
- bl.append((char*)&n, sizeof(n));
- for (typename std::map<T, std::set<U> >::const_iterator it = s.begin();
- it != s.end();
- it++) {
- T k = it->first;
- bl.append((char*)&k, sizeof(k));
- ::_encode(it->second, bl);
- n--;
- }
- assert(n==0);
-}
-template<class T, class U>
-inline void _decode(std::map<T, std::set<U> >& s, bufferlist& bl, int& off)
-{
- s.clear();
- int n;
- bl.copy(off, sizeof(n), (char*)&n);
- off += sizeof(n);
- for (int i=0; i<n; i++) {
- T k;
- bl.copy(off, sizeof(k), (char*)&k);
- off += sizeof(k);
- ::_decode(s[k], bl, off);
- }
- assert(s.size() == (unsigned)n);
-}
-// map<T,list<U>>
-template<class T, class U>
-inline void _encode(const std::map<T, std::list<U> >& s, bufferlist& bl)
+// bufferptr (encapsulated)
+inline void _encode(bufferptr& bp, bufferlist& bl)
{
- int n = s.size();
- bl.append((char*)&n, sizeof(n));
- for (typename std::map<T, std::list<U> >::const_iterator it = s.begin();
- it != s.end();
- it++) {
- T k = it->first;
- bl.append((char*)&k, sizeof(k));
- ::_encode(it->second, bl);
- n--;
- }
- assert(n==0);
+ __uint32_t len = bp.length();
+ _encoderaw(len, bl);
+ bl.append(bp);
}
-template<class T, class U>
-inline void _decode(std::map<T, std::list<U> >& s, bufferlist& bl, int& off)
+inline void _decode(bufferptr& bp, bufferlist& bl, int& off)
{
- s.clear();
- int n;
- bl.copy(off, sizeof(n), (char*)&n);
- off += sizeof(n);
- for (int i=0; i<n; i++) {
- T k;
- bl.copy(off, sizeof(k), (char*)&k);
- off += sizeof(k);
- ::_decode(s[k], bl, off);
- }
- assert(s.size() == (unsigned)n);
-}
+ __uint32_t len;
+ _decoderaw(len, bl, off);
+ bufferlist s;
+ s.substr_of(bl, off, len);
+ off += len;
-// map<T,U>
-template<class T, class U>
-inline void _encode(const std::map<T, U>& s, bufferlist& bl)
+ if (s.buffers().size() == 1)
+ bp = s.buffers().front();
+ else
+ bp = buffer::copy(s.c_str(), s.length());
+}
+
+// bufferlist (encapsulated)
+inline void _encode(const bufferlist& s, bufferlist& bl)
{
- int n = s.size();
- bl.append((char*)&n, sizeof(n));
- for (typename std::map<T, U>::const_iterator it = s.begin();
- it != s.end();
- it++) {
- T k = it->first;
- U v = it->second;
- bl.append((char*)&k, sizeof(k));
- bl.append((char*)&v, sizeof(v));
- n--;
- }
- assert(n==0);
+ __uint32_t len = s.length();
+ _encoderaw(len, bl);
+ bl.append(s);
}
-template<class T, class U>
-inline void _decode(std::map<T,U>& s, bufferlist& bl, int& off)
+inline void _decode(bufferlist& s, bufferlist& bl, int& off)
{
- s.clear();
- int n;
- bl.copy(off, sizeof(n), (char*)&n);
- off += sizeof(n);
- for (int i=0; i<n; i++) {
- T k;
- bl.copy(off, sizeof(k), (char*)&k);
- off += sizeof(k);
- bl.copy(off, sizeof(U), (char*)&s[k]);
- off += sizeof(U);
- }
- assert(s.size() == (unsigned)n);
+ __uint32_t len;
+ _decoderaw(len, bl, off);
+ s.substr_of(bl, off, len);
+ off += len;
}
-// hash_map<T,U>
-template<class T, class U>
-inline void _encode(const __gnu_cxx::hash_map<T, U>& s, bufferlist& bl)
+// base
+template<class T>
+inline void _encode(const T& t, bufferlist& bl)
{
- int n = s.size();
- bl.append((char*)&n, sizeof(n));
- for (typename __gnu_cxx::hash_map<T, U>::const_iterator it = s.begin();
- it != s.end();
- it++) {
- T k = it->first;
- U v = it->second;
- bl.append((char*)&k, sizeof(k));
- bl.append((char*)&v, sizeof(v));
- n--;
- }
- assert(n==0);
+ _encoderaw(t, bl);
}
-template<class T, class U>
-inline void _decode(__gnu_cxx::hash_map<T,U>& s, bufferlist& bl, int& off)
+template<class T>
+inline void _decode(T& t, bufferlist& bl, int& off)
{
- s.clear();
- int n;
- bl.copy(off, sizeof(n), (char*)&n);
- off += sizeof(n);
- for (int i=0; i<n; i++) {
- T k;
- bl.copy(off, sizeof(k), (char*)&k);
- off += sizeof(k);
- bl.copy(off, sizeof(U), (char*)&s[k]);
- off += sizeof(U);
- }
- assert(s.size() == (unsigned)n);
+ _decoderaw(t, bl, off);
}
-
#endif