#include "xentax.h"

const binary_stream::size_type binary_stream::npos = std::numeric_limits<size_type>::max();

binary_stream::binary_stream()
{
 elem = 0;
 position = 0;
}

binary_stream::binary_stream(const binary_stream& bs)
{
 data = bs.data;
 elem = bs.elem;
 position = bs.position;
}

binary_stream::binary_stream(const boost::shared_array<char>& stream, size_type n)
{
 data = stream;
 elem = n;
 position = 0;
}

binary_stream::~binary_stream()
{
}

binary_stream& binary_stream::operator =(const binary_stream& bs)
{
 if(this == &bs) return *this;
 data = bs.data;
 elem = bs.elem;
 position = bs.position;
 return *this;
}

void binary_stream::seek(size_type pos)
{
 if(can_seek(pos)) position = pos;
 else position = npos;
}

void binary_stream::seek_reverse(size_type pos)
{
 if(can_seek(pos)) position = elem - pos;
 else position = npos;
}

void binary_stream::move(diff_type pos)
{
 if(pos == 0) return;
 else if(pos > 0) seek(position + pos);
 else if(pos < 0) {
    size_type off = (size_type)std::abs(pos);
    if(!(position < off)) position -= off;
    else position = npos;
   }
}

void binary_stream::move(diff_type pos, size_type from)
{
 if(fail()) return;
 seek(from);
 if(good()) move(pos);
}

void binary_stream::reset(void)
{
 position = 0;
}

binary_stream::size_type binary_stream::search(const char* pattern, size_type p_len, size_t from)
{
 // initialize bad-character shifts
 boost::shared_array<unsigned char> table(new unsigned char[256]);
 for(size_t i = 0; i < 256; i++) table[i] = p_len;

 // bad-character shifts
 const unsigned char* p_str = reinterpret_cast<const unsigned char*>(pattern);
 for(size_t i = 0; i < p_len - 1; i++) table[p_str[i]] = p_len - i - 1;

 // convert source string
 const unsigned char* s_str = reinterpret_cast<const unsigned char*>(data.get());
 size_type s_len = elem;

 // search for p_str in s_str
 size_t j = from;
 while(j <= (s_len - p_len)) {
       unsigned char c = s_str[j + p_len - 1];
       if(p_str[p_len - 1] == c && memcmp(p_str, s_str + j, p_len - 1) == 0) return j;
       j += table[c];
      }

 return npos;
}

void binary_stream::read(char* ptr, size_type n)
{
 if(fail() || !ptr || !n) return;
 size_type newpos = position + n;
 if(!can_move(n)) { position = npos; return; }
 memmove(ptr, c_pos(), n);
 position = newpos;
}

void binary_stream::read_reverse(char* ptr, size_type n)
{
 read(ptr, n);
 if(good()) std::reverse(ptr, ptr + n);
}

std::string binary_stream::read_string(void)
{
 std::string retval;
 for(;;) {
     char c;
     read(&c, 1);
     if(fail()) break;
     retval += c;
     if(c == '\0') break;
    }
 return retval;
}

sint08 binary_stream::LE_read_sint08(void)
{
 typedef sint08 T;
 if(fail() || !(position < (npos - sizeof(T)))) return T();
 size_type newpos = position + sizeof(T);
 if(!can_seek(newpos)) { position = npos; return T(); }
 T r = *reinterpret_cast<const T*>(c_pos());
 position = newpos;
 return r;
}

uint08 binary_stream::LE_read_uint08(void)
{
 typedef uint08 T;
 if(fail() || !(position < (npos - sizeof(T)))) return T();
 size_type newpos = position + sizeof(T);
 if(!can_seek(newpos)) { position = npos; return T(); }
 T r = *reinterpret_cast<const T*>(c_pos());
 position = newpos;
 return r;
}

sint16 binary_stream::LE_read_sint16(void)
{
 typedef sint16 T;
 if(fail() || !(position < (npos - sizeof(T)))) return T();
 size_type newpos = position + sizeof(T);
 if(!can_seek(newpos)) { position = npos; return T(); }
 T r = *reinterpret_cast<const T*>(c_pos());
 position = newpos;
 return r;
}

uint16 binary_stream::LE_read_uint16(void)
{
 typedef uint16 T;
 if(fail() || !(position < (npos - sizeof(T)))) return T();
 size_type newpos = position + sizeof(T);
 if(!can_seek(newpos)) { position = npos; return T(); }
 T r = *reinterpret_cast<const T*>(c_pos());
 position = newpos;
 return r;
}

sint32 binary_stream::LE_read_sint32(void)
{
 typedef sint32 T;
 if(fail() || !(position < (npos - sizeof(T)))) return T();
 size_type newpos = position + sizeof(T);
 if(!can_seek(newpos)) { position = npos; return T(); }
 T r = *reinterpret_cast<const T*>(c_pos());
 position = newpos;
 return r;
}

uint32 binary_stream::LE_read_uint32(void)
{
 typedef uint32 T;
 if(fail() || !(position < (npos - sizeof(T)))) return T();
 size_type newpos = position + sizeof(T);
 if(!can_seek(newpos)) { position = npos; return T(); }
 T r = *reinterpret_cast<const T*>(c_pos());
 position = newpos;
 return r;
}

sint64 binary_stream::LE_read_sint64(void)
{
 typedef sint64 T;
 if(fail() || !(position < (npos - sizeof(T)))) return T();
 size_type newpos = position + sizeof(T);
 if(!can_seek(newpos)) { position = npos; return T(); }
 T r = *reinterpret_cast<const T*>(c_pos());
 position = newpos;
 return r;
}

uint64 binary_stream::LE_read_uint64(void)
{
 typedef uint64 T;
 if(fail() || !(position < (npos - sizeof(T)))) return T();
 size_type newpos = position + sizeof(T);
 if(!can_seek(newpos)) { position = npos; return T(); }
 T r = *reinterpret_cast<const T*>(c_pos());
 position = newpos;
 return r;
}

sint08 binary_stream::LE_read_sint08(size_type pos)
{
 typedef sint08 T;
 if(fail() || !(pos < (npos - sizeof(T)))) return T();
 size_type newpos = pos + sizeof(T);
 if(can_seek(newpos)) return *reinterpret_cast<const T*>(c_str(pos));
 position = npos;
 return T();
}

uint08 binary_stream::LE_read_uint08(size_type pos)
{
 typedef uint08 T;
 if(fail() || !(pos < (npos - sizeof(T)))) return T();
 size_type newpos = pos + sizeof(T);
 if(can_seek(newpos)) return *reinterpret_cast<const T*>(c_str(pos));
 position = npos;
 return T();
}

sint16 binary_stream::LE_read_sint16(size_type pos)
{
 typedef sint16 T;
 if(fail() || !(pos < (npos - sizeof(T)))) return T();
 size_type newpos = pos + sizeof(T);
 if(can_seek(newpos)) return *reinterpret_cast<const T*>(c_str(pos));
 position = npos;
 return T();
}

uint16 binary_stream::LE_read_uint16(size_type pos)
{
 typedef uint16 T;
 if(fail() || !(pos < (npos - sizeof(T)))) return T();
 size_type newpos = pos + sizeof(T);
 if(can_seek(newpos)) return *reinterpret_cast<const T*>(c_str(pos));
 position = npos;
 return T();
}

sint32 binary_stream::LE_read_sint32(size_type pos)
{
 typedef sint32 T;
 if(fail() || !(pos < (npos - sizeof(T)))) return T();
 size_type newpos = pos + sizeof(T);
 if(can_seek(newpos)) return *reinterpret_cast<const T*>(c_str(pos));
 position = npos;
 return T();
}

uint32 binary_stream::LE_read_uint32(size_type pos)
{
 typedef uint32 T;
 if(fail() || !(pos < (npos - sizeof(T)))) return T();
 size_type newpos = pos + sizeof(T);
 if(can_seek(newpos)) return *reinterpret_cast<const T*>(c_str(pos));
 position = npos;
 return T();
}

sint64 binary_stream::LE_read_sint64(size_type pos)
{
 typedef sint64 T;
 if(fail() || !(pos < (npos - sizeof(T)))) return T();
 size_type newpos = pos + sizeof(T);
 if(can_seek(newpos)) return *reinterpret_cast<const T*>(c_str(pos));
 position = npos;
 return T();
}

uint64 binary_stream::LE_read_uint64(size_type pos)
{
 typedef uint64 T;
 if(fail() || !(pos < (npos - sizeof(T)))) return T();
 size_type newpos = pos + sizeof(T);
 if(can_seek(newpos)) return *reinterpret_cast<const T*>(c_str(pos));
 position = npos;
 return T();
}

sint08 binary_stream::BE_read_sint08(void)
{
 return LE_read_sint08();
}

uint08 binary_stream::BE_read_uint08(void)
{
 return LE_read_uint08();
}

sint16 binary_stream::BE_read_sint16(void)
{
 typedef sint16 T;
 if(fail() || !(position < (npos - sizeof(T)))) return T();
 size_type newpos = position + sizeof(T);
 if(!can_seek(newpos)) { position = npos; return T(); }
 T r = *reinterpret_cast<const T*>(c_pos());
 position = newpos;
 reverse_byte_order(&r);
 return r;
}

uint16 binary_stream::BE_read_uint16(void)
{
 typedef uint16 T;
 if(fail() || !(position < (npos - sizeof(T)))) return T();
 size_type newpos = position + sizeof(T);
 if(!can_seek(newpos)) { position = npos; return T(); }
 T r = *reinterpret_cast<const T*>(c_pos());
 position = newpos;
 reverse_byte_order(&r);
 return r;
}

sint32 binary_stream::BE_read_sint32(void)
{
 typedef sint32 T;
 if(fail() || !(position < (npos - sizeof(T)))) return T();
 size_type newpos = position + sizeof(T);
 if(!can_seek(newpos)) { position = npos; return T(); }
 T r = *reinterpret_cast<const T*>(c_pos());
 position = newpos;
 reverse_byte_order(&r);
 return r;
}

uint32 binary_stream::BE_read_uint32(void)
{
 typedef uint32 T;
 if(fail() || !(position < (npos - sizeof(T)))) return T();
 size_type newpos = position + sizeof(T);
 if(!can_seek(newpos)) { position = npos; return T(); }
 T r = *reinterpret_cast<const T*>(c_pos());
 position = newpos;
 reverse_byte_order(&r);
 return r;
}

sint64 binary_stream::BE_read_sint64(void)
{
 typedef sint64 T;
 if(fail() || !(position < (npos - sizeof(T)))) return T();
 size_type newpos = position + sizeof(T);
 if(!can_seek(newpos)) { position = npos; return T(); }
 T r = *reinterpret_cast<const T*>(c_pos());
 position = newpos;
 reverse_byte_order(&r);
 return r;
}

uint64 binary_stream::BE_read_uint64(void)
{
 typedef uint64 T;
 if(fail() || !(position < (npos - sizeof(T)))) return T();
 size_type newpos = position + sizeof(T);
 if(!can_seek(newpos)) { position = npos; return T(); }
 T r = *reinterpret_cast<const T*>(c_pos());
 position = newpos;
 reverse_byte_order(&r);
 return r;
}

sint08 binary_stream::BE_read_sint08(size_type pos)
{
 return LE_read_sint08(pos);
}

uint08 binary_stream::BE_read_uint08(size_type pos)
{
 return LE_read_uint08(pos);
}

sint16 binary_stream::BE_read_sint16(size_type pos)
{
 typedef sint16 T;
 if(fail() || !(pos < (npos - sizeof(T)))) return T();
 size_type newpos = pos + sizeof(T);
 if(!can_seek(newpos)) { position = npos; return T(); }
 T r = *reinterpret_cast<const T*>(c_str(pos));
 reverse_byte_order(&r);
 return r;
}

uint16 binary_stream::BE_read_uint16(size_type pos)
{
 typedef uint16 T;
 if(fail() || !(pos < (npos - sizeof(T)))) return T();
 size_type newpos = pos + sizeof(T);
 if(!can_seek(newpos)) { position = npos; return T(); }
 T r = *reinterpret_cast<const T*>(c_str(pos));
 reverse_byte_order(&r);
 return r;
}

sint32 binary_stream::BE_read_sint32(size_type pos)
{
 typedef sint32 T;
 if(fail() || !(pos < (npos - sizeof(T)))) return T();
 size_type newpos = pos + sizeof(T);
 if(!can_seek(newpos)) { position = npos; return T(); }
 T r = *reinterpret_cast<const T*>(c_str(pos));
 reverse_byte_order(&r);
 return r;
}

uint32 binary_stream::BE_read_uint32(size_type pos)
{
 typedef uint32 T;
 if(fail() || !(pos < (npos - sizeof(T)))) return T();
 size_type newpos = pos + sizeof(T);
 if(!can_seek(newpos)) { position = npos; return T(); }
 T r = *reinterpret_cast<const T*>(c_str(pos));
 reverse_byte_order(&r);
 return r;
}

sint64 binary_stream::BE_read_sint64(size_type pos)
{
 typedef sint64 T;
 if(fail() || !(pos < (npos - sizeof(T)))) return T();
 size_type newpos = pos + sizeof(T);
 if(!can_seek(newpos)) { position = npos; return T(); }
 T r = *reinterpret_cast<const T*>(c_str(pos));
 reverse_byte_order(&r);
 return r;
}

uint64 binary_stream::BE_read_uint64(size_type pos)
{
 typedef uint64 T;
 if(fail() || !(pos < (npos - sizeof(T)))) return T();
 size_type newpos = pos + sizeof(T);
 if(!can_seek(newpos)) { position = npos; return T(); }
 T r = *reinterpret_cast<const T*>(c_str(pos));
 reverse_byte_order(&r);
 return r;
}

float32 binary_stream::LE_read_float16(void)
{
 typedef uint16 T; typedef float32 R;
 if(fail() || !(position < (npos - sizeof(T)))) return R();
 size_type oldpos = position;
 size_type newpos = position + sizeof(T);
 if(!can_seek(newpos)) { position = npos; return R(); }
 position = newpos;
 T r = *reinterpret_cast<const T*>(c_str(oldpos));
 return float_16_to_32(r);
}

float32 binary_stream::LE_read_float32(void)
{
 typedef float32 T;
 if(fail() || !(position < (npos - sizeof(T)))) return T();
 size_type oldpos = position;
 size_type newpos = position + sizeof(T);
 if(!can_seek(newpos)) { position = npos; return T(); }
 position = newpos;
 return *reinterpret_cast<const T*>(c_str(oldpos));
}

float64 binary_stream::LE_read_float64(void)
{
 typedef float64 T;
 if(fail() || !(position < (npos - sizeof(T)))) return T();
 size_type oldpos = position;
 size_type newpos = position + sizeof(T);
 if(!can_seek(newpos)) { position = npos; return T(); }
 position = newpos;
 return *reinterpret_cast<const T*>(c_str(oldpos));
}

float32 binary_stream::LE_read_float16(size_type pos)
{
 typedef uint16 T; typedef float32 R;
 if(fail() || !(pos < (npos - sizeof(T)))) return R();
 size_type newpos = pos + sizeof(T);
 if(can_seek(newpos)) return float_16_to_32(*reinterpret_cast<const T*>(c_str(pos)));
 position = npos;
 return R();
}

float32 binary_stream::LE_read_float32(size_type pos)
{
 typedef float32 T;
 if(fail() || !(pos < (npos - sizeof(T)))) return T();
 size_type newpos = pos + sizeof(T);
 if(can_seek(newpos)) return *reinterpret_cast<const T*>(c_str(pos));
 position = npos;
 return T();
}

float64 binary_stream::LE_read_float64(size_type pos)
{
 typedef float64 T;
 if(fail() || !(pos < (npos - sizeof(T)))) return T();
 size_type newpos = pos + sizeof(T);
 if(can_seek(newpos)) return *reinterpret_cast<const T*>(c_str(pos));
 position = npos;
 return T();
}

float32 binary_stream::BE_read_float16(void)
{
 typedef uint16 T; typedef float32 R;
 if(fail() || !(position < (npos - sizeof(T)))) return R();
 size_type oldpos = position;
 size_type newpos = position + sizeof(T);
 if(!can_seek(newpos)) { position = npos; return R(); }
 position = newpos;
 T r = *reinterpret_cast<const T*>(c_str(oldpos));
 reverse_byte_order(&r);
 return float_16_to_32(r);
}

float32 binary_stream::BE_read_float32(void)
{
 typedef float32 T;
 if(fail() || !(position < (npos - sizeof(T)))) return T();
 size_type oldpos = position;
 size_type newpos = position + sizeof(T);
 if(!can_seek(newpos)) { position = npos; return T(); }
 position = newpos;
 T r = *reinterpret_cast<const T*>(c_str(oldpos));
 reverse_byte_order(&r);
 return r;
}

float64 binary_stream::BE_read_float64(void)
{
 typedef float64 T;
 if(fail() || !(position < (npos - sizeof(T)))) return T();
 size_type oldpos = position;
 size_type newpos = position + sizeof(T);
 if(!can_seek(newpos)) { position = npos; return T(); }
 position = newpos;
 T r = *reinterpret_cast<const T*>(c_str(oldpos));
 reverse_byte_order(&r);
 return r;
}

float32 binary_stream::BE_read_float16(size_type pos)
{
 typedef uint16 T; typedef float32 R;
 if(fail() || !(pos < (npos - sizeof(T)))) return R();
 size_type newpos = pos + sizeof(T);
 if(!can_seek(newpos)) { position = npos; return R(); }
 T r = *reinterpret_cast<const T*>(c_str(pos));
 reverse_byte_order(&r);
 return float_16_to_32(r);
}

float32 binary_stream::BE_read_float32(size_type pos)
{
 typedef float32 T;
 if(fail() || !(pos < (npos - sizeof(T)))) return T();
 size_type newpos = pos + sizeof(T);
 if(!can_seek(newpos)) { position = npos; return T(); }
 T r = *reinterpret_cast<const T*>(c_str(pos));
 reverse_byte_order(&r);
 return r;
}

float64 binary_stream::BE_read_float64(size_type pos)
{
 typedef float64 T;
 if(fail() || !(pos < (npos - sizeof(T)))) return T();
 size_type newpos = pos + sizeof(T);
 if(!can_seek(newpos)) { position = npos; return T(); }
 T r = *reinterpret_cast<const T*>(c_str(pos));
 reverse_byte_order(&r);
 return r;
}

void binary_stream::LE_read(sint08* ptr, size_type n)
{
 typedef sint08 T;
 if(fail() || !ptr || !n) return;
 size_type offset = n*sizeof(T);
 size_type newpos = position + offset;
 if(!can_seek(newpos)) { position = npos; return; }
 memmove(ptr, c_pos(), offset);
 position = newpos;
}

void binary_stream::LE_read(sint16* ptr, size_type n)
{
 typedef sint16 T;
 if(fail() || !ptr || !n) return;
 size_type offset = n*sizeof(T);
 size_type newpos = position + offset;
 if(!can_seek(newpos)) { position = npos; return; }
 memmove(ptr, c_pos(), offset);
 position = newpos;
}

void binary_stream::LE_read(sint32* ptr, size_type n)
{
 typedef sint32 T;
 if(fail() || !ptr || !n) return;
 size_type offset = n*sizeof(T);
 size_type newpos = position + offset;
 if(!can_seek(newpos)) { position = npos; return; }
 memmove(ptr, c_pos(), offset);
 position = newpos;
}

void binary_stream::LE_read(sint64* ptr, size_type n)
{
 typedef sint64 T;
 if(fail() || !ptr || !n) return;
 size_type offset = n*sizeof(T);
 size_type newpos = position + offset;
 if(!can_seek(newpos)) { position = npos; return; }
 memmove(ptr, c_pos(), offset);
 position = newpos;
}

void binary_stream::LE_read(sint08* ptr, size_type n, size_type pos)
{
 typedef sint08 T;
 if(fail() || !ptr || !n) return;
 size_type offset = n*sizeof(T);
 size_type newpos = position + offset;
 if(!can_move(newpos)) { position = npos; return; }
 memmove(ptr, c_str(pos), offset);
}

void binary_stream::LE_read(sint16* ptr, size_type n, size_type pos)
{
 typedef sint16 T;
 if(fail() || !ptr || !n) return;
 size_type offset = n*sizeof(T);
 size_type newpos = position + offset;
 if(!can_move(newpos)) { position = npos; return; }
 memmove(ptr, c_str(pos), offset);
}

void binary_stream::LE_read(sint32* ptr, size_type n, size_type pos)
{
 typedef sint32 T;
 if(fail() || !ptr || !n) return;
 size_type offset = n*sizeof(T);
 size_type newpos = position + offset;
 if(!can_move(newpos)) { position = npos; return; }
 memmove(ptr, c_str(pos), offset);
}

void binary_stream::LE_read(sint64* ptr, size_type n, size_type pos)
{
 typedef sint64 T;
 if(fail() || !ptr || !n) return;
 size_type offset = n*sizeof(T);
 size_type newpos = position + offset;
 if(!can_move(newpos)) { position = npos; return; }
 memmove(ptr, c_str(pos), offset);
}

void binary_stream::BE_read(sint08* ptr, size_type n)
{
}

void binary_stream::BE_read(sint16* ptr, size_type n)
{
}

void binary_stream::BE_read(sint32* ptr, size_type n)
{
}

void binary_stream::BE_read(sint64* ptr, size_type n)
{
}

void binary_stream::BE_read(sint08* ptr, size_type n, size_type pos)
{
}

void binary_stream::BE_read(sint16* ptr, size_type n, size_type pos)
{
}

void binary_stream::BE_read(sint32* ptr, size_type n, size_type pos)
{
}

void binary_stream::BE_read(sint64* ptr, size_type n, size_type pos)
{
}

void binary_stream::LE_read(uint08* ptr, size_type n)
{
 typedef uint08 T;
 if(fail() || !ptr || !n) return;
 size_type offset = n*sizeof(T);
 size_type newpos = position + offset;
 if(!can_seek(newpos)) { position = npos; return; }
 memmove(ptr, c_pos(), offset);
 position = newpos;
}

void binary_stream::LE_read(uint16* ptr, size_type n)
{
 typedef uint16 T;
 if(fail() || !ptr || !n) return;
 size_type offset = n*sizeof(T);
 size_type newpos = position + offset;
 if(!can_seek(newpos)) { position = npos; return; }
 memmove(ptr, c_pos(), offset);
 position = newpos;
}

void binary_stream::LE_read(uint32* ptr, size_type n)
{
 typedef uint32 T;
 if(fail() || !ptr || !n) return;
 size_type offset = n*sizeof(T);
 size_type newpos = position + offset;
 if(!can_seek(newpos)) { position = npos; return; }
 memmove(ptr, c_pos(), offset);
 position = newpos;
}

void binary_stream::LE_read(uint64* ptr, size_type n)
{
 typedef uint64 T;
 if(fail() || !ptr || !n) return;
 size_type offset = n*sizeof(T);
 size_type newpos = position + offset;
 if(!can_seek(newpos)) { position = npos; return; }
 memmove(ptr, c_pos(), offset);
 position = newpos;
}

void binary_stream::LE_read(uint08* ptr, size_type n, size_type pos)
{
 // validate arguments
 typedef uint08 T;
 if(fail() || !ptr || !n) return;

 // compute offset
 size_type offset = n*sizeof(T);
 if(!(position < npos - offset)) { position = npos; return; }

 // compute newpos
 size_type newpos = position + offset;
 if(!can_seek(newpos)) { position = npos; return; }

 // copy data from current position
 memmove(ptr, c_pos(), offset);
 position = newpos;
}

void binary_stream::LE_read(uint16* ptr, size_type n, size_type pos)
{
 typedef uint16 T;
 if(fail() || !ptr || !n) return;
 size_type offset = n*sizeof(T);
 if(!(position < npos - offset)) { position = npos; return; }
 size_type newpos = position + offset;
 if(!can_seek(newpos)) { position = npos; return; }
 memmove(ptr, c_pos(), offset);
 position = newpos;
}

void binary_stream::LE_read(uint32* ptr, size_type n, size_type pos)
{
 typedef uint32 T;
 if(fail() || !ptr || !n) return;
 size_type offset = n*sizeof(T);
 if(!(position < npos - offset)) { position = npos; return; }
 size_type newpos = position + offset;
 if(!can_seek(newpos)) { position = npos; return; }
 memmove(ptr, c_pos(), offset);
 position = newpos;
}

void binary_stream::LE_read(uint64* ptr, size_type n, size_type pos)
{
 typedef uint64 T;
 if(fail() || !ptr || !n) return;
 size_type offset = n*sizeof(T);
 if(!(position < npos - offset)) { position = npos; return; }
 size_type newpos = position + offset;
 if(!can_seek(newpos)) { position = npos; return; }
 memmove(ptr, c_pos(), offset);
 position = newpos;
}

void binary_stream::BE_read(uint08* ptr, size_type n)
{
 LE_read(ptr, n);
 if(good()) reverse_byte_order(ptr, n);
}

void binary_stream::BE_read(uint16* ptr, size_type n)
{
 LE_read(ptr, n);
 if(good()) reverse_byte_order(ptr, n);
}

void binary_stream::BE_read(uint32* ptr, size_type n)
{
 LE_read(ptr, n);
 if(good()) reverse_byte_order(ptr, n);
}

void binary_stream::BE_read(uint64* ptr, size_type n)
{
 LE_read(ptr, n);
 if(good()) reverse_byte_order(ptr, n);
}

void binary_stream::BE_read(uint08* ptr, size_type n, size_type pos)
{
 LE_read(ptr, n, pos);
 if(good()) reverse_byte_order(ptr, n);
}

void binary_stream::BE_read(uint16* ptr, size_type n, size_type pos)
{
 LE_read(ptr, n, pos);
 if(good()) reverse_byte_order(ptr, n);
}

void binary_stream::BE_read(uint32* ptr, size_type n, size_type pos)
{
 LE_read(ptr, n, pos);
 if(good()) reverse_byte_order(ptr, n);
}

void binary_stream::BE_read(uint64* ptr, size_type n, size_type pos)
{
 LE_read(ptr, n, pos);
 if(good()) reverse_byte_order(ptr, n);
}

void binary_stream::LE_read(float32* ptr, size_type n)
{
 // validate arguments
 typedef float32 T;
 if(fail() || !ptr || !n) return;

 // compute offset
 size_type offset = n*sizeof(T);
 if(!(position < npos - offset)) { position = npos; return; }

 // compute newpos
 size_type newpos = position + offset;
 if(!can_seek(newpos)) { position = npos; return; }

 // copy data from current position
 memmove(ptr, c_pos(), offset);
 position = newpos;
}

void binary_stream::LE_read(float64* ptr, size_type n)
{
 typedef float64 T;
 if(fail() || !ptr || !n) return;
 size_type offset = n*sizeof(T);
 if(!(position < npos - offset)) { position = npos; return; }
 size_type newpos = position + offset;
 if(!can_seek(newpos)) { position = npos; return; }
 memmove(ptr, c_pos(), offset);
 position = newpos;
}

void binary_stream::LE_read(float32* ptr, size_type n, size_type pos)
{
 // validate arguments
 typedef float32 T;
 if(fail() || !ptr || !n) return;

 // compute offset
 size_type offset = n*sizeof(T);
 if(!(pos < npos - offset)) { position = npos; return; }

 // compute newpos
 size_type newpos = pos + offset;
 if(!can_seek(newpos)) { position = npos; return; }

 // copy data from selected position
 memmove(ptr, c_str(pos), offset);
}

void binary_stream::LE_read(float64* ptr, size_type n, size_type pos)
{
 typedef float64 T;
 if(fail() || !ptr || !n) return;
 size_type offset = n*sizeof(T);
 if(!(pos < npos - offset)) { position = npos; return; }
 size_type newpos = pos + offset;
 if(!can_seek(newpos)) { position = npos; return; }
 memmove(ptr, c_str(pos), offset);
}

void binary_stream::BE_read(float32* ptr, size_type n)
{
 LE_read(ptr, n);
 if(good()) reverse_byte_order(ptr, n);
}

void binary_stream::BE_read(float64* ptr, size_type n)
{
 LE_read(ptr, n);
 if(good()) reverse_byte_order(ptr, n);
}

void binary_stream::BE_read(float32* ptr, size_type n, size_type pos)
{
 LE_read(ptr, n, pos);
 if(good()) reverse_byte_order(ptr, n);
}

void binary_stream::BE_read(float64* ptr, size_type n, size_type pos)
{
 LE_read(ptr, n, pos);
 if(good()) reverse_byte_order(ptr, n);
}

void binary_stream::LE_read_float16(float32* ptr, size_type n)
{
 // validate arguments
 size_type typesize = sizeof(uint16);
 if(fail() || !ptr || !n) return;

 // compute offset
 size_type offset = n*typesize;
 if(!(position < npos - offset)) { position = npos; return; }

 // compute newpos
 size_type newpos = position + offset;
 if(!can_seek(newpos)) { position = npos; return; }

 // copy data from current position
 for(size_type i = 0; i < n; i++) ptr[i] = float_16_to_32(*reinterpret_cast<const uint16*>(c_str(position + i*typesize)));
 position = newpos;
}

void binary_stream::LE_read_float16(float64* ptr, size_type n)
{
 size_type typesize = sizeof(uint16);
 if(fail() || !ptr || !n) return;
 size_type offset = n*typesize;
 if(!(position < npos - offset)) { position = npos; return; }
 size_type newpos = position + offset;
 if(!can_seek(newpos)) { position = npos; return; }
 for(size_type i = 0; i < n; i++) ptr[i] = float_16_to_32(*reinterpret_cast<const uint16*>(c_str(position + i*typesize)));
 position = newpos;
}

void binary_stream::LE_read_float16(float32* ptr, size_type n, size_type pos)
{
 // validate arguments
 size_type typesize = sizeof(uint16);
 if(fail() || !ptr || !n) return;

 // compute offset
 size_type offset = n*typesize;
 if(!(pos < npos - offset)) { position = npos; return; }

 // compute newpos
 size_type newpos = pos + offset;
 if(!can_seek(newpos)) { position = npos; return; }

 // copy data from selected position
 for(size_type i = 0; i < n; i++) ptr[i] = float_16_to_32(*reinterpret_cast<const uint16*>(c_str(pos + i*typesize)));
}

void binary_stream::LE_read_float16(float64* ptr, size_type n, size_type pos)
{
 size_type typesize = sizeof(uint16);
 if(fail() || !ptr || !n) return;
 size_type offset = n*typesize;
 if(!(pos < npos - offset)) { position = npos; return; }
 size_type newpos = pos + offset;
 if(!can_seek(newpos)) { position = npos; return; }
 for(size_type i = 0; i < n; i++) ptr[i] = float_16_to_32(*reinterpret_cast<const uint16*>(c_str(pos + i*typesize)));
}

void binary_stream::BE_read_float16(float32* ptr, size_type n)
{
 // validate arguments
 size_type typesize = sizeof(uint16);
 if(fail() || !ptr || !n) return;

 // compute offset
 size_type offset = n*typesize;
 if(!(position < npos - offset)) { position = npos; return; }

 // compute newpos
 size_type newpos = position + offset;
 if(!can_seek(newpos)) { position = npos; return; }

 // copy data from current position
 for(size_type i = 0; i < n; i++) {
     uint16 temp = *reinterpret_cast<const uint16*>(c_str(position + i*typesize));
     reverse_byte_order(&temp);
     ptr[i] = float_16_to_32(temp);
    }

 // move to newpos
 position = newpos;
}

void binary_stream::BE_read_float16(float64* ptr, size_type n)
{
 size_type typesize = sizeof(uint16);
 if(fail() || !ptr || !n) return;
 size_type offset = n*typesize;
 if(!(position < npos - offset)) { position = npos; return; }
 size_type newpos = position + offset;
 if(!can_seek(newpos)) { position = npos; return; }
 for(size_type i = 0; i < n; i++) {
     uint16 temp = *reinterpret_cast<const uint16*>(c_str(position + i*typesize));
     reverse_byte_order(&temp);
     ptr[i] = float_16_to_32(temp);
    }
 position = newpos;
}

void binary_stream::BE_read_float16(float32* ptr, size_type n, size_type pos)
{
 // validate arguments
 size_type typesize = sizeof(uint16);
 if(fail() || !ptr || !n) return;

 // compute offset
 size_type offset = n*typesize;
 if(!(pos < npos - offset)) { position = npos; return; }

 // compute newpos
 size_type newpos = pos + offset;
 if(!can_seek(newpos)) { position = npos; return; }

 // copy data from selected position
 for(size_type i = 0; i < n; i++) {
     uint16 temp = *reinterpret_cast<const uint16*>(c_str(pos + i*typesize));
     reverse_byte_order(&temp);
     ptr[i] = float_16_to_32(temp);
    }
}

void binary_stream::BE_read_float16(float64* ptr, size_type n, size_type pos)
{
 size_type typesize = sizeof(uint16);
 if(fail() || !ptr || !n) return;
 size_type offset = n*typesize;
 if(!(pos < npos - offset)) { position = npos; return; }
 size_type newpos = pos + offset;
 if(!can_seek(newpos)) { position = npos; return; }
 for(size_type i = 0; i < n; i++) {
     uint16 temp = *reinterpret_cast<const uint16*>(c_str(pos + i*typesize));
     reverse_byte_order(&temp);
     ptr[i] = float_16_to_32(temp);
    }
}