00001
00013 #ifndef G3D_BINARYINPUT_H
00014 #define G3D_BINARYINPUT_H
00015
00016 #ifdef _MSC_VER
00017
00018 # pragma warning(push)
00019 # pragma warning( disable : 4127 )
00020
00021
00022 # pragma warning (disable:4267)
00023 #endif
00024
00025 #include <assert.h>
00026 #include <string>
00027 #include <vector>
00028 #include <sys/stat.h>
00029 #include <sys/types.h>
00030 #include <stdio.h>
00031 #include "G3D/platform.h"
00032 #include "G3D/Array.h"
00033 #include "G3D/Color4.h"
00034 #include "G3D/Color3.h"
00035 #include "G3D/Vector4.h"
00036 #include "G3D/Vector3.h"
00037 #include "G3D/Vector2.h"
00038 #include "G3D/g3dmath.h"
00039 #include "G3D/debug.h"
00040 #include "G3D/System.h"
00041
00042
00043 namespace G3D {
00044
00045 #if defined(G3D_WIN32) || defined(G3D_LINUX)
00046
00047
00048 #define G3D_ALLOW_UNALIGNED_WRITES
00049 #endif
00050
00071 class BinaryInput {
00072 private:
00073
00074
00075
00076 enum {INITIAL_BUFFER_LENGTH = 50000000};
00077
00081 G3DEndian fileEndian;
00082 std::string filename;
00083
00084 bool swapBytes;
00085
00087 int bitPos;
00088
00093 uint32 bitString;
00094
00096 int beginEndBits;
00097
00101 size_t alreadyRead;
00102
00107 int length;
00108
00110 int bufferLength;
00111 uint8* buffer;
00112
00116 int pos;
00117
00121 bool freeBuffer;
00122
00125 void loadIntoMemory(int startPosition, int minLength = 0);
00126
00128 inline void prepareToRead(size_t bytes) {
00129 debugAssertM((int)pos + (int)bytes + (int)alreadyRead <= (int)length, "Read past end of file.");
00130
00131 if ((int)pos + (int)bytes > (int)bufferLength) {
00132 loadIntoMemory((int)pos + (int)alreadyRead, (int)bytes);
00133 }
00134 }
00135
00136
00137 BinaryInput(const BinaryInput&);
00138 BinaryInput& operator=(const BinaryInput&);
00139 bool operator==(const BinaryInput&);
00140
00141 public:
00142
00144 static const bool NO_COPY;
00145
00149 BinaryInput(
00150 const std::string& filename,
00151 G3DEndian fileEndian,
00152 bool compressed = false);
00153
00175 BinaryInput(
00176 const uint8* data,
00177 int dataLen,
00178 G3DEndian dataEndian,
00179 bool compressed = false,
00180 bool copyMemory = true);
00181
00182 virtual ~BinaryInput();
00183
00184
00185 std::string getFilename() const {
00186 return filename;
00187 }
00188
00193 const uint8* getCArray() const {
00194 if (alreadyRead > 0) {
00195 throw "Cannot getCArray for a huge file";
00196 }
00197 return buffer;
00198 }
00199
00206 inline const uint8 operator[](int n) {
00207 setPosition(n);
00208 return readUInt8();
00209 }
00210
00214 inline int getLength() const {
00215 return length;
00216 }
00217
00218 inline int size() const {
00219 return getLength();
00220 }
00221
00226 inline int getPosition() const {
00227 return (int)pos + (int)alreadyRead;
00228 }
00229
00234 inline void setPosition(int p) {
00235 debugAssertM(p <= length, "Read past end of file");
00236 pos = (int)p - (int)alreadyRead;
00237 if ((pos < 0) || (pos > bufferLength)) {
00238 loadIntoMemory((int)pos + (int)alreadyRead);
00239 }
00240 }
00241
00245 inline void reset() {
00246 setPosition(0);
00247 }
00248
00249 inline int8 readInt8() {
00250 prepareToRead(1);
00251 return buffer[pos++];
00252 }
00253
00254 inline bool readBool8() {
00255 return (readInt8() != 0);
00256 }
00257
00258 inline uint8 readUInt8() {
00259 prepareToRead(1);
00260 return ((uint8*)buffer)[pos++];
00261 }
00262
00263 uint16 inline readUInt16() {
00264 prepareToRead(2);
00265
00266 pos += 2;
00267 if (swapBytes) {
00268 uint8 out[2];
00269 out[0] = buffer[pos - 1];
00270 out[1] = buffer[pos - 2];
00271 return *(uint16*)out;
00272 } else {
00273 #ifdef G3D_ALLOW_UNALIGNED_WRITES
00274 return *(uint16*)(&buffer[pos - 2]);
00275 #else
00276 uint8 out[2];
00277 out[0] = buffer[pos - 2];
00278 out[1] = buffer[pos - 1];
00279 return *(uint16*)out;
00280 #endif
00281 }
00282
00283 }
00284
00285 inline int16 readInt16() {
00286 uint16 a = readUInt16();
00287 return *(int16*)&a;
00288 }
00289
00290 inline uint32 readUInt32() {
00291 prepareToRead(4);
00292
00293 pos += 4;
00294 if (swapBytes) {
00295 uint8 out[4];
00296 out[0] = buffer[pos - 1];
00297 out[1] = buffer[pos - 2];
00298 out[2] = buffer[pos - 3];
00299 out[3] = buffer[pos - 4];
00300 return *(uint32*)out;
00301 } else {
00302 #ifdef G3D_ALLOW_UNALIGNED_WRITES
00303 return *(uint32*)(&buffer[pos - 4]);
00304 #else
00305 uint8 out[4];
00306 out[0] = buffer[pos - 4];
00307 out[1] = buffer[pos - 3];
00308 out[2] = buffer[pos - 2];
00309 out[3] = buffer[pos - 1];
00310 return *(uint32*)out;
00311 #endif
00312 }
00313 }
00314
00315
00316 inline int32 readInt32() {
00317 uint32 a = readUInt32();
00318 return *(int32*)&a;
00319 }
00320
00321 uint64 readUInt64();
00322
00323 inline int64 readInt64() {
00324 uint64 a = readUInt64();
00325 return *(int64*)&a;
00326 }
00327
00328 inline float32 readFloat32() {
00329 uint32 a = readUInt32();
00330 return *(float32*)&a;
00331 }
00332
00333 inline float64 readFloat64() {
00334 uint64 a = readUInt64();
00335 return *(float64*)&a;
00336 }
00337
00342 void readBytes(int n, void* bytes);
00343
00347 inline void readBytes(void* bytes, int n) {
00348 readBytes(n, bytes);
00349 }
00350
00356 std::string readString(int n);
00357
00361 std::string readString();
00362
00368 std::string readStringEven();
00369
00370
00371 std::string readString32();
00372
00373 Vector4 readVector4();
00374 Vector3 readVector3();
00375 Vector2 readVector2();
00376
00377 Color4 readColor4();
00378 Color3 readColor3();
00379
00383 inline void skip(int n) {
00384 setPosition((int)pos + (int)alreadyRead + n);
00385 }
00386
00390 inline bool hasMore() const {
00391 return (int)pos + (int)alreadyRead < (int)length;
00392 }
00393
00397 void beginBits();
00398
00400 uint32 readBits(int numBits);
00401
00403 void endBits();
00404
00405 # define DECLARE_READER(ucase, lcase)\
00406 void read##ucase(lcase* out, int n);\
00407 void read##ucase(std::vector<lcase>& out, int n);\
00408 void read##ucase(Array<lcase>& out, int n);
00409
00410 DECLARE_READER(Bool8, bool)
00411 DECLARE_READER(UInt8, uint8)
00412 DECLARE_READER(Int8, int8)
00413 DECLARE_READER(UInt16, uint16)
00414 DECLARE_READER(Int16, int16)
00415 DECLARE_READER(UInt32, uint32)
00416 DECLARE_READER(Int32, int32)
00417 DECLARE_READER(UInt64, uint64)
00418 DECLARE_READER(Int64, int64)
00419 DECLARE_READER(Float32, float32)
00420 DECLARE_READER(Float64, float64)
00421 # undef DECLARE_READER
00422 };
00423
00424
00425 }
00426
00427 #endif
00428
00429 #ifdef _MSC_VER
00430 # pragma warning(pop)
00431 #endif