#ifndef STRINGSERIALIZATION_H
#define STRINGSERIALIZATION_H

#include <string>
#include <sstream>
#include <vector>
using namespace std;

#include <typedefs.h>

//  String serialization classes.
//  See http://en.wikipedia.org/wiki/Serialization 

/*!
\brief Read and write vectors to strings.
*/
class vectorstring
{
public:

  /** Write a vector to a string. */
  template< typename T >
  static boolc serialize(string & str, vector<T> const & v);
  /** Read a string into a vector.  */
  template< typename T >
  static boolc deserialize(vector<T> & v, stringc & str);

  template< typename T >
  static void serializeInverse(vector<T> & v, stringc & str)
    { deserialize(v,str); };
 

};

/*!
\brief Read and write files to strings.
*/
class filestring
{
public:

  /** Write a file to a string. Clears string first. */
  static boolc serialize(string & str, stringc & filename);
  /** Write a string to a file. */
  static boolc deserialize(stringc & filename, stringc & str);
  /** Write a string to a file. */
  static boolc serializeInverse(stringc & filename, stringc & str);
};

/*!
\brief Read and write vectors to files.
*/
class vectorfile
{
public:

  /** Write a vector to a file. */
  template< typename T >
  static boolc serialize(string & filename, vector<T> const & v);
  /** Read a vector from a file. */
  template< typename T >
  static boolc deserialize(vector<T> & v, stringc & filename);

};

/*!
\brief Convert html name strings.

i.e. Save text in xml tags without interfering with the tags. 
*/
class htmlstring
{
public:

  static string lessthan;
  static string greaterthan;
  static string amp;
  static string quot;

  /** Convert html to text. e.g. &amp; is replaced by &. */
  static boolc serialize(string & str, stringc & html );
  static boolc serializeInverse(string & html, stringc & str );

  /** If html encoding is present return true. */
  static boolc ishtml(stringc & str);

  


};




//---------------------------------------------------------
//  Implementation.

template< typename T >
boolc vectorstring::serialize(string & str, vector<T> const & v)
{
  uintc vsz=v.size();
  str="";
  stringc space(" ");
  
  for (uint i=0; i<vsz; ++i)
  {
    stringstream targ;
    targ << v[i];
    if (targ.good()==false)
      return false;
   
    str += (targ.str()+space);
  }

  return true;
}

template< typename T >
boolc vectorstring::deserialize(vector<T> & v, stringc & str)
{
  stringstream targ(str);
  if (targ.good()==false)
    return false;

  bool process=true;
  T val;
  for (;process; )
  {
    targ >> val;
    // The end of input must fail.
    if (targ.fail())
    {
      // If it is not the end of the data stream return false.
      if (!targ.eof())
        return false;

      // Do not add the last element twice.
      process=false;
    }
    else
      v.push_back(val);
  }
  
  return true;
}

template< typename T >
boolc vectorfile::serialize(string & filename, vector<T> const & v)
{
  bool result;
  string str;
  result=vectorstring::serialize(str,v);
  if (result==false)
    return false;

  result=filestring::deserialize(filename,str);
  if (result==false)
    return false;

  return true;
}

template< typename T >
boolc vectorfile::deserialize(vector<T> & v, stringc & filename)
{
  bool result;
  string str;
  result=filestring::serialize(str,filename);
  if (result==false)
    return false;

  result=vectorstring::deserialize(v,str);
  if (result==false)
    return false;

  return true;
}


#endif


