/////////////////////////////////////////////////////////////////
//
// Copyright (C) 2005 Affymetrix, Inc.
//
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation; either version 2.1 of the License,
// or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
// for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this library; if not, write to the Free Software Foundation, Inc.,
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 
//
/////////////////////////////////////////////////////////////////

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <cstring>		// port to gcc 4.3, by Tao Liu
#include <climits>		// port to gcc 4.3, by Tao Liu
#include <cstdlib>		// port to gcc 4.3, by Tao Liu
#include <cstdio>		// port to gcc 4.3, by Tao Liu
#include <cctype>		// port to gcc 4.3, by Tao Liu
#include <algorithm>		// port to gcc 4.3, by Tao Liu
#include <iterator>		// port to gcc 4.3, by Tao Liu
#include <memory>		// port to gcc 4.3, by Tao Liu
#include <typeinfo>		// port to gcc 4.3, by Tao Liu

#include "FileWriter.h"

//////////////////////////////////////////////////////////////////////

#ifdef WIN32
#include <winsock2.h>
#else
#include <inttypes.h>
#include <netinet/in.h>
#include <sys/types.h>
#endif

using namespace std;

//
void 
WriteUInt32_I(OFSTREAM& outstr,uint32_t val)
{
  val = htoil(val);
 	outstr.write((char *)&val,sizeof(val));
}
void
WriteInt32_I(OFSTREAM& outstr,int32_t val)
{
  WriteUInt32_I(outstr,(uint32_t)val);
}
//
void 
WriteUInt32_N(OFSTREAM& outstr,uint32_t val)
{
  val = htonl(val);
 	outstr.write((char *)&val,sizeof(val));
}
void
WriteInt32_N(OFSTREAM& outstr,int32_t val)
{
  WriteUInt32_N(outstr,(uint32_t)val);
}

//
void
WriteUInt16_I(OFSTREAM& outstr,uint16_t val)
{
  val = htois(val);
 	outstr.write((char *)&val,sizeof(val));
}
void
WriteInt16_I(OFSTREAM& outstr,int16_t val)
{
  WriteUInt16_I(outstr,(uint16_t)val);
}
void
WriteUInt16_N(OFSTREAM& outstr,uint16_t val)
{
  val = htons(val);
 	outstr.write((char *)&val,sizeof(val));
}
void
WriteInt16_N(OFSTREAM& outstr,int16_t val)
{
  WriteUInt16_N(outstr,(uint16_t)val);
}

//
void 
WriteUInt8(OFSTREAM& outstr,uint8_t val)
{
 	outstr.write((char *)&val,sizeof(val));
}
void 
WriteInt8(OFSTREAM& outstr,int8_t val)
{
  WriteUInt8(outstr,(uint8_t)val);
}

//
void 
WriteFloat_I(OFSTREAM& outstr,float fval)
{
	WriteUInt32_I(outstr,*(uint32_t *)(&fval));
}
void 
WriteFloat_N(OFSTREAM& outstr,float fval)
{
	WriteUInt32_N(outstr,*(uint32_t *)(&fval));
}


// Customers wanted repeatablity with old
// text files with only had a single digit after the decimal point.

void
WriteFloatLowPrecision(OFSTREAM& outstr,float fval)
{
  fval=(float)((floor((fval+0.05)*10))/10.0);
	WriteFloat_I(outstr,fval);
}

//====================

// normal C strings.
void 
WriteFixedCString(OFSTREAM& outstr,const char* str,size_t outlen)
{
  uint32_t slen=(uint32_t)strlen(str);
  outstr.write(str,((outlen<slen)?(uint32_t)outlen:slen));
  // pad with nulls
  for (uint32_t i=slen;i<outlen;i++) {
    outstr.put(0);
  }
}

void 
WriteCString(OFSTREAM& outstr,const char* str)
{
  uint32_t slen=(uint32_t)strlen(str);
 	WriteUInt32_I(outstr,slen);
  WriteFixedCString(outstr,str,slen);
}

// C++ strings

void 
WriteFixedString(OFSTREAM& outstr,const string& str,size_t outlen)
{
  WriteFixedCString(outstr,str.c_str(),outlen);
}

void
WriteString_I(OFSTREAM& outstr,const string& str)
{
	WriteCString(outstr,str.c_str());
}

void
WriteString_N(OFSTREAM& outstr,const string& str)
{
	int len = (int) str.length();
	WriteInt32_N(outstr, len);
	WriteFixedString(outstr, str, len);
}

// Character Array
void
WriteCharacterArray(OFSTREAM& outstr, char *c, size_t outlen)
{
        for (uint32_t i=0; i<outlen; i++) { outstr.put(c[i]); }
}

