#ifndef __XENTAX_STREAM_H
#define __XENTAX_STREAM_H

class binary_stream {
 public :
  typedef boost::shared_array<char> data_type;
  typedef size_t size_type;
  typedef ptrdiff_t diff_type;
  static const size_type npos;
 private :
  data_type data;
  size_type elem;
  size_type position;
 public :
  size_type size(void)const { return elem; }
  const char* c_str(void)const { return data.get(); }
  const char* c_str(size_type pos)const { return data.get() + pos; }
  const char* c_pos(void)const { return data.get() + position; }
  size_type tell(void)const { return position; }
  bool at_begin(void)const { return position == 0; }
  bool at_end(void)const { return position == elem; }
  bool can_seek(size_type pos)const { return ((position != npos) && !(elem < pos)); }
  bool can_move(diff_type pos)const { return ((position != npos) && (pos != npos) && !(pos < 0 ? (position < (size_type)std::abs(pos)) : (elem < (position + pos)))); }
  bool fail(void)const { return position == npos; }
  bool good(void)const { return position != npos; }
 public :
  void seek(size_type pos);
  void seek_reverse(size_type pos);
  void move(diff_type pos);
  void move(diff_type pos, size_type from);
  void reset(void);
 public :
  size_type search(const char* pattern, size_type n, size_t from = 0);
 public :
  void read(char* ptr, size_type n);
  void read_reverse(char* ptr, size_type n);
  std::string read_string(void);
 public :
  sint08 LE_read_sint08(void);
  uint08 LE_read_uint08(void);
  sint16 LE_read_sint16(void);
  uint16 LE_read_uint16(void);
  sint32 LE_read_sint32(void);
  uint32 LE_read_uint32(void);
  sint64 LE_read_sint64(void);
  uint64 LE_read_uint64(void);
  sint08 LE_read_sint08(size_type pos);
  uint08 LE_read_uint08(size_type pos);
  sint16 LE_read_sint16(size_type pos);
  uint16 LE_read_uint16(size_type pos);
  sint32 LE_read_sint32(size_type pos);
  uint32 LE_read_uint32(size_type pos);
  sint64 LE_read_sint64(size_type pos);
  uint64 LE_read_uint64(size_type pos);
 public :
  sint08 BE_read_sint08(void);
  uint08 BE_read_uint08(void);
  sint16 BE_read_sint16(void);
  uint16 BE_read_uint16(void);
  sint32 BE_read_sint32(void);
  uint32 BE_read_uint32(void);
  sint64 BE_read_sint64(void);
  uint64 BE_read_uint64(void);
  sint08 BE_read_sint08(size_type pos);
  uint08 BE_read_uint08(size_type pos);
  sint16 BE_read_sint16(size_type pos);
  uint16 BE_read_uint16(size_type pos);
  sint32 BE_read_sint32(size_type pos);
  uint32 BE_read_uint32(size_type pos);
  sint64 BE_read_sint64(size_type pos);
  uint64 BE_read_uint64(size_type pos);
 public :
  real32 LE_read_real16(void);
  real32 LE_read_real32(void);
  real64 LE_read_real64(void);
  real32 LE_read_real16(size_type pos);
  real32 LE_read_real32(size_type pos);
  real64 LE_read_real64(size_type pos);
 public :
  real32 BE_read_real16(void);
  real32 BE_read_real32(void);
  real64 BE_read_real64(void);
  real32 BE_read_real16(size_type pos);
  real32 BE_read_real32(size_type pos);
  real64 BE_read_real64(size_type pos);
 public :
  void LE_read_array(sint08* ptr, size_type n);
  void LE_read_array(sint16* ptr, size_type n);
  void LE_read_array(sint32* ptr, size_type n);
  void LE_read_array(sint64* ptr, size_type n);
  void LE_read_array(sint08* ptr, size_type n, size_type pos);
  void LE_read_array(sint16* ptr, size_type n, size_type pos);
  void LE_read_array(sint32* ptr, size_type n, size_type pos);
  void LE_read_array(sint64* ptr, size_type n, size_type pos);
 public :
  void BE_read_array(sint08* ptr, size_type n);
  void BE_read_array(sint16* ptr, size_type n);
  void BE_read_array(sint32* ptr, size_type n);
  void BE_read_array(sint64* ptr, size_type n);
  void BE_read_array(sint08* ptr, size_type n, size_type pos);
  void BE_read_array(sint16* ptr, size_type n, size_type pos);
  void BE_read_array(sint32* ptr, size_type n, size_type pos);
  void BE_read_array(sint64* ptr, size_type n, size_type pos);
 public :
  void LE_read_array(uint08* ptr, size_type n);
  void LE_read_array(uint16* ptr, size_type n);
  void LE_read_array(uint32* ptr, size_type n);
  void LE_read_array(uint64* ptr, size_type n);
  void LE_read_array(uint08* ptr, size_type n, size_type pos);
  void LE_read_array(uint16* ptr, size_type n, size_type pos);
  void LE_read_array(uint32* ptr, size_type n, size_type pos);
  void LE_read_array(uint64* ptr, size_type n, size_type pos);
 public :
  void BE_read_array(uint08* ptr, size_type n);
  void BE_read_array(uint16* ptr, size_type n);
  void BE_read_array(uint32* ptr, size_type n);
  void BE_read_array(uint64* ptr, size_type n);
  void BE_read_array(uint08* ptr, size_type n, size_type pos);
  void BE_read_array(uint16* ptr, size_type n, size_type pos);
  void BE_read_array(uint32* ptr, size_type n, size_type pos);
  void BE_read_array(uint64* ptr, size_type n, size_type pos);
 public :
  void LE_read_array(real32* ptr, size_type n);
  void LE_read_array(real64* ptr, size_type n);
  void LE_read_array(real32* ptr, size_type n, size_type pos);
  void LE_read_array(real64* ptr, size_type n, size_type pos);
 public :
  void BE_read_array(real32* ptr, size_type n);
  void BE_read_array(real64* ptr, size_type n);
  void BE_read_array(real32* ptr, size_type n, size_type pos);
  void BE_read_array(real64* ptr, size_type n, size_type pos);
 public :
  void LE_read_real16_array(real32* ptr, size_type n);
  void LE_read_real16_array(real64* ptr, size_type n);
  void LE_read_real16_array(real32* ptr, size_type n, size_type pos);
  void LE_read_real16_array(real64* ptr, size_type n, size_type pos);
 public :
  void BE_read_real16_array(real32* ptr, size_type n);
  void BE_read_real16_array(real64* ptr, size_type n);
  void BE_read_real16_array(real32* ptr, size_type n, size_type pos);
  void BE_read_real16_array(real64* ptr, size_type n, size_type pos);
 public :
  binary_stream& operator =(const binary_stream& bs);
 public :
  binary_stream();
  binary_stream(const binary_stream& bs);
  binary_stream(const boost::shared_array<char>& stream, size_type n);
 ~binary_stream();
};

#endif
