#ifndef _SERIALIZATION_H
#define _SERIALIZATION_H

#include <string>


/// Helper templates for binary data.
// These functions come in two forms:
//
// pcWrite(targetBuffer, data);
//   writes data into targetBuffer.  Returns address of the byte just after the written data.
//
// pcRead(sourceBuffer, pData);
//   reads data into *pData from sourceBuffer.  Returns address of byte just after the read data.
template<class TYPE> 
inline char* pcWrite(char* buffer, const TYPE& t)
{
  *((TYPE*)buffer) = t;
  return buffer + sizeof(TYPE);
}

template<class TYPE> 
inline const char* pcRead(const char* buffer, TYPE* pt)
{
  *pt = *((TYPE*)buffer);
  return buffer + sizeof(TYPE);
}


inline char* pcWriteBuffer(char* pcTarget, const char*buffer, int iLen)
{
  char* pc = pcWrite(pcTarget, iLen);
  memcpy(pc, buffer, iLen);
  return pc + iLen;
}

// Makes *ppcTarget point to constant data straight from the buffer.
// Use memcpy to get your own copy.
inline const char* pcReadBuffer(const char* pcSource, const char**ppcTarget, int *piLen)
{
  
  const char* pc = pcRead(pcSource, piLen);
  *ppcTarget = pc;
  return pc + *piLen;
}

inline char* pcWriteString(char* buffer, const char* writeMe)
{
  return pcWriteBuffer(buffer, writeMe, strlen(writeMe)+1);
}

// Makes *ppcString point to constant sting data straight from the buffer.
// Use strcpy to get your own copy.
inline const char* pcReadString(const char* buffer, const char** ppcString)
{
  int iLen;
  const char* pc = pcReadBuffer(buffer, ppcString, &iLen);
  Assert(pc[-1] == '\0');
  return pc;
}

inline char* pcWriteString(char* buffer, const string writeMe)
{
  return pcWriteString(buffer, writeMe.c_str());
}

// Actually copies into the string
inline const char* pcReadString(const char* buffer, string* pString)
{
  const char* pcSource = 0;

  // Read the data.
  const char* pc = pcReadString(buffer, &pcSource);
  
  // Copy it into the string.
  *pString = pcSource;
  return pc;
}


template <class C>
inline int iExpectedBinarySize(C& c)
{
  return sizeof(C);
}

inline int iExpectedBinarySizeString(const char* pcString)
{
  return sizeof(int) + strlen(pcString) + 1;
}



#endif
