From 82b60bbd176bf82863dbb75c6cc9ec708acd7ad4 Mon Sep 17 00:00:00 2001 From: leo Date: Wed, 3 Jan 2001 20:03:27 +0000 Subject: Check endianess when loading project files git-svn-id: http://svn.leocad.org/trunk@202 c7d43263-9d01-0410-8a33-9dba5d9f93d6 --- common/camera.cpp | 50 +++++++-------- common/file.cpp | 181 ++++++++++++++++++++++++++++++++++++----------------- common/file.h | 58 ++++++++--------- common/piece.cpp | 14 ++--- common/terrain.cpp | 94 ++++++++++++++-------------- 5 files changed, 231 insertions(+), 166 deletions(-) diff --git a/common/camera.cpp b/common/camera.cpp index b0d3806..0ffd218 100644 --- a/common/camera.cpp +++ b/common/camera.cpp @@ -311,8 +311,8 @@ bool Camera::FileLoad (File& file) int snapshot; // BOOL under Windows int cam; - file.Read(&snapshot, 4); - file.Read(&cam, 4); + file.ReadLong (&snapshot, 1); + file.ReadLong (&cam, 1); // if (cam == -1) // node->pCam = NULL; // else @@ -337,41 +337,41 @@ bool Camera::FileLoad (File& file) float param[4]; unsigned char type; - file.Read(&n, 4); + file.ReadLong (&n, 1); while (n--) { - file.Read(&time, 2); - file.Read(param, 12); - file.Read(&type, 1); + file.ReadShort (&time, 1); + file.ReadFloat (param, 3); + file.ReadByte (&type, 1); ChangeKey (time, false, true, param, type); } - file.Read(&n, 4); + file.ReadLong (&n, 1); while (n--) { - file.Read(&time, 2); - file.Read(param, 12); - file.Read(&type, 1); + file.ReadShort (&time, 1); + file.ReadFloat (param, 3); + file.ReadByte (&type, 1); ChangeKey (time, true, true, param, type); } } - file.Read(&m_fovy, 4); - file.Read(&m_zFar, 4); - file.Read(&m_zNear, 4); + file.ReadFloat (&m_fovy, 1); + file.ReadFloat (&m_zFar, 1); + file.ReadFloat (&m_zNear, 1); if (version < 5) { - file.Read(&n, 4); + file.ReadLong (&n, 1); if (n != 0) m_nState |= LC_CAMERA_HIDDEN; } else { - file.Read(&m_nState, 1); - file.Read(&m_nType, 1); + file.ReadByte (&m_nState, 1); + file.ReadByte (&m_nType, 1); } } @@ -380,9 +380,9 @@ bool Camera::FileLoad (File& file) unsigned long show; int user; - file.Read(&show, 4); + file.ReadLong (&show, 1); // if (version > 2) - file.Read(&user, 4); + file.ReadLong (&user, 1); if (show == 0) m_nState |= LC_CAMERA_HIDDEN; } @@ -399,15 +399,15 @@ void Camera::FileSave (File& file) const Object::FileSave (file); ch = (unsigned char)strlen(m_strName); - file.Write(&ch, 1); - file.Write(m_strName, ch); + file.Write (&ch, 1); + file.Write (m_strName, ch); - file.Write(&m_fovy, 4); - file.Write(&m_zFar, 4); - file.Write(&m_zNear, 4); + file.WriteFloat (&m_fovy, 1); + file.WriteFloat (&m_zFar, 1); + file.WriteFloat (&m_zNear, 1); // version 5 - file.Write(&m_nState, 1); - file.Write(&m_nType, 1); + file.WriteByte (&m_nState, 1); + file.WriteByte (&m_nType, 1); } ///////////////////////////////////////////////////////////////////////////// diff --git a/common/file.cpp b/common/file.cpp index 898816f..f858342 100644 --- a/common/file.cpp +++ b/common/file.cpp @@ -1,5 +1,6 @@ // File class, can be a memory file or in the disk. // Needed to work with the clipboard and undo/redo easily. +// NOTE: Because of endianess issues, all I/O must be done from a File class. #include #include @@ -9,112 +10,174 @@ #include "defines.h" #include "config.h" -///////////////////////////////////////////////////////////////////////////// +// ============================================================================= // File construction/destruction -File::File() +File::File () { } -File::~File() +File::~File () { } -// ======================================================== +// ============================================================================= +// Endian-safe functions -unsigned long File::ReadByte(void* pBuf, unsigned long nCount) +// reads 1-byte integers +unsigned long File::ReadByte (void* pBuf, unsigned long nCount) { - return Read(pBuf, nCount); + return Read (pBuf, nCount); +} + +// reads 2-byte integers +unsigned long File::ReadShort (void* pBuf, unsigned long nCount) +{ + unsigned long read; + + read = Read (pBuf, nCount*2)/2; + +#ifdef LC_BIG_ENDIAN + unsigned long i; + unsigned short* val = (unsigned short*)pBuf, x; + + for (i = 0; i < read; i++) + { + x = *val; + *val = ((x>>8) | (x<<8)); + val++; + } +#endif + + return read; } -// Reads a 2-byte value -unsigned long File::ReadShort(void* pBuf, unsigned long nCount) +// reads 4-byte integers +unsigned long File::ReadLong (void* pBuf, unsigned long nCount) { - unsigned long read; + unsigned long read; - read = Read(pBuf, nCount*2)/2; + read = Read (pBuf, nCount*4)/4; #ifdef LC_BIG_ENDIAN - unsigned long i; - unsigned short* val = (unsigned short*)pBuf, x; - - for (i = 0; i < read; i++) - { - x = *val; - *val = ((x>>8) | (x<<8)); - val++; - } + unsigned long i; + unsigned long* val = (unsigned long*)pBuf, x; + + for (i = 0; i < read; i++) + { + x = *val; + *val = ((x>>24) | ((x>>8) & 0xff00) | ((x<<8) & 0xff0000) | (x<<24)); + val++; + } #endif - return read; + return read; } -// Read a 4-byte value -unsigned long File::ReadLong(void* pBuf, unsigned long nCount) +// reads 4-byte integers +unsigned long File::ReadFloat (void* pBuf, unsigned long nCount) { - unsigned long read; + unsigned long read; - read = Read(pBuf, nCount*4)/4; + read = Read (pBuf, nCount*4)/4; #ifdef LC_BIG_ENDIAN - unsigned long i; - unsigned long* val = (unsigned long*)pBuf, x; - - for (i = 0; i < read; i++) - { - x = *val; - *val = ((x>>24) | ((x>>8) & 0xff00) | ((x<<8) & 0xff0000) | (x<<24)); - val++; - } + unsigned long i; + float* val = (float*)pBuf; + union { unsigned char b[4]; float f; } in, out; + + for (i = 0; i < read; i++) + { + in.f = *val; + + out.b[0] = in.b[3]; + out.b[1] = in.b[2]; + out.b[2] = in.b[1]; + out.b[3] = in.b[0]; + + *val = out.f; + val++; + } #endif - return read; + return read; +} + +// writes 1-byte integers +unsigned long File::WriteByte (const void* pBuf, unsigned long nCount) +{ + return Write (pBuf, nCount); } -unsigned long File::WriteByte(const void* pBuf, unsigned long nCount) +// writes 2-byte integers +unsigned long File::WriteShort (const void* pBuf, unsigned long nCount) { - return Write(pBuf, nCount); +#ifdef LC_BIG_ENDIAN + unsigned long wrote = 0, i; + unsigned short* val = (unsigned short*)pBuf, x; + + for (i = 0; i < nCount; i++) + { + x = (((*val)>>8) | ((*val)<<8)); + val++; + wrote += Write (&x, 2)/2; + } + + return wrote; +#else + return Write(pBuf, nCount*2)/2; +#endif } -unsigned long File::WriteShort(const void* pBuf, unsigned long nCount) +// writes 4-byte integers +unsigned long File::WriteLong (const void* pBuf, unsigned long nCount) { #ifdef LC_BIG_ENDIAN - unsigned long wrote = 0, i; - unsigned short* val = (unsigned short*)pBuf, x; + unsigned long wrote = 0, i; + unsigned long* val = (unsigned long*)pBuf, x; - for (i = 0; i < nCount; i++) - { - x = (((*val)>>8) | ((*val)<<8)); - val++; - wrote += Write(&x, 2)/2; - } + for (i = 0; i < nCount; i++) + { + x = (((*val)>>24) | (((*val)>>8) & 0xff00) | (((*val)<<8) & 0xff0000) | ((*val)<<24)); + val++; + wrote += Write (&x, 4)/4; + } - return wrote; + return wrote; #else - return Write(pBuf, nCount*2); + return Write (pBuf, nCount*4)/4; #endif } -unsigned long File::WriteLong(const void* pBuf, unsigned long nCount) +// writes 4-byte floats +unsigned long File::WriteFloat (const void* pBuf, unsigned long nCount) { #ifdef LC_BIG_ENDIAN - unsigned long wrote = 0, i; - unsigned long* val = (unsigned long*)pBuf, x; + unsigned long wrote = 0, i; + float* val = (float*)pBuf, x; + union { unsigned char b[4]; float f; } in, out; - for (i = 0; i < nCount; i++) - { - x = (((*val)>>24) | (((*val)>>8) & 0xff00) | (((*val)<<8) & 0xff0000) | ((*val)<<24)); - val++; - wrote += Write(&x, 4)/4; - } + for (i = 0; i < nCount; i++) + { + in.f = *val; + val++; + + out.b[0] = in.b[3]; + out.b[1] = in.b[2]; + out.b[2] = in.b[1]; + out.b[3] = in.b[0]; + x = out.f; + + wrote += Write (&x, 4)/4; + } - return wrote; + return wrote; #else - return Write(pBuf, nCount*4); + return Write (pBuf, nCount*4)/4; #endif } -// ========================================================= +// ============================================================================= FileMem::FileMem() { diff --git a/common/file.h b/common/file.h index 6445a61..7e9ba9c 100644 --- a/common/file.h +++ b/common/file.h @@ -9,34 +9,36 @@ class File { -public: -// Constructors - File(); - virtual ~File(); - -// Implementation -public: - virtual unsigned long GetPosition() const = 0; - virtual unsigned long Seek(long lOff, int nFrom) = 0; - virtual void SetLength(unsigned long nNewLen) = 0; - virtual unsigned long GetLength() const = 0; - - virtual char* ReadString(char* pBuf, unsigned long nMax)=0; - virtual unsigned long Read(void* pBuf, unsigned long nCount)=0; - virtual unsigned long Write(const void* pBuf, unsigned long nCount)=0; - virtual int GetChar()=0; - virtual int PutChar(int c)=0; - - unsigned long ReadByte(void* pBuf, unsigned long nCount); - unsigned long ReadShort(void* pBuf, unsigned long nCount); - unsigned long ReadLong(void* pBuf, unsigned long nCount); - unsigned long WriteByte(const void* pBuf, unsigned long nCount); - unsigned long WriteShort(const void* pBuf, unsigned long nCount); - unsigned long WriteLong(const void* pBuf, unsigned long nCount); - - virtual void Abort()=0; - virtual void Flush()=0; - virtual void Close()=0; + public: + // Constructors + File(); + virtual ~File(); + + // Implementation + public: + virtual unsigned long GetPosition() const = 0; + virtual unsigned long Seek(long lOff, int nFrom) = 0; + virtual void SetLength(unsigned long nNewLen) = 0; + virtual unsigned long GetLength() const = 0; + + virtual char* ReadString(char* pBuf, unsigned long nMax)=0; + virtual unsigned long Read(void* pBuf, unsigned long nCount)=0; + virtual unsigned long Write(const void* pBuf, unsigned long nCount)=0; + virtual int GetChar()=0; + virtual int PutChar(int c)=0; + + unsigned long ReadByte (void* pBuf, unsigned long nCount); + unsigned long ReadShort (void* pBuf, unsigned long nCount); + unsigned long ReadLong (void* pBuf, unsigned long nCount); + unsigned long ReadFloat (void* pBuf, unsigned long nCount); + unsigned long WriteByte (const void* pBuf, unsigned long nCount); + unsigned long WriteShort (const void* pBuf, unsigned long nCount); + unsigned long WriteLong (const void* pBuf, unsigned long nCount); + unsigned long WriteFloat (const void* pBuf, unsigned long nCount); + + virtual void Abort()=0; + virtual void Flush()=0; + virtual void Close()=0; }; class FileMem : public File diff --git a/common/piece.cpp b/common/piece.cpp index a1f8495..abbddf7 100644 --- a/common/piece.cpp +++ b/common/piece.cpp @@ -191,7 +191,7 @@ bool Piece::FileLoad (File& file, char* name) file.ReadLong (&keys, 1); while (keys--) { - file.Read (param, 16); + file.ReadFloat (param, 4); file.ReadShort (&time, 1); file.ReadByte (&type, 1); @@ -201,7 +201,7 @@ bool Piece::FileLoad (File& file, char* name) file.ReadLong (&keys, 1); while (keys--) { - file.Read (param, 16); + file.ReadFloat (param, 4); file.ReadShort (&time, 1); file.ReadByte (&type, 1); @@ -220,14 +220,14 @@ bool Piece::FileLoad (File& file, char* name) if (version > 3) { float m[16]; - file.Read (m, sizeof(m)); + file.ReadFloat (m, 16); mat.FromFloat (m); } else { float move[3], rotate[3]; - file.Read (move, sizeof(float[3])); - file.Read (rotate, sizeof(float[3])); + file.ReadFloat (move, 3); + file.ReadFloat (rotate, 3); mat.CreateOld (move[0], move[1], move[2], rotate[0], rotate[1], rotate[2]); } @@ -252,8 +252,8 @@ bool Piece::FileLoad (File& file, char* name) { Matrix mat; float move[3], rotate[3]; - file.Read (move, sizeof(float[3])); - file.Read (rotate, sizeof(float[3])); + file.ReadFloat (move, 3); + file.ReadFloat (rotate, 3); mat.CreateOld (move[0], move[1], move[2], rotate[0], rotate[1], rotate[2]); mat.GetTranslation(¶m[0], ¶m[1], ¶m[2]); diff --git a/common/terrain.cpp b/common/terrain.cpp index 072b865..90545b3 100644 --- a/common/terrain.cpp +++ b/common/terrain.cpp @@ -257,57 +257,57 @@ Terrain::~Terrain() void Terrain::FileLoad(File* file) { - unsigned char ch; - unsigned short sh; - int i, j; - - file->Read(&ch, 1); - file->Read(&i, 4); - file->Read(&j, 4); - file->Read(&m_uSize, 4); - file->Read(&m_vSize, 4); - file->Read(&m_nOptions, 4); - file->Read(&m_fColor, 12); - - if (ch == 1) - { - file->Read(&ch, 1); - sh = ch; - } - else - file->Read(&sh, 2); - - if (sh > LC_MAXPATH) - file->Seek(sh, SEEK_CUR); - else - file->Read(&m_strTexture, sh); - - SetPatchCount(i, j); - for (i = 0; i < GetCountU(); i++) - for (j = 0; j < GetCountV(); j++) - file->Read(&m_pControl[i][j*3+2], 4); + unsigned char ch; + unsigned short sh; + int i, j; + + file->ReadByte (&ch, 1); + file->ReadLong (&i, 1); + file->ReadLong (&j, 1); + file->ReadFloat (&m_uSize, 1); + file->ReadFloat (&m_vSize, 1); + file->ReadLong (&m_nOptions, 1); + file->ReadFloat (&m_fColor, 3); + + if (ch == 1) + { + file->Read(&ch, 1); + sh = ch; + } + else + file->ReadShort (&sh, 1); + + if (sh > LC_MAXPATH) + file->Seek (sh, SEEK_CUR); + else + file->Read (&m_strTexture, sh); + + SetPatchCount(i, j); + for (i = 0; i < GetCountU(); i++) + for (j = 0; j < GetCountV(); j++) + file->ReadFloat (&m_pControl[i][j*3+2], 1); } void Terrain::FileSave(File* file) { - unsigned char version = 2; // LeoCAD 0.70 - unsigned short sh; - - file->Write(&version, 1); - file->Write(&m_uPatches, 4); - file->Write(&m_vPatches, 4); - file->Write(&m_uSize, 4); - file->Write(&m_vSize, 4); - file->Write(&m_nOptions, 4); - file->Write(&m_fColor, 12); - - sh = strlen(m_strTexture); - file->Write(&sh, 2); - file->Write(m_strTexture, sh); - - for (int i = 0; i < GetCountU(); i++) - for (int j = 0; j < GetCountV(); j++) - file->Write(&m_pControl[i][j*3+2], 4); + unsigned char version = 2; // LeoCAD 0.70 + unsigned short sh; + + file->WriteByte (&version, 1); + file->WriteLong (&m_uPatches, 1); + file->WriteLong (&m_vPatches, 1); + file->WriteFloat (&m_uSize, 1); + file->WriteFloat (&m_vSize, 1); + file->WriteLong (&m_nOptions, 1); + file->WriteFloat (&m_fColor, 3); + + sh = strlen (m_strTexture); + file->WriteShort (&sh, 1); + file->Write (m_strTexture, sh); + + for (int i = 0; i < GetCountU(); i++) + for (int j = 0; j < GetCountV(); j++) + file->WriteFloat (&m_pControl[i][j*3+2], 1); } void Terrain::FreeMemory() -- cgit v1.2.3