#include "builtin_xiso.h"
#include "platform.h"
#include <sstream>

namespace xiso {


  void leaf<char>::read_text(void *elm, std::istringstream &istm, 
			     const aka2::preconditions &pcd) {
    long value;
    istm >> value;
    if ((value < -128) || (127 < value))
      throw aka2::parse_error(std::string("char value(" + istm.rdbuf()->str()
					  + ") is out of range."),
			      __FILE__, __LINE__);
    char &ch = *static_cast<char*>(elm);
    ch = (char)value;
  }

  void leaf<char>::write_text(const void *elm, std::ostream &ostm, 
			      const aka2::preconditions &pcd) {
    
    const char &uch = *static_cast<const char*>(elm);
    ostm << (const long)uch;
  }

  void leaf<unsigned char>::read_text(void *elm, std::istringstream &istm, 
				      const aka2::preconditions &pcd) {
    long value;
    istm >> value;
    if ((value < 0) || (255 < value))
      throw aka2::parse_error(std::string("unsigned char value(" + istm.rdbuf()->str()
					  + ") is out of range."),
			      __FILE__, __LINE__);
    unsigned char &ch = *static_cast<unsigned char*>(elm);
    ch = (unsigned char)value;
  }

  void leaf<unsigned char>::write_text(const void *elm, std::ostream &ostm, 
				       const aka2::preconditions &pcd) {
    
    const unsigned char &uch = *static_cast<const unsigned char*>(elm);
    ostm << (const unsigned long)uch;
  }


  void leaf<std::string>::read_text(void *elm, std::istringstream &istm,
				    const aka2::preconditions &pcd) {
    std::string &value = *reinterpret_cast<std::string*>(elm);
    value = istm.rdbuf()->str();
  }


  void leaf<bool>::read_text(void *elm, std::istringstream &istm,
			     const aka2::preconditions &gattrs) {
    bool &bval = *static_cast<bool*>(elm);
    const std::string &value = istm.rdbuf()->str();
    if ((value == "false") || (value == "0"))
      bval = false;
    else if ((value == "true") || (value == "1"))
      bval = true;
    else
      throw aka2::parse_error(std::string("Wrong bool value \"") + value + "\".",
			      __FILE__, __LINE__);
  }


  void leaf<bool>::write_text(const void *elm, std::ostream &ostm,
			      const aka2::preconditions &pcd) {
    bool val = *static_cast<const bool*>(elm);
    if (val)
      ostm << "true";
    else
      ostm << "false";
  }

  void leaf<LONGLONG>::write_text(const void *elm, std::ostream &ostm, 
				  const aka2::preconditions &pcd) {
    const LONGLONG &ll = *static_cast<const LONGLONG*>(elm);
#ifdef _MSC_VER
    char buf[64];
    sprintf(buf, "%I64d", ll);
    ostm << buf;
#else
    ostm << ll;    
#endif
  }

  void leaf<ULONGLONG>::write_text(const void *elm, std::ostream &ostm, 
				   const aka2::preconditions &pcd) {
    const ULONGLONG &ull = *static_cast<const ULONGLONG*>(elm);
#ifdef _MSC_VER
    char buf[128];
    sprintf(buf, "%I64u", ull);
    ostm << buf;
#else
    ostm << ull;    
#endif
  }



} // namespace xiso
