#ifndef _COUTPUTSTREAM #define _COUTPUTSTREAM #include "types.h" #include "stddef.h" class COutputStream; template < typename T > void coutput_stream_helper(const T& t, COutputStream& out); class COutputStream { public: COutputStream(int len); virtual ~COutputStream(); virtual void Write(const void* ptr, size_t len) = 0; void WriteBits(uint val, uint bitCount); void DoPut(const void* ptr, size_t len); void DoFlush(); void Flush(); void FlushShiftRegister(); void Put(const void* ptr, size_t len) { FlushShiftRegister(); DoPut(ptr, len); } template < typename T > void Put(const T& t) { coutput_stream_helper(t, *this); } void WriteInt8(const schar t) { Put(t); } void WriteUint8(const uchar t) { Put(t); } void WriteInt16(const sshort t) { Put(t); } void WriteUint16(const ushort t) { Put(t); } void WriteReal32(const float t) { Put(t); } void WriteUint32(const uint t) { Put(t); } void WriteInt32(const int t) { Put(t); } void WriteShort(const short t) { Put(&t, sizeof(short)); } void WriteLong(const int t) { Put(&t, sizeof(int)); } void WriteChar(const uchar c) { FlushShiftRegister(); if (mUnwrittenLen >= mBufLen) { DoFlush(); } ++mNumWrites; *(reinterpret_cast< uchar* >(mBufPtr) + mUnwrittenLen++) = c; } uint GetWrittenBytes() const { return mNumWrites; } private: uint mUnwrittenLen; uint mBufLen; void* mBufPtr; uint mNumWrites; uint mShiftRegister; volatile uint mShiftRegisterOffset; uchar mScratch[96]; }; template < typename T > inline void coutput_stream_helper(const T& t, COutputStream& out) { t.PutTo(out); } template <> inline void coutput_stream_helper(const float& t, COutputStream& out) { int tmp = *(int*)&t; out.Put(&tmp, sizeof(float)); } template <> inline void coutput_stream_helper(const schar& t, COutputStream& out) { out.WriteChar(t); } template <> inline void coutput_stream_helper(const uchar& t, COutputStream& out) { out.WriteChar(t); } template <> inline void coutput_stream_helper(const sshort& t, COutputStream& out) { out.WriteShort(t); } template <> inline void coutput_stream_helper(const ushort& t, COutputStream& out) { out.WriteShort(t); } template <> inline void coutput_stream_helper(const int& t, COutputStream& out) { out.WriteLong(t); } template <> inline void coutput_stream_helper(const uint& t, COutputStream& out) { out.WriteLong(t); } template <> inline void coutput_stream_helper(const bool& t, COutputStream& out) { out.WriteChar(static_cast< u8 >(t)); } #endif // _COUTPUTSTREAM