// yfs wire protocol

#ifndef yfs_protocol_h
#define yfs_protocol_h

#include "rpc.h"

class yfs_protocol {
 public:
  typedef unsigned long long inum;
  enum xxstatus { OK, RPCERR, NOENT, IOERR, FBIG };
  typedef int status;
  enum rpc_numbers {
    getfile = 0x5001,
    getdir,
    lookup,
    setattr,
    readdir,
   // readfile,
   // writefile,
    create,
    mknod, //I added it
    setsize,
    read,
    mkdir,
    write,
    unlink //,
   //test_server_connection
  };
  
  /* these are my flags; fuse's can change; code still works */
#define MODE	(1 << 0)
#define UID	(1 << 1)
#define GID	(1 << 2)
#define SIZE	(1 << 3)
#define ATIME	(1 << 4)
#define MTIME	(1 << 5)

  struct fileinfo {
    unsigned long long size;
    unsigned long atime;
    unsigned long mtime;
    unsigned long ctime;
  };
  struct dirinfo {
    unsigned long atime;
    unsigned long mtime;
    unsigned long ctime;
  };
  struct dirent {
    std::string name;
    unsigned long long inum;
  };
};

inline unmarshall &
operator>>(unmarshall &u, yfs_protocol::dirent &e)
{
  u >> e.name;
  u >> e.inum;
  return u;
}

inline marshall &
operator<<(marshall &m, yfs_protocol::dirent e)
{
  m << e.name;
  m << e.inum;
  return m;
}

inline unmarshall &
		operator>>(unmarshall &u, std::list<yfs_protocol::dirent> &lst)
{
	int size;
	u >> size;
	for (int kjd = 0; kjd < size; kjd++) {
		yfs_protocol::dirent e;
		u >> e;
		lst.push_back(e);
	}
	
	return u;
}

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



inline unmarshall &
operator>>(unmarshall &u, yfs_protocol::fileinfo &e)
{
  u >> e.size;
  u >> e.atime;
  u >> e.mtime;
  u >> e.ctime;
  return u;
}

inline marshall &
operator<<(marshall &m, yfs_protocol::fileinfo e)
{
  m << e.size;
  m << e.atime;
  m << e.mtime;
  m << e.ctime;
  return m;
}

inline unmarshall &
operator>>(unmarshall &u, yfs_protocol::dirinfo &e)
{
  u >> e.atime;
  u >> e.mtime;
  u >> e.ctime;
  return u;
}

inline marshall &
operator<<(marshall &m, yfs_protocol::dirinfo e)
{
  m << e.atime;
  m << e.mtime;
  m << e.ctime;
  return m;
}

#endif 
