00001 /* 00002 ----------------------------------------------------------------------------- 00003 This source file is part of OGRE 00004 (Object-oriented Graphics Rendering Engine) 00005 For the latest info, see http://www.ogre3d.org/ 00006 00007 Copyright © 2000-2002 The OGRE Team 00008 Also see acknowledgements in Readme.html 00009 00010 This program is free software; you can redistribute it and/or modify it under 00011 the terms of the GNU Lesser General Public License as published by the Free Software 00012 Foundation; either version 2 of the License, or (at your option) any later 00013 version. 00014 00015 This program is distributed in the hope that it will be useful, but WITHOUT 00016 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 00017 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. 00018 00019 You should have received a copy of the GNU Lesser General Public License along with 00020 this program; if not, write to the Free Software Foundation, Inc., 59 Temple 00021 Place - Suite 330, Boston, MA 02111-1307, USA, or go to 00022 http://www.gnu.org/copyleft/lesser.txt. 00023 ----------------------------------------------------------------------------- 00024 */ 00025 #include "OgreStableHeaders.h" 00026 00027 #include "OgreSerializer.h" 00028 #include "OgreLogManager.h" 00029 #include "OgreDataChunk.h" 00030 #include "OgreException.h" 00031 #include "OgreVector3.h" 00032 #include "OgreQuaternion.h" 00033 00034 00035 namespace Ogre { 00036 00038 const unsigned long CHUNK_OVERHEAD_SIZE = sizeof(unsigned short) + sizeof(unsigned long); 00039 const unsigned short HEADER_CHUNK_ID = 0x1000; 00040 //--------------------------------------------------------------------- 00041 Serializer::Serializer() 00042 { 00043 // Version number 00044 mVersion = "[Serializer_v1.00]"; 00045 } 00046 //--------------------------------------------------------------------- 00047 Serializer::~Serializer() 00048 { 00049 } 00050 //--------------------------------------------------------------------- 00051 void Serializer::writeFileHeader(void) 00052 { 00053 00054 unsigned short val = HEADER_CHUNK_ID; 00055 writeShorts(&val, 1); 00056 00057 writeString(mVersion); 00058 00059 } 00060 //--------------------------------------------------------------------- 00061 void Serializer::writeChunkHeader(unsigned short id, unsigned long size) 00062 { 00063 writeShorts(&id, 1); 00064 writeLongs(&size, 1); 00065 } 00066 //--------------------------------------------------------------------- 00067 void Serializer::writeReals(const Real* pReal, size_t count) 00068 { 00069 # if OGRE_ENDIAN == ENDIAN_BIG 00070 Real * pRealToWrite = (Real *)malloc(sizeof(Real) * count); 00071 memcpy(pRealToWrite, pReal, sizeof(Real) * count); 00072 00073 flipToLittleEndian(pRealToWrite, sizeof(Real), count); 00074 writeData(pRealToWrite, sizeof(Real), count); 00075 00076 free(pRealToWrite); 00077 # else 00078 writeData(pReal, sizeof(Real), count); 00079 # endif 00080 } 00081 //--------------------------------------------------------------------- 00082 void Serializer::writeShorts(const unsigned short* pShort, size_t count) 00083 { 00084 # if OGRE_ENDIAN == ENDIAN_BIG 00085 unsigned short * pShortToWrite = (unsigned short *)malloc(sizeof(unsigned short) * count); 00086 memcpy(pShortToWrite, pShort, sizeof(unsigned short) * count); 00087 00088 flipToLittleEndian(pShortToWrite, sizeof(unsigned short), count); 00089 writeData(pShortToWrite, sizeof(unsigned short), count); 00090 00091 free(pShortToWrite); 00092 # else 00093 writeData(pShort, sizeof(unsigned short), count); 00094 # endif 00095 } 00096 //--------------------------------------------------------------------- 00097 void Serializer::writeInts(const unsigned int* pInt, size_t count) 00098 { 00099 # if OGRE_ENDIAN == ENDIAN_BIG 00100 unsigned int * pIntToWrite = (unsigned int *)malloc(sizeof(unsigned int) * count); 00101 memcpy(pIntToWrite, pInt, sizeof(unsigned int) * count); 00102 00103 flipToLittleEndian(pIntToWrite, sizeof(unsigned int), count); 00104 writeData(pIntToWrite, sizeof(unsigned int), count); 00105 00106 free(pIntToWrite); 00107 # else 00108 writeData(pInt, sizeof(unsigned int), count); 00109 # endif 00110 } 00111 //--------------------------------------------------------------------- 00112 void Serializer::writeLongs(const unsigned long* pLong, size_t count) 00113 { 00114 # if OGRE_ENDIAN == ENDIAN_BIG 00115 unsigned long * pLongToWrite = (unsigned long *)malloc(sizeof(unsigned long) * count); 00116 memcpy(pLongToWrite, pLong, sizeof(unsigned long) * count); 00117 00118 flipToLittleEndian(pLongToWrite, sizeof(unsigned long), count); 00119 writeData(pLongToWrite, sizeof(unsigned long), count); 00120 00121 free(pLongToWrite); 00122 # else 00123 writeData(pLong, sizeof(unsigned long), count); 00124 # endif 00125 } 00126 //--------------------------------------------------------------------- 00127 void Serializer::writeBools(const bool* pBool, size_t count) 00128 { 00129 //no endian flipping for 1-byte bools 00130 //XXX Nasty Hack to convert to 1-byte bools 00131 # if OGRE_PLATFORM == PLATFORM_APPLE 00132 char * pCharToWrite = (char *)malloc(sizeof(char) * count); 00133 for(int i = 0; i < count; i++) 00134 { 00135 *(char *)(pCharToWrite + i) = *(bool *)(pBool + i); 00136 } 00137 00138 writeData(pCharToWrite, sizeof(char), count); 00139 00140 free(pCharToWrite); 00141 # else 00142 writeData(pBool, sizeof(bool), count); 00143 # endif 00144 00145 } 00146 00147 //--------------------------------------------------------------------- 00148 void Serializer::writeData(const void* buf, size_t size, size_t count) 00149 { 00150 fwrite((void* const)buf, size, count, mpfFile); 00151 } 00152 //--------------------------------------------------------------------- 00153 void Serializer::writeString(const String& string) 00154 { 00155 fputs(string.c_str(), mpfFile); 00156 // Write terminating newline char 00157 fputc('\n', mpfFile); 00158 } 00159 //--------------------------------------------------------------------- 00160 void Serializer::readFileHeader(DataChunk& chunk) 00161 { 00162 unsigned short headerID; 00163 00164 // Read header ID 00165 readShorts(chunk, &headerID, 1); 00166 00167 if (headerID == HEADER_CHUNK_ID) 00168 { 00169 // Read version 00170 String ver = readString(chunk); 00171 if (ver != mVersion) 00172 { 00173 Except(Exception::ERR_INTERNAL_ERROR, 00174 "Invalid file: version incompatible, file reports " + String(ver) + 00175 " Serializer is version " + mVersion, 00176 "Serializer::readFileHeader"); 00177 } 00178 } 00179 else 00180 { 00181 Except(Exception::ERR_INTERNAL_ERROR, "Invalid file: no header", 00182 "Serializer::readFileHeader"); 00183 } 00184 00185 } 00186 //--------------------------------------------------------------------- 00187 unsigned short Serializer::readChunk(DataChunk& chunk) 00188 { 00189 unsigned short id; 00190 readShorts(chunk, &id, 1); 00191 00192 readLongs(chunk, &mCurrentChunkLen, 1); 00193 return id; 00194 } 00195 //--------------------------------------------------------------------- 00196 void Serializer::readBools(DataChunk& chunk, bool* pDest, size_t count) 00197 { 00198 //XXX Nasty Hack to convert 1 byte bools to 4 byte bools 00199 # if OGRE_PLATFORM == PLATFORM_APPLE 00200 char * pTemp = (char *)malloc(1*count); // to hold 1-byte bools 00201 chunk.read(pTemp, 1 * count); 00202 for(int i = 0; i < count; i++) 00203 *(bool *)(pDest + i) = *(char *)(pTemp + i); 00204 00205 free (pTemp); 00206 # else 00207 chunk.read(pDest, sizeof(bool) * count); 00208 # endif 00209 //no flipping on 1-byte datatypes 00210 } 00211 //--------------------------------------------------------------------- 00212 void Serializer::readReals(DataChunk& chunk, Real* pDest, size_t count) 00213 { 00214 chunk.read(pDest, sizeof(Real) * count); 00215 flipFromLittleEndian(pDest, sizeof(Real), count); 00216 } 00217 //--------------------------------------------------------------------- 00218 void Serializer::readShorts(DataChunk& chunk, unsigned short* pDest, size_t count) 00219 { 00220 chunk.read(pDest, sizeof(unsigned short) * count); 00221 flipFromLittleEndian(pDest, sizeof(unsigned short), count); 00222 } 00223 //--------------------------------------------------------------------- 00224 void Serializer::readInts(DataChunk& chunk, unsigned int* pDest, size_t count) 00225 { 00226 chunk.read(pDest, sizeof(unsigned int) * count); 00227 flipFromLittleEndian(pDest, sizeof(unsigned int), count); 00228 } 00229 //--------------------------------------------------------------------- 00230 void Serializer::readLongs(DataChunk& chunk, unsigned long* pDest, size_t count) 00231 { 00232 chunk.read(pDest, sizeof(unsigned long) * count); 00233 flipFromLittleEndian(pDest, sizeof(unsigned long), count); 00234 } 00235 //--------------------------------------------------------------------- 00236 String Serializer::readString(DataChunk& chunk) 00237 { 00238 char str[255]; 00239 size_t readcount; 00240 readcount = chunk.readUpTo(str, 255); 00241 str[readcount] = '\0'; 00242 return str; 00243 00244 } 00245 //--------------------------------------------------------------------- 00246 void Serializer::writeObject(const Vector3& vec) 00247 { 00248 writeReals(&vec.x, 1); 00249 writeReals(&vec.y, 1); 00250 writeReals(&vec.z, 1); 00251 00252 } 00253 //--------------------------------------------------------------------- 00254 void Serializer::writeObject(const Quaternion& q) 00255 { 00256 writeReals(&q.x, 1); 00257 writeReals(&q.y, 1); 00258 writeReals(&q.z, 1); 00259 writeReals(&q.w, 1); 00260 } 00261 //--------------------------------------------------------------------- 00262 void Serializer::readObject(DataChunk& chunk, Vector3* pDest) 00263 { 00264 readReals(chunk, &pDest->x, 1); 00265 readReals(chunk, &pDest->y, 1); 00266 readReals(chunk, &pDest->z, 1); 00267 } 00268 //--------------------------------------------------------------------- 00269 void Serializer::readObject(DataChunk& chunk, Quaternion* pDest) 00270 { 00271 readReals(chunk, &pDest->x, 1); 00272 readReals(chunk, &pDest->y, 1); 00273 readReals(chunk, &pDest->z, 1); 00274 readReals(chunk, &pDest->w, 1); 00275 } 00276 //--------------------------------------------------------------------- 00277 00278 00279 void Serializer::flipToLittleEndian(void* pData, size_t size, size_t count) 00280 { 00281 # if OGRE_ENDIAN == ENDIAN_BIG 00282 flipEndian(pData, size, count); 00283 # endif 00284 } 00285 00286 void Serializer::flipFromLittleEndian(void* pData, size_t size, size_t count) 00287 { 00288 # if OGRE_ENDIAN == ENDIAN_BIG 00289 flipEndian(pData, size, count); 00290 # endif 00291 } 00292 00293 void Serializer::flipEndian(void * pData, size_t size, size_t count) 00294 { 00295 for(unsigned int index = 0; index < count; index++) 00296 { 00297 flipEndian((void *)((int)pData + (index * size)), size); 00298 } 00299 } 00300 00301 void Serializer::flipEndian(void * pData, size_t size) 00302 { 00303 char swapByte; 00304 for(unsigned int byteIndex = 0; byteIndex < size/2; byteIndex++) 00305 { 00306 swapByte = *(char *)((int)pData + byteIndex); 00307 *(char *)((int)pData + byteIndex) = *(char *)((int)pData + size - byteIndex - 1); 00308 *(char *)((int)pData + size - byteIndex - 1) = swapByte; 00309 } 00310 } 00311 00312 } 00313
Copyright © 2002-2003 by The OGRE Team
Last modified Wed Jan 21 00:10:28 2004