#if !defined(__OBJSTRM_H)
#define __OBJSTRM_H

#if !defined(__STDIO_H)
#include <stdio.h>
#endif

#if !defined(int32)
#define int8	char
#define uint8	unsigned char
#define int16	short
#define uint16	unsigned short
#define int32	int
#define uint32	unsigned int
#endif

class TStreamableBase;
class ipstream;
class opstream;

class TStreamableBase {
 protected:
  virtual void* read(ipstream&, uint32=0) = 0;
  virtual void write(opstream&) const = 0;
  
 private:
  virtual const char* streamableName () const = 0;
  
  friend ipstream;
  friend opstream;
};

class ipstream {
 public:
  ipstream(const char *fName);
  ~ipstream();
  void close();
  
  inline int good() { 
    return stream ? 1 : 0; 
  }
  
  uint16 readWord16();
  uint32 readWord32();
  
  float readSingle();
  double readDouble();
  
  char* readString();
  char* readString(char* buf, unsigned maxLen);
  
  TStreamableBase* readObject();
  TStreamableBase* readObject(TStreamableBase&);
  
 protected:
  FILE* stream;
};

class opstream {
 public:
  opstream(const char *filename);
  ~opstream();
  void close();
  
  inline int good() { 
    return stream ? 1 : 0; 
  }

  inline void writeWord16(uint16 value) {
    fwrite(&value, 2, 1, stream); 
  }
  inline void writeWord32(uint32 value) {
    fwrite(&value, 4, 1, stream); 
  }
  
  inline void writeSingle(float value) {
    fwrite(&value, 4, 1, stream); 
  }
  inline void writeDouble(double value) {
    fwrite(&value, 8, 1, stream); 
  }
  
  void writeString(const char*);
  
  void writeObject(const TStreamableBase *t, int isPtr=0);
  
  inline void writeObject(const TStreamableBase &t, int isPtr=0) {
    writeObject(&t); 
  }
  
 protected:
  FILE* stream;
};

#endif
