#ifndef marshall_h
#define marshall_h

#include <sstream>
#include <string>
#include <vector>

//#include "../src/member.h"
#include <list>



class marshall {
 private:
  std::ostringstream s;
 public:
  marshall() { }
  const std::string str() const { return s.str(); }
  void rawbyte(unsigned);
  void rawbytes(const char *, int);
};
marshall& operator<<(marshall &, unsigned int);
marshall& operator<<(marshall &, unsigned long);
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 &, const std::string &);


// i32() &c do not directly signal an error.
// call ok() to check that all calls succeeded.
class unmarshall {
 private:
  std::istringstream s;
  bool _ok;
 public:
  unmarshall(const std::string &xs) : s(xs), _ok(true) { }
  unmarshall() : _ok(true) { }
  void str(std::string xs) { s.str(xs); }
  bool ok() { return _ok; }
  bool okdone();
  unsigned int rawbyte();
  std::string rawbytes(unsigned int n);
  unsigned int i32();
  unsigned long long i64();
  std::string istr();
};
unmarshall& operator>>(unmarshall &, unsigned char &);
unmarshall& operator>>(unmarshall &, char &);
unmarshall& operator>>(unmarshall &, unsigned short &);
unmarshall& operator>>(unmarshall &, short &);
unmarshall& operator>>(unmarshall &, unsigned int &);
unmarshall& operator>>(unmarshall &, unsigned long &);
unmarshall& operator>>(unmarshall &, int &);
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 int i = 0; i < v.size(); i++)
    m << v[i];
  return m;
}

template <class C> unmarshall &
operator>>(unmarshall &u, std::vector<C> &v)
{
  int n;
  u >> n;
  for(int i = 0; i < n; i++){
    C z;
    u >> z;
    v.push_back(z);
  }
  return u;
}



/* inline marshall&  */
/* operator<<(marshall & b, std::list<member> lst) { */
/* 	std::list<member>::iterator it = lst.begin(); */
/* 	b << lst.size(); */
/* 	while (it != lst.end()) { */
/* 		b << (member) *it;	 */
/* 		it++; */
/* 	} */
/* 	return b; */
/* } */


/* inline umarshall&  */
/* operator>>(umarshall & b, std::list<member> & lst) { */
/* 	lst.clear(); */
/* 	unsigned int size; */
/* 	b >> size; */
/* 	for (int i = 0;  i < size ; i++) { */
/* 		member m; */
/* 		b >> m; */
/* 		lst.push_back(m); */
/* 	} */
/* 	return b; */
	
/* } */






#endif
