Contents Functions Classes Topics User Forum CVS

BinaryInput.h

Go to the documentation of this file.
00001 
00013 #ifndef G3D_BINARYINPUT_H
00014 #define G3D_BINARYINPUT_H
00015 
00016 #ifdef _MSC_VER
00017 // Disable conditional expression is constant, which occurs incorrectly on inlined functions
00018 #   pragma  warning(push)
00019 #   pragma warning( disable : 4127 )
00020 
00021 // signed/unsigned warnings (TODO: revisit)
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     // Allow writing of integers to non-word aligned locations.
00047     // This is legal on x86, but not on other platforms.
00048     #define G3D_ALLOW_UNALIGNED_WRITES
00049 #endif
00050 
00071 class BinaryInput {
00072 private:
00073 
00074     // The initial buffer will be no larger than this, but 
00075     // may grow if a large memory read occurs.  50 MB
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     // Not implemented on purpose, don't use
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

Generated on Mon Jul 17 11:50:41 2006 for G3D by doxygen 1.4.5
Hosted by SourceForge.net Logo