天龙八部二进制文件 读写序列化类

来源:互联网 发布:中国安检有多严格 知乎 编辑:程序博客网 时间:2024/05/16 11:00
 

可以方便地实现天龙二进制的读和写

 

首先是序列化类

 

view plaincopy to clipboardprint?
  1. #ifndef __CORE_SERIALIZER_UTIL_H__  
  2. #define __CORE_SERIALIZER_UTIL_H__  
  3.   
  4. #include <OgreString.h>   
  5. #include <OgreDataStream.h>  
  6. using namespace Ogre;  
  7.   
  8. namespace Core  
  9. {  
  10.     // Endian routines   
  11.     extern void flipToLittleEndian(void* pData, size_t size, size_t count = 1);  
  12.     extern void flipFromLittleEndian(void* pData, size_t size, size_t count = 1);  
  13.   
  14.     extern void flipEndian(void * pData, size_t size, size_t count);  
  15.     extern void flipEndian(void * pData, size_t size);  
  16.   
  17.     // Writer   
  18.     class Writer   
  19.     {  
  20.     public:  
  21.         virtual ~Writer() {}  
  22.   
  23.         void writeFloats(const float* pFloat, size_t count = 1);  
  24.         void writeFloats(const double* pDouble, size_t count = 1);  
  25.         void writeShorts(const uint16* pShort, size_t count = 1);  
  26.         void writeInts(const uint32* pInt, size_t count = 1);  
  27.         void writeBools(const bool* pBool, size_t count = 1);  
  28.   
  29.         void writeString(const String& string);  
  30.   
  31.         void writeObject(const Ogre::Vector3& v);  
  32.         void writeObject(const Ogre::Quaternion& q);  
  33.   
  34.         void writeData(const void* data, size_t size);  
  35.   
  36.     protected:  
  37.         virtual void _write(const void* buf, size_t size, size_t count) = 0;  
  38.     };  
  39.   
  40.     // Reader   
  41.     class Reader   
  42.     {  
  43.     public:  
  44.         virtual ~Reader() {}  
  45.   
  46.         void readFloats(float* pFloat, size_t count = 1);  
  47.         void readFloats(double* pDouble, size_t count = 1);  
  48.         void readShorts(uint16* pShort, size_t count = 1);  
  49.         void readInts(uint32* pInt, size_t count = 1);  
  50.         void readBools(bool* pBool, size_t count = 1);  
  51.   
  52.         String readString(void);  
  53.         String readString(size_t numChars);  
  54.   
  55.         void readObject(Ogre::Vector3& v);  
  56.         void readObject(Ogre::Quaternion& q);  
  57.   
  58.         void readData(void* data, size_t size);  
  59.   
  60.     protected:  
  61.         virtual void _read(void* buf, size_t size, size_t count) = 0;  
  62.     };  
  63.   
  64.     // FileWriter   
  65.     class FileWriter : public Writer   
  66.     {  
  67.     private:  
  68.         FileWriter(const FileWriter&);  
  69.         FileWriter& operator= (const FileWriter&);  
  70.   
  71.     public:  
  72.         explicit FileWriter(FILE* file, bool adopts = false)  
  73.             : mFile(file)  
  74.             , mAdopts(adopts)  
  75.         {  
  76.         }  
  77.   
  78.         explicit FileWriter(const String& filename)  
  79.             : mFile(fopen(filename.c_str(), "wb"))  
  80.             , mAdopts(true)  
  81.         {  
  82.         }  
  83.   
  84.         ~FileWriter()  
  85.         {  
  86.             if (mAdopts && mFile)  
  87.                 fclose(mFile);  
  88.         }  
  89.   
  90.         FILE* getFile(voidconst  
  91.         {  
  92.             return mFile;  
  93.         }  
  94.   
  95.     protected:  
  96.         FILE* mFile;  
  97.         bool mAdopts;  
  98.   
  99.         void _write(const void* buf, size_t size, size_t count);  
  100.     };  
  101.   
  102.     // DataStreamReader   
  103.     class DataStreamReader : public Reader   
  104.     {  
  105.     private:  
  106.         DataStreamReader(const DataStreamReader&);  
  107.         DataStreamReader& operator= (const DataStreamReader&);  
  108.   
  109.     public:  
  110.         explicit DataStreamReader(Ogre::DataStreamPtr& stream)  
  111.             : mStream(stream)  
  112.         {  
  113.         }  
  114.   
  115.         Ogre::DataStreamPtr& getStream(void)  
  116.         {  
  117.             return mStream;  
  118.         }  
  119.   
  120.     protected:  
  121.         Ogre::DataStreamPtr mStream;  
  122.   
  123.         void _read(void* buf, size_t size, size_t count);  
  124.     };  
  125.   
  126. }  
  127.   
  128. #endif  

view plaincopy to clipboardprint?
  1. #include "CoreSerializerUtil.h"   
  2.   
  3. #include <OgreDataStream.h>  
  4. #include <OgreVector3.h>   
  5. #include <OgreQuaternion.h>  
  6. #include <OgreException.h>   
  7.   
  8. namespace Core  
  9. {  
  10.   
  11.     //--------------------------------------------------------------------------------------------  
  12.     void flipToLittleEndian(void* pData, size_t size, size_t count)  
  13.     {  
  14. #   if OGRE_ENDIAN == OGRE_ENDIAN_BIG  
  15.         flipEndian(pData, size, count);  
  16. #   endif   
  17.     }  
  18.   
  19.     //--------------------------------------------------------------------------------------------  
  20.     void flipFromLittleEndian(void* pData, size_t size, size_t count)  
  21.     {  
  22. #   if OGRE_ENDIAN == OGRE_ENDIAN_BIG  
  23.         flipEndian(pData, size, count);  
  24. #   endif   
  25.     }  
  26.   
  27.     //--------------------------------------------------------------------------------------------  
  28.     void flipEndian(void * pData, size_t size, size_t count)  
  29.     {  
  30.         for(size_t index = 0; index < count; index++)  
  31.         {  
  32.             flipEndian((void *)((int)pData + (index * size)), size);  
  33.         }  
  34.     }  
  35.   
  36.     //--------------------------------------------------------------------------------------------  
  37.     void flipEndian(void * pData, size_t size)  
  38.     {  
  39.         char swapByte;  
  40.         for(size_t byteIndex = 0; byteIndex < size/2; byteIndex++)  
  41.         {  
  42.             swapByte = *(char *)((int)pData + byteIndex);  
  43.             *(char *)((int)pData + byteIndex) = *(char *)((int)pData + size - byteIndex - 1);  
  44.             *(char *)((int)pData + size - byteIndex - 1) = swapByte;  
  45.         }  
  46.     }  
  47.   
  48.     //---------------------------------------------------------------------  
  49.     void Writer::writeFloats(const float* pFloat, size_t count)  
  50.     {  
  51. #   if OGRE_ENDIAN == OGRE_ENDIAN_BIG  
  52.         float * pFloatToWrite = (float *)malloc(sizeof(float) * count);  
  53.         memcpy(pFloatToWrite, pFloat, sizeof(float) * count);  
  54.   
  55.         flipToLittleEndian(pFloatToWrite, sizeof(float), count);  
  56.         _write(pFloatToWrite, sizeof(float), count);  
  57.   
  58.         free(pFloatToWrite);  
  59. #   else   
  60.         _write(pFloat, sizeof(float), count);  
  61. #   endif   
  62.     }  
  63.   
  64.     //---------------------------------------------------------------------  
  65.     void Writer::writeFloats(const double* pDouble, size_t count)  
  66.     {  
  67.         // Convert to float, then write  
  68.         float* tmp = new float[count];  
  69.         for (size_t i = 0; i < count; ++i)  
  70.         {  
  71.             tmp[i] = static_cast<float>(pDouble[i]);  
  72.         }  
  73. #   if OGRE_ENDIAN == OGRE_ENDIAN_BIG  
  74.         flipToLittleEndian(tmp, sizeof(float), count);  
  75.         _write(tmp, sizeof(float), count);  
  76. #   else   
  77.         _write(tmp, sizeof(float), count);  
  78. #   endif   
  79.         delete [] tmp;  
  80.     }  
  81.   
  82.     //---------------------------------------------------------------------  
  83.     void Writer::writeShorts(const uint16* pShort, size_t count)  
  84.     {  
  85. #   if OGRE_ENDIAN == OGRE_ENDIAN_BIG  
  86.         uint16 * pShortToWrite = (uint16 *)malloc(sizeof(uint16) * count);  
  87.         memcpy(pShortToWrite, pShort, sizeof(uint16) * count);  
  88.   
  89.         flipToLittleEndian(pShortToWrite, sizeof(uint16), count);  
  90.         _write(pShortToWrite, sizeof(uint16), count);  
  91.   
  92.         free(pShortToWrite);  
  93. #   else   
  94.         _write(pShort, sizeof(uint16), count);  
  95. #   endif   
  96.     }  
  97.   
  98.     //---------------------------------------------------------------------  
  99.     void Writer::writeInts(const uint32* pInt, size_t count)  
  100.     {  
  101. #   if OGRE_ENDIAN == OGRE_ENDIAN_BIG  
  102.         uint32 * pIntToWrite = (uint32 *)malloc(sizeof(uint32) * count);  
  103.         memcpy(pIntToWrite, pInt, sizeof(uint32) * count);  
  104.   
  105.         flipToLittleEndian(pIntToWrite, sizeof(uint32), count);  
  106.         _write(pIntToWrite, sizeof(uint32), count);  
  107.   
  108.         free(pIntToWrite);  
  109. #   else   
  110.         _write(pInt, sizeof(uint32), count);  
  111. #   endif   
  112.     }  
  113.   
  114.     //---------------------------------------------------------------------  
  115.     void Writer::writeBools(const bool* pBool, size_t count)  
  116.     {  
  117.         // no endian flipping for 1-byte bools  
  118.         // XXX Nasty Hack to convert to 1-byte bools  
  119. #   if OGRE_PLATFORM == OGRE_PLATFORM_APPLE  
  120.         char * pCharToWrite = (char *)malloc(sizeof(char) * count);  
  121.         for(int i = 0; i < count; i++)  
  122.         {  
  123.             *(char *)(pCharToWrite + i) = *(bool *)(pBool + i);  
  124.         }  
  125.   
  126.         _write(pCharToWrite, sizeof(char), count);  
  127.   
  128.         free(pCharToWrite);  
  129. #   else   
  130.         _write(pBool, sizeof(bool), count);  
  131. #   endif   
  132.   
  133.     }  
  134.   
  135.     //---------------------------------------------------------------------  
  136.     void Writer::writeString(const String& string)  
  137.     {  
  138.         uint32 numChars = string.length();  
  139.         writeInts(&numChars);  
  140.         _write(string.c_str(), sizeof(String::value_type), numChars);  
  141.     }  
  142.   
  143.     //---------------------------------------------------------------------  
  144.     void Writer::writeObject(const Ogre::Vector3& v)  
  145.     {  
  146.         writeFloats(&v.x);  
  147.         writeFloats(&v.y);  
  148.         writeFloats(&v.z);  
  149.     }  
  150.   
  151.     //---------------------------------------------------------------------  
  152.     void Writer::writeObject(const Ogre::Quaternion& q)  
  153.     {  
  154.         writeFloats(&q.x);  
  155.         writeFloats(&q.y);  
  156.         writeFloats(&q.z);  
  157.         writeFloats(&q.w);  
  158.     }  
  159.   
  160.     //---------------------------------------------------------------------  
  161.     void Writer::writeData(const void* data, size_t size)  
  162.     {  
  163.         _write(data, size, 1);  
  164.     }  
  165.   
  166.     //---------------------------------------------------------------------  
  167.     void Reader::readFloats(float* pFloat, size_t count)  
  168.     {  
  169.         _read(pFloat, sizeof(float), count);  
  170.         flipFromLittleEndian(pFloat, sizeof(float), count);  
  171.     }  
  172.   
  173.     //---------------------------------------------------------------------  
  174.     void Reader::readFloats(double* pDouble, size_t count)  
  175.     {  
  176.         // Read from float, convert to double  
  177.         float* tmp = new float[count];  
  178.         float* ptmp = tmp;  
  179.         _read(tmp, sizeof(float), count);  
  180.         flipFromLittleEndian(tmp, sizeof(float), count);  
  181.         // Convert to doubles (no cast required)  
  182.         while (count--)  
  183.         {  
  184.             *pDouble++ = *ptmp++;  
  185.         }  
  186.         delete [] tmp;  
  187.     }  
  188.   
  189.     //---------------------------------------------------------------------  
  190.     void Reader::readShorts(uint16* pShort, size_t count)  
  191.     {  
  192.         _read(pShort, sizeof(uint16), count);  
  193.         flipFromLittleEndian(pShort, sizeof(uint16), count);  
  194.     }  
  195.   
  196.     //---------------------------------------------------------------------  
  197.     void Reader::readInts(uint32* pInt, size_t count)  
  198.     {  
  199.         _read(pInt, sizeof(uint32), count);  
  200.         flipFromLittleEndian(pInt, sizeof(uint32), count);  
  201.     }  
  202.   
  203.     //---------------------------------------------------------------------  
  204.     void Reader::readBools(bool* pBool, size_t count)  
  205.     {  
  206.         //XXX Nasty Hack to convert 1 byte bools to 4 byte bools  
  207. #   if OGRE_PLATFORM == OGRE_PLATFORM_APPLE  
  208.         char * pTemp = (char *)malloc(1*count); // to hold 1-byte bools  
  209.         _read(pTemp, sizeof(char), count);  
  210.         for(int i = 0; i < count; i++)  
  211.             *(bool *)(pBool + i) = *(char *)(pTemp + i);  
  212.   
  213.         free (pTemp);  
  214. #   else   
  215.         _read(pBool, sizeof(bool), count);  
  216. #   endif   
  217.         //no flipping on 1-byte datatypes  
  218.     }  
  219.   
  220.     //---------------------------------------------------------------------  
  221.     String Reader::readString(size_t numChars)  
  222.     {  
  223.         String str(numChars, '/0');  
  224.         _read(const_cast<String::value_type*>(str.data()), sizeof(String::value_type), numChars);  
  225.         return str;  
  226.     }  
  227.     //---------------------------------------------------------------------  
  228.     String Reader::readString(void)  
  229.     {  
  230.         uint32 numChars;  
  231.         readInts(&numChars);  
  232.         return readString(numChars);  
  233.     }  
  234.     //---------------------------------------------------------------------  
  235.     void Reader::readObject(Ogre::Vector3& v)  
  236.     {  
  237.         readFloats(&v.x);  
  238.         readFloats(&v.y);  
  239.         readFloats(&v.z);  
  240.     }  
  241.     //---------------------------------------------------------------------  
  242.     void Reader::readObject(Ogre::Quaternion& q)  
  243.     {  
  244.         readFloats(&q.x);  
  245.         readFloats(&q.y);  
  246.         readFloats(&q.z);  
  247.         readFloats(&q.w);  
  248.     }  
  249.     //---------------------------------------------------------------------  
  250.     void Reader::readData(void* data, size_t size)  
  251.     {  
  252.         _read(data, size, 1);  
  253.     }  
  254.   
  255.     //--------------------------------------------------------------------------------------------  
  256.     void FileWriter::_write(const void* buf, size_t size, size_t count)  
  257.     {  
  258.         if (fwrite(buf, size, count, mFile) != count)  
  259.         {  
  260.             OGRE_EXCEPT(Ogre::Exception::ERR_CANNOT_WRITE_TO_FILE,  
  261.                 "Can't write data to file",  
  262.                 "FileWriter::_write");  
  263.         }  
  264.     }  
  265.   
  266.     //--------------------------------------------------------------------------------------------  
  267.     void DataStreamReader::_read(void* buf, size_t size, size_t count)  
  268.     {  
  269.         if (mStream->read(buf, size * count) != size * count)  
  270.         {  
  271.             OGRE_EXCEPT(Ogre::Exception::ERR_INTERNAL_ERROR,  
  272.                 "Can't read data from stream",  
  273.                 "DataStreamReader::_read");  
  274.         }  
  275.     }  
  276. }  

 

 

怎么用呢,举个例子,我们读取和写入高度图

view plaincopy to clipboardprint?
  1. namespace Core  
  2. {  
  3.     const uint32 TERRAIN_HEIGHTMAP_MAGIC = 'FEHM';  
  4.     const uint32 TERRAIN_HEIGHTMAP_VERSION = 0x00100000;  
  5.   
  6.     //------------------------------------------------------------------------------------------------  
  7.     void TerrainData::_loadHeightmap(const String& filename, const String& type, const String& groupName)  
  8.     {  
  9.         // 分配buffer   
  10.         mHeightmap.resize((mXSize + 1) * (mZSize + 1));  
  11.   
  12.         if (filename.empty())  
  13.         {  
  14.             std::fill(mHeightmap.begin(), mHeightmap.end(), (Real)0);  
  15.         }  
  16.         else if (type == "image")  
  17.         {  
  18.             // 省略   
  19.         }  
  20.         else if (type == "standard")  
  21.         {  
  22.             Ogre::DataStreamPtr stream = Ogre::ResourceGroupManager::getSingleton().openResource(filename, groupName);  
  23.             DataStreamReader reader(stream);  
  24.   
  25.             // 文件头校验   
  26.             uint32 header[4];  
  27.             reader.readInts(header, 4);  
  28.             if (header[0] != TERRAIN_HEIGHTMAP_MAGIC)  
  29.             {  
  30.                 // 异常   
  31.             }  
  32.             if (header[1] != TERRAIN_HEIGHTMAP_VERSION)  
  33.             {  
  34.                 // 异常   
  35.             }  
  36.             if (header[2] != mXSize+1 || header[3] != mZSize+1)  
  37.             {  
  38.                 // 异常   
  39.             }  
  40.   
  41.             // 读取高度数据   
  42.             reader.readFloats(&mHeightmap[0], mHeightmap.size());  
  43.   
  44.             // 文件尾校验   
  45.             if (stream->tell() != stream->size())  
  46.             {  
  47.                 // 异常   
  48.             }  
  49.         }  
  50.         else  
  51.         {  
  52.             assert(type == "raw");  
  53.             // 省略   
  54.         }  
  55.     }  
  56.   
  57.     //-----------------------------------------------------------------------------------------------------------------  
  58.     void TerrainData::_saveHeightmap(const String& filename) const  
  59.     {  
  60.         FileWriter writer(filename);  
  61.   
  62.         // 写文件头   
  63.         uint32 header[4];  
  64.         header[0] = TERRAIN_HEIGHTMAP_MAGIC;  
  65.         header[1] = TERRAIN_HEIGHTMAP_VERSION;  
  66.         header[2] = mXSize + 1;  
  67.         header[3] = mZSize + 1;  
  68.         writer.writeInts(header, 4);  
  69.   
  70.         // 写数据   
  71.         writer.writeFloats(&mHeightmap[0], mHeightmap.size());  
  72.     }  
  73. }