#include "xentax.h"

float32 float_16_to_32(uint16 value)
{
 // sign/exponent/mantissa
 const uint16 s = (value & 0x8000);
 const uint16 e = (value & 0x7C00) >> 10;
 const uint16 m = (value & 0x03FF);

 // ok
 const float32 sgn = (s ? -1.0f : 1.0f);
 if(e == 0) return sgn*(m == 0 ? 0.0f : std::pow(2.0f, -14.0f)*((float32)m/1024.0f));
 if(e < 32) return sgn*std::pow(2.0f, (float32)e - 15.0f)*(1.0f + ((float32)m/1024.0f));

 // not ok!
 if(m == 0) return std::numeric_limits<float32>::quiet_NaN();
 return std::numeric_limits<float32>::quiet_NaN();
}

sint08 LE_read_sint08(std::istream& ifile)
{
 sint08 temp;
 ifile.read((char*)&temp, sizeof(temp));
 return temp;
}

uint08 LE_read_uint08(std::istream& ifile)
{
 uint08 temp;
 ifile.read((char*)&temp, sizeof(temp));
 return temp;
}

sint16 LE_read_sint16(std::istream& ifile)
{
 sint16 temp;
 ifile.read((char*)&temp, sizeof(temp));
 return temp;
}

uint16 LE_read_uint16(std::istream& ifile)
{
 uint16 temp;
 ifile.read((char*)&temp, sizeof(temp));
 return temp;
}

sint32 LE_read_sint32(std::istream& ifile)
{
 sint32 temp;
 ifile.read((char*)&temp, sizeof(temp));
 return temp;
}

uint32 LE_read_uint32(std::istream& ifile)
{
 uint32 temp;
 ifile.read((char*)&temp, sizeof(temp));
 return temp;
}

sint64 LE_read_sint64(std::istream& ifile)
{
 sint64 temp;
 ifile.read((char*)&temp, sizeof(temp));
 return temp;
}

uint64 LE_read_uint64(std::istream& ifile)
{
 uint64 temp;
 ifile.read((char*)&temp, sizeof(temp));
 return temp;
}

sint08 LE_read_sint08(std::istream& ifile, unsigned int offset)
{
 ifile.seekg(offset);
 sint08 temp;
 ifile.read((char*)&temp, sizeof(temp));
 return temp;
}

uint08 LE_read_uint08(std::istream& ifile, unsigned int offset)
{
 ifile.seekg(offset);
 uint08 temp;
 ifile.read((char*)&temp, sizeof(temp));
 return temp;
}

sint16 LE_read_sint16(std::istream& ifile, unsigned int offset)
{
 ifile.seekg(offset);
 sint16 temp;
 ifile.read((char*)&temp, sizeof(temp));
 return temp;
}

uint16 LE_read_uint16(std::istream& ifile, unsigned int offset)
{
 ifile.seekg(offset);
 uint16 temp;
 ifile.read((char*)&temp, sizeof(temp));
 return temp;
}

sint32 LE_read_sint32(std::istream& ifile, unsigned int offset)
{
 ifile.seekg(offset);
 sint32 temp;
 ifile.read((char*)&temp, sizeof(temp));
 return temp;
}

uint32 LE_read_uint32(std::istream& ifile, unsigned int offset)
{
 ifile.seekg(offset);
 uint32 temp;
 ifile.read((char*)&temp, sizeof(temp));
 return temp;
}

sint64 LE_read_sint64(std::istream& ifile, unsigned int offset)
{
 ifile.seekg(offset);
 sint64 temp;
 ifile.read((char*)&temp, sizeof(temp));
 return temp;
}

uint64 LE_read_uint64(std::istream& ifile, unsigned int offset)
{
 ifile.seekg(offset);
 uint64 temp;
 ifile.read((char*)&temp, sizeof(temp));
 return temp;
}

sint08 BE_read_sint08(std::istream& ifile)
{
 sint08 temp;
 ifile.read((char*)&temp, sizeof(temp));
 return temp;
}

uint08 BE_read_uint08(std::istream& ifile)
{
 uint08 temp;
 ifile.read((char*)&temp, sizeof(temp));
 return temp;
}

sint16 BE_read_sint16(std::istream& ifile)
{
 sint16 temp;
 ifile.read((char*)&temp, sizeof(temp));
 reverse_byte_order(&temp);
 return temp;
}

uint16 BE_read_uint16(std::istream& ifile)
{
 uint16 temp;
 ifile.read((char*)&temp, sizeof(temp));
 reverse_byte_order(&temp);
 return temp;
}

sint32 BE_read_sint32(std::istream& ifile)
{
 sint32 temp;
 ifile.read((char*)&temp, sizeof(temp));
 reverse_byte_order(&temp);
 return temp;
}

uint32 BE_read_uint32(std::istream& ifile)
{
 uint32 temp;
 ifile.read((char*)&temp, sizeof(temp));
 reverse_byte_order(&temp);
 return temp;
}

sint64 BE_read_sint64(std::istream& ifile)
{
 sint64 temp;
 ifile.read((char*)&temp, sizeof(temp));
 reverse_byte_order(&temp);
 return temp;
}

uint64 BE_read_uint64(std::istream& ifile)
{
 uint64 temp;
 ifile.read((char*)&temp, sizeof(temp));
 reverse_byte_order(&temp);
 return temp;
}

sint08 BE_read_sint08(std::istream& ifile, unsigned int offset)
{
 ifile.seekg(offset);
 sint08 temp;
 ifile.read((char*)&temp, sizeof(temp));
 reverse_byte_order(&temp);
 return temp;
}

uint08 BE_read_uint08(std::istream& ifile, unsigned int offset)
{
 ifile.seekg(offset);
 uint08 temp;
 ifile.read((char*)&temp, sizeof(temp));
 reverse_byte_order(&temp);
 return temp;
}

sint16 BE_read_sint16(std::istream& ifile, unsigned int offset)
{
 ifile.seekg(offset);
 sint16 temp;
 ifile.read((char*)&temp, sizeof(temp));
 reverse_byte_order(&temp);
 return temp;
}

uint16 BE_read_uint16(std::istream& ifile, unsigned int offset)
{
 ifile.seekg(offset);
 uint16 temp;
 ifile.read((char*)&temp, sizeof(temp));
 reverse_byte_order(&temp);
 return temp;
}

sint32 BE_read_sint32(std::istream& ifile, unsigned int offset)
{
 ifile.seekg(offset);
 sint32 temp;
 ifile.read((char*)&temp, sizeof(temp));
 reverse_byte_order(&temp);
 return temp;
}

uint32 BE_read_uint32(std::istream& ifile, unsigned int offset)
{
 ifile.seekg(offset);
 uint32 temp;
 ifile.read((char*)&temp, sizeof(temp));
 reverse_byte_order(&temp);
 return temp;
}

sint64 BE_read_sint64(std::istream& ifile, unsigned int offset)
{
 ifile.seekg(offset);
 sint64 temp;
 ifile.read((char*)&temp, sizeof(temp));
 reverse_byte_order(&temp);
 return temp;
}

uint64 BE_read_uint64(std::istream& ifile, unsigned int offset)
{
 ifile.seekg(offset);
 uint64 temp;
 ifile.read((char*)&temp, sizeof(temp));
 reverse_byte_order(&temp);
 return temp;
}

float32 LE_read_float16(std::istream& ifile)
{
 unsigned short temp;
 ifile.read((char*)&temp, sizeof(temp));
 return float_16_to_32(temp);
}

float32 LE_read_float32(std::istream& ifile)
{
 float32 temp;
 ifile.read((char*)&temp, sizeof(temp));
 return temp;
}

float64 LE_read_float64(std::istream& ifile)
{
 float64 temp;
 ifile.read((char*)&temp, sizeof(temp));
 return temp;
}

float32 LE_read_float16(std::istream& ifile, unsigned int offset)
{
 ifile.seekg(offset);
 unsigned short temp;
 ifile.read((char*)&temp, sizeof(temp));
 return float_16_to_32(temp);
}

float32 LE_read_float32(std::istream& ifile, unsigned int offset)
{
 ifile.seekg(offset);
 float32 temp;
 ifile.read((char*)&temp, sizeof(temp));
 return temp;
}

float64 LE_read_float64(std::istream& ifile, unsigned int offset)
{
 ifile.seekg(offset);
 float64 temp;
 ifile.read((char*)&temp, sizeof(temp));
 return temp;
}

float32 BE_read_float16(std::istream& ifile)
{
 unsigned short temp;
 ifile.read((char*)&temp, sizeof(temp));
 reverse_byte_order(&temp);
 return float_16_to_32(temp);
}

float32 BE_read_float32(std::istream& ifile)
{
 float32 temp;
 ifile.read((char*)&temp, sizeof(temp));
 reverse_byte_order(&temp);
 return temp;
}

float64 BE_read_float64(std::istream& ifile)
{
 float64 temp;
 ifile.read((char*)&temp, sizeof(temp));
 reverse_byte_order(&temp);
 return temp;
}

float32 BE_read_float16(std::istream& ifile, unsigned int offset)
{
 ifile.seekg(offset);
 float32 temp;
 ifile.read((char*)&temp, sizeof(temp));
 reverse_byte_order(&temp);
 return temp;
}

float32 BE_read_float32(std::istream& ifile, unsigned int offset)
{
 ifile.seekg(offset);
 float32 temp;
 ifile.read((char*)&temp, sizeof(temp));
 reverse_byte_order(&temp);
 return temp;
}

float64 BE_read_float64(std::istream& ifile, unsigned int offset)
{
 ifile.seekg(offset);
 float64 temp;
 ifile.read((char*)&temp, sizeof(temp));
 reverse_byte_order(&temp);
 return temp;
}

bool read_string(std::istream& ifile, char* data, size_t size)
{ 
 return read_string(ifile, data, size, (char)0);
}

bool read_string(std::istream& ifile, char* data, size_t size, char delimiter)
{
 if(size == 0) return false;
 for(size_t curr = 0; ; curr++) {
     char c = (char)ifile.peek();
     if(ifile.fail() || ifile.eof()) return false;
     ifile.seekg(1, ios::cur);
     if(ifile.fail()) return false;
     if(c == delimiter) { data[curr] = '\0'; break; }
     else data[curr] = c;     
    }
 return true;
}