1 // This code is in the public domain -- castanyo@yahoo.es
2 
3 #ifndef NVCORE_STREAM_H
4 #define NVCORE_STREAM_H
5 
6 #include <nvcore/nvcore.h>
7 #include <nvcore/Debug.h>
8 
9 namespace nv
10 {
11 
12 /// Base stream class.
13 class NVCORE_CLASS Stream {
14 public:
15 
16 	enum ByteOrder {
17 		LittleEndian = false,
18 		BigEndian = true,
19 	};
20 
21 	/// Get the byte order of the system.
getSystemByteOrder()22 	static ByteOrder getSystemByteOrder() {
23 #	if NV_LITTLE_ENDIAN
24 		return LittleEndian;
25 #	else
26 		return BigEndian;
27 #	endif
28 	}
29 
30 
31 	/// Ctor.
Stream()32 	Stream() : m_byteOrder(LittleEndian) { }
33 
34 	/// Virtual destructor.
~Stream()35 	virtual ~Stream() {}
36 
37 	/// Set byte order.
setByteOrder(ByteOrder bo)38 	void setByteOrder(ByteOrder bo) { m_byteOrder = bo; }
39 
40 	/// Get byte order.
byteOrder()41 	ByteOrder byteOrder() const { return m_byteOrder; }
42 
43 
44 	/// Serialize the given data.
45 	virtual uint serialize( void * data, uint len ) = 0;
46 
47 	/// Move to the given position in the archive.
48 	virtual void seek( uint pos ) = 0;
49 
50 	/// Return the current position in the archive.
51 	virtual uint tell() const = 0;
52 
53 	/// Return the current size of the archive.
54 	virtual uint size() const = 0;
55 
56 	/// Determine if there has been any error.
57 	virtual bool isError() const = 0;
58 
59 	/// Clear errors.
60 	virtual void clearError() = 0;
61 
62 	/// Return true if the stream is at the end.
63 	virtual bool isAtEnd() const = 0;
64 
65 	/// Return true if the stream is seekable.
66 	virtual bool isSeekable() const = 0;
67 
68 	/// Return true if this is an input stream.
69 	virtual bool isLoading() const = 0;
70 
71 	/// Return true if this is an output stream.
72 	virtual bool isSaving() const = 0;
73 
74 
75 	// friends
76 	friend Stream & operator<<( Stream & s, bool & c ) {
77 #	if NV_OS_DARWIN
78 		nvStaticCheck(sizeof(bool) == 4);
79 		uint8 b = c ? 1 : 0;
80 		s.serialize( &b, 1 );
81 		c = (b == 1);
82 #	else
83 		nvStaticCheck(sizeof(bool) == 1);
84 		s.serialize( &c, 1 );
85 #	endif
86 		return s;
87 	}
88 	friend Stream & operator<<( Stream & s, char & c ) {
89 		nvStaticCheck(sizeof(char) == 1);
90 		s.serialize( &c, 1 );
91 		return s;
92 	}
93 	friend Stream & operator<<( Stream & s, uint8 & c ) {
94 		nvStaticCheck(sizeof(uint8) == 1);
95 		s.serialize( &c, 1 );
96 		return s;
97 	}
98 	friend Stream & operator<<( Stream & s, int8 & c ) {
99 		nvStaticCheck(sizeof(int8) == 1);
100 		s.serialize( &c, 1 );
101 		return s;
102 	}
103 	friend Stream & operator<<( Stream & s, uint16 & c ) {
104 		nvStaticCheck(sizeof(uint16) == 2);
105 		return s.byteOrderSerialize( &c, 2 );
106 	}
107 	friend Stream & operator<<( Stream & s, int16 & c ) {
108 		nvStaticCheck(sizeof(int16) == 2);
109 		return s.byteOrderSerialize( &c, 2 );
110 	}
111 	friend Stream & operator<<( Stream & s, uint32 & c ) {
112 		nvStaticCheck(sizeof(uint32) == 4);
113 		return s.byteOrderSerialize( &c, 4 );
114 	}
115 	friend Stream & operator<<( Stream & s, int32 & c ) {
116 		nvStaticCheck(sizeof(int32) == 4);
117 		return s.byteOrderSerialize( &c, 4 );
118 	}
119 	friend Stream & operator<<( Stream & s, uint64 & c ) {
120 		nvStaticCheck(sizeof(uint64) == 8);
121 		return s.byteOrderSerialize( &c, 8 );
122 	}
123 	friend Stream & operator<<( Stream & s, int64 & c ) {
124 		nvStaticCheck(sizeof(int64) == 8);
125 		return s.byteOrderSerialize( &c, 8 );
126 	}
127 	friend Stream & operator<<( Stream & s, float & c ) {
128 		nvStaticCheck(sizeof(float) == 4);
129 		return s.byteOrderSerialize( &c, 4 );
130 	}
131 	friend Stream & operator<<( Stream & s, double & c ) {
132 		nvStaticCheck(sizeof(double) == 8);
133 		return s.byteOrderSerialize( &c, 8 );
134 	}
135 
136 protected:
137 
138 	/// Serialize in the stream byte order.
byteOrderSerialize(void * v,uint len)139 	Stream & byteOrderSerialize( void * v, uint len ) {
140 		if( m_byteOrder == getSystemByteOrder() ) {
141 			serialize( v, len );
142 		}
143 		else {
144 			for( uint i = len; i > 0; i-- ) {
145 				serialize( (uint8 *)v + i - 1, 1 );
146 			}
147 		}
148 		return *this;
149 	}
150 
151 
152 private:
153 
154 	ByteOrder m_byteOrder;
155 
156 };
157 
158 } // nv namespace
159 
160 #endif // NV_STREAM_H
161