天龙八部二进制文件 读写序列化类
来源:互联网 发布:中国安检有多严格 知乎 编辑:程序博客网 时间:2024/05/16 11:00
可以方便地实现天龙二进制的读和写
首先是序列化类
- #ifndef __CORE_SERIALIZER_UTIL_H__
- #define __CORE_SERIALIZER_UTIL_H__
- #include <OgreString.h>
- #include <OgreDataStream.h>
- using namespace Ogre;
- namespace Core
- {
- // Endian routines
- extern void flipToLittleEndian(void* pData, size_t size, size_t count = 1);
- extern void flipFromLittleEndian(void* pData, size_t size, size_t count = 1);
- extern void flipEndian(void * pData, size_t size, size_t count);
- extern void flipEndian(void * pData, size_t size);
- // Writer
- class Writer
- {
- public:
- virtual ~Writer() {}
- void writeFloats(const float* pFloat, size_t count = 1);
- void writeFloats(const double* pDouble, size_t count = 1);
- void writeShorts(const uint16* pShort, size_t count = 1);
- void writeInts(const uint32* pInt, size_t count = 1);
- void writeBools(const bool* pBool, size_t count = 1);
- void writeString(const String& string);
- void writeObject(const Ogre::Vector3& v);
- void writeObject(const Ogre::Quaternion& q);
- void writeData(const void* data, size_t size);
- protected:
- virtual void _write(const void* buf, size_t size, size_t count) = 0;
- };
- // Reader
- class Reader
- {
- public:
- virtual ~Reader() {}
- void readFloats(float* pFloat, size_t count = 1);
- void readFloats(double* pDouble, size_t count = 1);
- void readShorts(uint16* pShort, size_t count = 1);
- void readInts(uint32* pInt, size_t count = 1);
- void readBools(bool* pBool, size_t count = 1);
- String readString(void);
- String readString(size_t numChars);
- void readObject(Ogre::Vector3& v);
- void readObject(Ogre::Quaternion& q);
- void readData(void* data, size_t size);
- protected:
- virtual void _read(void* buf, size_t size, size_t count) = 0;
- };
- // FileWriter
- class FileWriter : public Writer
- {
- private:
- FileWriter(const FileWriter&);
- FileWriter& operator= (const FileWriter&);
- public:
- explicit FileWriter(FILE* file, bool adopts = false)
- : mFile(file)
- , mAdopts(adopts)
- {
- }
- explicit FileWriter(const String& filename)
- : mFile(fopen(filename.c_str(), "wb"))
- , mAdopts(true)
- {
- }
- ~FileWriter()
- {
- if (mAdopts && mFile)
- fclose(mFile);
- }
- FILE* getFile(void) const
- {
- return mFile;
- }
- protected:
- FILE* mFile;
- bool mAdopts;
- void _write(const void* buf, size_t size, size_t count);
- };
- // DataStreamReader
- class DataStreamReader : public Reader
- {
- private:
- DataStreamReader(const DataStreamReader&);
- DataStreamReader& operator= (const DataStreamReader&);
- public:
- explicit DataStreamReader(Ogre::DataStreamPtr& stream)
- : mStream(stream)
- {
- }
- Ogre::DataStreamPtr& getStream(void)
- {
- return mStream;
- }
- protected:
- Ogre::DataStreamPtr mStream;
- void _read(void* buf, size_t size, size_t count);
- };
- }
- #endif
- #include "CoreSerializerUtil.h"
- #include <OgreDataStream.h>
- #include <OgreVector3.h>
- #include <OgreQuaternion.h>
- #include <OgreException.h>
- namespace Core
- {
- //--------------------------------------------------------------------------------------------
- void flipToLittleEndian(void* pData, size_t size, size_t count)
- {
- # if OGRE_ENDIAN == OGRE_ENDIAN_BIG
- flipEndian(pData, size, count);
- # endif
- }
- //--------------------------------------------------------------------------------------------
- void flipFromLittleEndian(void* pData, size_t size, size_t count)
- {
- # if OGRE_ENDIAN == OGRE_ENDIAN_BIG
- flipEndian(pData, size, count);
- # endif
- }
- //--------------------------------------------------------------------------------------------
- void flipEndian(void * pData, size_t size, size_t count)
- {
- for(size_t index = 0; index < count; index++)
- {
- flipEndian((void *)((int)pData + (index * size)), size);
- }
- }
- //--------------------------------------------------------------------------------------------
- void flipEndian(void * pData, size_t size)
- {
- char swapByte;
- for(size_t byteIndex = 0; byteIndex < size/2; byteIndex++)
- {
- swapByte = *(char *)((int)pData + byteIndex);
- *(char *)((int)pData + byteIndex) = *(char *)((int)pData + size - byteIndex - 1);
- *(char *)((int)pData + size - byteIndex - 1) = swapByte;
- }
- }
- //---------------------------------------------------------------------
- void Writer::writeFloats(const float* pFloat, size_t count)
- {
- # if OGRE_ENDIAN == OGRE_ENDIAN_BIG
- float * pFloatToWrite = (float *)malloc(sizeof(float) * count);
- memcpy(pFloatToWrite, pFloat, sizeof(float) * count);
- flipToLittleEndian(pFloatToWrite, sizeof(float), count);
- _write(pFloatToWrite, sizeof(float), count);
- free(pFloatToWrite);
- # else
- _write(pFloat, sizeof(float), count);
- # endif
- }
- //---------------------------------------------------------------------
- void Writer::writeFloats(const double* pDouble, size_t count)
- {
- // Convert to float, then write
- float* tmp = new float[count];
- for (size_t i = 0; i < count; ++i)
- {
- tmp[i] = static_cast<float>(pDouble[i]);
- }
- # if OGRE_ENDIAN == OGRE_ENDIAN_BIG
- flipToLittleEndian(tmp, sizeof(float), count);
- _write(tmp, sizeof(float), count);
- # else
- _write(tmp, sizeof(float), count);
- # endif
- delete [] tmp;
- }
- //---------------------------------------------------------------------
- void Writer::writeShorts(const uint16* pShort, size_t count)
- {
- # if OGRE_ENDIAN == OGRE_ENDIAN_BIG
- uint16 * pShortToWrite = (uint16 *)malloc(sizeof(uint16) * count);
- memcpy(pShortToWrite, pShort, sizeof(uint16) * count);
- flipToLittleEndian(pShortToWrite, sizeof(uint16), count);
- _write(pShortToWrite, sizeof(uint16), count);
- free(pShortToWrite);
- # else
- _write(pShort, sizeof(uint16), count);
- # endif
- }
- //---------------------------------------------------------------------
- void Writer::writeInts(const uint32* pInt, size_t count)
- {
- # if OGRE_ENDIAN == OGRE_ENDIAN_BIG
- uint32 * pIntToWrite = (uint32 *)malloc(sizeof(uint32) * count);
- memcpy(pIntToWrite, pInt, sizeof(uint32) * count);
- flipToLittleEndian(pIntToWrite, sizeof(uint32), count);
- _write(pIntToWrite, sizeof(uint32), count);
- free(pIntToWrite);
- # else
- _write(pInt, sizeof(uint32), count);
- # endif
- }
- //---------------------------------------------------------------------
- void Writer::writeBools(const bool* pBool, size_t count)
- {
- // no endian flipping for 1-byte bools
- // XXX Nasty Hack to convert to 1-byte bools
- # if OGRE_PLATFORM == OGRE_PLATFORM_APPLE
- char * pCharToWrite = (char *)malloc(sizeof(char) * count);
- for(int i = 0; i < count; i++)
- {
- *(char *)(pCharToWrite + i) = *(bool *)(pBool + i);
- }
- _write(pCharToWrite, sizeof(char), count);
- free(pCharToWrite);
- # else
- _write(pBool, sizeof(bool), count);
- # endif
- }
- //---------------------------------------------------------------------
- void Writer::writeString(const String& string)
- {
- uint32 numChars = string.length();
- writeInts(&numChars);
- _write(string.c_str(), sizeof(String::value_type), numChars);
- }
- //---------------------------------------------------------------------
- void Writer::writeObject(const Ogre::Vector3& v)
- {
- writeFloats(&v.x);
- writeFloats(&v.y);
- writeFloats(&v.z);
- }
- //---------------------------------------------------------------------
- void Writer::writeObject(const Ogre::Quaternion& q)
- {
- writeFloats(&q.x);
- writeFloats(&q.y);
- writeFloats(&q.z);
- writeFloats(&q.w);
- }
- //---------------------------------------------------------------------
- void Writer::writeData(const void* data, size_t size)
- {
- _write(data, size, 1);
- }
- //---------------------------------------------------------------------
- void Reader::readFloats(float* pFloat, size_t count)
- {
- _read(pFloat, sizeof(float), count);
- flipFromLittleEndian(pFloat, sizeof(float), count);
- }
- //---------------------------------------------------------------------
- void Reader::readFloats(double* pDouble, size_t count)
- {
- // Read from float, convert to double
- float* tmp = new float[count];
- float* ptmp = tmp;
- _read(tmp, sizeof(float), count);
- flipFromLittleEndian(tmp, sizeof(float), count);
- // Convert to doubles (no cast required)
- while (count--)
- {
- *pDouble++ = *ptmp++;
- }
- delete [] tmp;
- }
- //---------------------------------------------------------------------
- void Reader::readShorts(uint16* pShort, size_t count)
- {
- _read(pShort, sizeof(uint16), count);
- flipFromLittleEndian(pShort, sizeof(uint16), count);
- }
- //---------------------------------------------------------------------
- void Reader::readInts(uint32* pInt, size_t count)
- {
- _read(pInt, sizeof(uint32), count);
- flipFromLittleEndian(pInt, sizeof(uint32), count);
- }
- //---------------------------------------------------------------------
- void Reader::readBools(bool* pBool, size_t count)
- {
- //XXX Nasty Hack to convert 1 byte bools to 4 byte bools
- # if OGRE_PLATFORM == OGRE_PLATFORM_APPLE
- char * pTemp = (char *)malloc(1*count); // to hold 1-byte bools
- _read(pTemp, sizeof(char), count);
- for(int i = 0; i < count; i++)
- *(bool *)(pBool + i) = *(char *)(pTemp + i);
- free (pTemp);
- # else
- _read(pBool, sizeof(bool), count);
- # endif
- //no flipping on 1-byte datatypes
- }
- //---------------------------------------------------------------------
- String Reader::readString(size_t numChars)
- {
- String str(numChars, '/0');
- _read(const_cast<String::value_type*>(str.data()), sizeof(String::value_type), numChars);
- return str;
- }
- //---------------------------------------------------------------------
- String Reader::readString(void)
- {
- uint32 numChars;
- readInts(&numChars);
- return readString(numChars);
- }
- //---------------------------------------------------------------------
- void Reader::readObject(Ogre::Vector3& v)
- {
- readFloats(&v.x);
- readFloats(&v.y);
- readFloats(&v.z);
- }
- //---------------------------------------------------------------------
- void Reader::readObject(Ogre::Quaternion& q)
- {
- readFloats(&q.x);
- readFloats(&q.y);
- readFloats(&q.z);
- readFloats(&q.w);
- }
- //---------------------------------------------------------------------
- void Reader::readData(void* data, size_t size)
- {
- _read(data, size, 1);
- }
- //--------------------------------------------------------------------------------------------
- void FileWriter::_write(const void* buf, size_t size, size_t count)
- {
- if (fwrite(buf, size, count, mFile) != count)
- {
- OGRE_EXCEPT(Ogre::Exception::ERR_CANNOT_WRITE_TO_FILE,
- "Can't write data to file",
- "FileWriter::_write");
- }
- }
- //--------------------------------------------------------------------------------------------
- void DataStreamReader::_read(void* buf, size_t size, size_t count)
- {
- if (mStream->read(buf, size * count) != size * count)
- {
- OGRE_EXCEPT(Ogre::Exception::ERR_INTERNAL_ERROR,
- "Can't read data from stream",
- "DataStreamReader::_read");
- }
- }
- }
怎么用呢,举个例子,我们读取和写入高度图
- namespace Core
- {
- const uint32 TERRAIN_HEIGHTMAP_MAGIC = 'FEHM';
- const uint32 TERRAIN_HEIGHTMAP_VERSION = 0x00100000;
- //------------------------------------------------------------------------------------------------
- void TerrainData::_loadHeightmap(const String& filename, const String& type, const String& groupName)
- {
- // 分配buffer
- mHeightmap.resize((mXSize + 1) * (mZSize + 1));
- if (filename.empty())
- {
- std::fill(mHeightmap.begin(), mHeightmap.end(), (Real)0);
- }
- else if (type == "image")
- {
- // 省略
- }
- else if (type == "standard")
- {
- Ogre::DataStreamPtr stream = Ogre::ResourceGroupManager::getSingleton().openResource(filename, groupName);
- DataStreamReader reader(stream);
- // 文件头校验
- uint32 header[4];
- reader.readInts(header, 4);
- if (header[0] != TERRAIN_HEIGHTMAP_MAGIC)
- {
- // 异常
- }
- if (header[1] != TERRAIN_HEIGHTMAP_VERSION)
- {
- // 异常
- }
- if (header[2] != mXSize+1 || header[3] != mZSize+1)
- {
- // 异常
- }
- // 读取高度数据
- reader.readFloats(&mHeightmap[0], mHeightmap.size());
- // 文件尾校验
- if (stream->tell() != stream->size())
- {
- // 异常
- }
- }
- else
- {
- assert(type == "raw");
- // 省略
- }
- }
- //-----------------------------------------------------------------------------------------------------------------
- void TerrainData::_saveHeightmap(const String& filename) const
- {
- FileWriter writer(filename);
- // 写文件头
- uint32 header[4];
- header[0] = TERRAIN_HEIGHTMAP_MAGIC;
- header[1] = TERRAIN_HEIGHTMAP_VERSION;
- header[2] = mXSize + 1;
- header[3] = mZSize + 1;
- writer.writeInts(header, 4);
- // 写数据
- writer.writeFloats(&mHeightmap[0], mHeightmap.size());
- }
- }
- 天龙八部二进制文件 读写序列化类
- 天龙八部二进制文件 读写序列化类
- 读写二进制文件
- 读写二进制文件
- 读写二进制文件
- 二进制文件读写
- 二进制文件读写
- 二进制文件读写
- 读写二进制文件
- 二进制文件读写
- 读写二进制文件
- 二进制文件读写
- 读写二进制文件
- 读写二进制文件
- 二进制文件读写
- 读写二进制文件
- 读写二进制文件
- 二进制文件读写
- 偶有感想
- 字符串处理函数学习整理之二 strcat
- 在VC++ 6.0 或 Visual Studio中设置包含链接库lib文件(无法解析的外部符号 __imp__WSAStartup 的解决方案)
- linux驱动之--fops的关联
- flexlib开源组件库
- 天龙八部二进制文件 读写序列化类
- 子网掩码的作用
- 论坛?疑惑不解的
- Python的内建sort方法
- Going green
- 笔记--JDK1.5之新特性--2011/9/4 10:57
- Dedecms织梦系统数据库备份还原方法
- window下开发iphone程序环境搭建---iphone tool chain
- BackgroundWorker使用入门