Implemented binary serializer classes
This commit is contained in:
parent
9a243f94ac
commit
3dc0d71403
|
@ -68,13 +68,7 @@ TString CAssetID::ToString() const
|
|||
|
||||
bool CAssetID::IsValid() const
|
||||
{
|
||||
if (mLength == e32Bit)
|
||||
return (*this != skInvalidID32);
|
||||
|
||||
else if (mLength == e64Bit)
|
||||
return (*this != skInvalidID64);
|
||||
|
||||
else return false;
|
||||
return *this != InvalidID(mLength);
|
||||
}
|
||||
|
||||
// ************ STATIC ************
|
||||
|
|
|
@ -81,7 +81,11 @@ HEADERS += \
|
|||
Serialization/IArchive.h \
|
||||
Serialization/CXMLWriter.h \
|
||||
Serialization/CXMLReader.h \
|
||||
EGame.h
|
||||
EGame.h \
|
||||
Serialization/CBasicBinaryWriter.h \
|
||||
Serialization/CBasicBinaryReader.h \
|
||||
Serialization/CBinaryWriter.h \
|
||||
Serialization/CBinaryReader.h
|
||||
|
||||
# Source Files
|
||||
SOURCES += \
|
||||
|
|
|
@ -0,0 +1,78 @@
|
|||
#ifndef CBASICBINARYREADER
|
||||
#define CBASICBINARYREADER
|
||||
|
||||
#include "IArchive.h"
|
||||
#include "Common/CFourCC.h"
|
||||
#include <FileIO/IInputStream.h>
|
||||
|
||||
// This is a basic binary reader that doesn't do any checks on parameter names.
|
||||
// This is the fastest serializer, but it relies entirely on parameter order so
|
||||
// changes to file structure will break old versions of the file. Use carefully!
|
||||
class CBasicBinaryReader : public IArchive
|
||||
{
|
||||
IInputStream *mpStream;
|
||||
bool mOwnsStream;
|
||||
|
||||
public:
|
||||
CBasicBinaryReader(const TString& rkFilename, IOUtil::EEndianness = IOUtil::eLittleEndian)
|
||||
: IArchive(true, false)
|
||||
, mOwnsStream(true)
|
||||
{
|
||||
mpStream = new CFileInStream(rkFilename.ToStdString(), IOUtil::eBigEndian);
|
||||
ASSERT(mpStream->IsValid());
|
||||
|
||||
mFileVersion = mpStream->ReadShort();
|
||||
mArchiveVersion = mpStream->ReadShort();
|
||||
mGame = GetGameForID( CFourCC(*mpStream) );
|
||||
}
|
||||
|
||||
CBasicBinaryReader(IInputStream *pStream)
|
||||
: IArchive(true, false)
|
||||
, mOwnsStream(false)
|
||||
{
|
||||
ASSERT(pStream->IsValid());
|
||||
mpStream = pStream;
|
||||
|
||||
mFileVersion = mpStream->ReadShort();
|
||||
mArchiveVersion = mpStream->ReadShort();
|
||||
mGame = GetGameForID( CFourCC(*mpStream) );
|
||||
}
|
||||
|
||||
~CBasicBinaryReader()
|
||||
{
|
||||
if (mOwnsStream) delete mpStream;
|
||||
}
|
||||
|
||||
// Interface
|
||||
virtual bool ParamBegin(const char*) { return true; }
|
||||
virtual void ParamEnd() { }
|
||||
|
||||
virtual void SerializeContainerSize(u32& rSize) { SerializePrimitive(rSize); }
|
||||
virtual void SerializeAbstractObjectType(u32& rType) { SerializePrimitive(rType); }
|
||||
virtual void SerializePrimitive(bool& rValue) { rValue = mpStream->ReadBool(); }
|
||||
virtual void SerializePrimitive(char& rValue) { rValue = mpStream->ReadByte(); }
|
||||
virtual void SerializePrimitive(s8& rValue) { rValue = mpStream->ReadByte(); }
|
||||
virtual void SerializePrimitive(u8& rValue) { rValue = mpStream->ReadByte(); }
|
||||
virtual void SerializePrimitive(s16& rValue) { rValue = mpStream->ReadShort(); }
|
||||
virtual void SerializePrimitive(u16& rValue) { rValue = mpStream->ReadShort(); }
|
||||
virtual void SerializePrimitive(s32& rValue) { rValue = mpStream->ReadLong(); }
|
||||
virtual void SerializePrimitive(u32& rValue) { rValue = mpStream->ReadLong(); }
|
||||
virtual void SerializePrimitive(s64& rValue) { rValue = mpStream->ReadLongLong(); }
|
||||
virtual void SerializePrimitive(u64& rValue) { rValue = mpStream->ReadLongLong(); }
|
||||
virtual void SerializePrimitive(float& rValue) { rValue = mpStream->ReadFloat(); }
|
||||
virtual void SerializePrimitive(double& rValue) { rValue = mpStream->ReadDouble(); }
|
||||
virtual void SerializePrimitive(TString& rValue) { rValue = mpStream->ReadSizedString(); }
|
||||
virtual void SerializePrimitive(CAssetID& rValue) { rValue = CAssetID(*mpStream, mGame); }
|
||||
|
||||
virtual void SerializeHexPrimitive(s8& rValue) { rValue = mpStream->ReadByte(); }
|
||||
virtual void SerializeHexPrimitive(u8& rValue) { rValue = mpStream->ReadByte(); }
|
||||
virtual void SerializeHexPrimitive(s16& rValue) { rValue = mpStream->ReadShort(); }
|
||||
virtual void SerializeHexPrimitive(u16& rValue) { rValue = mpStream->ReadShort(); }
|
||||
virtual void SerializeHexPrimitive(s32& rValue) { rValue = mpStream->ReadLong(); }
|
||||
virtual void SerializeHexPrimitive(u32& rValue) { rValue = mpStream->ReadLong(); }
|
||||
virtual void SerializeHexPrimitive(s64& rValue) { rValue = mpStream->ReadLongLong(); }
|
||||
virtual void SerializeHexPrimitive(u64& rValue) { rValue = mpStream->ReadLongLong(); }
|
||||
};
|
||||
|
||||
#endif // CBASICBINARYREADER
|
||||
|
|
@ -0,0 +1,84 @@
|
|||
#ifndef CBASICBINARYWRITER
|
||||
#define CBASICBINARYWRITER
|
||||
|
||||
#include "IArchive.h"
|
||||
#include "Common/CFourCC.h"
|
||||
#include <FileIO/IOutputStream.h>
|
||||
|
||||
// This is a basic binary reader that doesn't do any checks on parameter names.
|
||||
// This is the fastest serializer, but it relies entirely on parameter order so
|
||||
// changes to file structure will break old versions of the file. Use carefully!
|
||||
class CBasicBinaryWriter : public IArchive
|
||||
{
|
||||
IOutputStream *mpStream;
|
||||
bool mOwnsStream;
|
||||
|
||||
public:
|
||||
CBasicBinaryWriter(const TString& rkFilename, u32 FileVersion, EGame Game = eUnknownGame, IOUtil::EEndianness = IOUtil::eLittleEndian)
|
||||
: IArchive(false, true)
|
||||
, mOwnsStream(true)
|
||||
{
|
||||
mpStream = new CFileOutStream(rkFilename.ToStdString(), IOUtil::eBigEndian);
|
||||
ASSERT(mpStream->IsValid());
|
||||
|
||||
mFileVersion = FileVersion;
|
||||
mGame = Game;
|
||||
|
||||
mpStream->WriteShort((u16) FileVersion);
|
||||
mpStream->WriteShort((u16) skCurrentArchiveVersion);
|
||||
GetGameID(Game).Write(*mpStream);
|
||||
}
|
||||
|
||||
CBasicBinaryWriter(IOutputStream *pStream, u32 FileVersion, EGame Game = eUnknownGame)
|
||||
: IArchive(false, true)
|
||||
, mOwnsStream(false)
|
||||
{
|
||||
ASSERT(pStream->IsValid());
|
||||
mpStream = pStream;
|
||||
|
||||
mFileVersion = FileVersion;
|
||||
mGame = Game;
|
||||
|
||||
mpStream->WriteShort((u16) FileVersion);
|
||||
mpStream->WriteShort((u16) skCurrentArchiveVersion);
|
||||
GetGameID(Game).Write(*mpStream);
|
||||
}
|
||||
|
||||
~CBasicBinaryWriter()
|
||||
{
|
||||
if (mOwnsStream) delete mpStream;
|
||||
}
|
||||
|
||||
// Interface
|
||||
virtual bool ParamBegin(const char*) { return true; }
|
||||
virtual void ParamEnd() { }
|
||||
|
||||
virtual void SerializeContainerSize(u32& rSize) { SerializePrimitive(rSize); }
|
||||
virtual void SerializeAbstractObjectType(u32& rType) { SerializePrimitive(rType); }
|
||||
virtual void SerializePrimitive(bool& rValue) { mpStream->WriteBool(rValue); }
|
||||
virtual void SerializePrimitive(char& rValue) { mpStream->WriteByte(rValue); }
|
||||
virtual void SerializePrimitive(s8& rValue) { mpStream->WriteByte(rValue); }
|
||||
virtual void SerializePrimitive(u8& rValue) { mpStream->WriteByte(rValue); }
|
||||
virtual void SerializePrimitive(s16& rValue) { mpStream->WriteShort(rValue); }
|
||||
virtual void SerializePrimitive(u16& rValue) { mpStream->WriteShort(rValue); }
|
||||
virtual void SerializePrimitive(s32& rValue) { mpStream->WriteLong(rValue); }
|
||||
virtual void SerializePrimitive(u32& rValue) { mpStream->WriteLong(rValue); }
|
||||
virtual void SerializePrimitive(s64& rValue) { mpStream->WriteLongLong(rValue); }
|
||||
virtual void SerializePrimitive(u64& rValue) { mpStream->WriteLongLong(rValue); }
|
||||
virtual void SerializePrimitive(float& rValue) { mpStream->WriteFloat(rValue); }
|
||||
virtual void SerializePrimitive(double& rValue) { mpStream->WriteDouble(rValue); }
|
||||
virtual void SerializePrimitive(TString& rValue) { mpStream->WriteSizedString(rValue.ToStdString()); }
|
||||
virtual void SerializePrimitive(CAssetID& rValue) { rValue.Write(*mpStream); }
|
||||
|
||||
virtual void SerializeHexPrimitive(s8& rValue) { mpStream->WriteByte(rValue); }
|
||||
virtual void SerializeHexPrimitive(u8& rValue) { mpStream->WriteByte(rValue); }
|
||||
virtual void SerializeHexPrimitive(s16& rValue) { mpStream->WriteShort(rValue); }
|
||||
virtual void SerializeHexPrimitive(u16& rValue) { mpStream->WriteShort(rValue); }
|
||||
virtual void SerializeHexPrimitive(s32& rValue) { mpStream->WriteLong(rValue); }
|
||||
virtual void SerializeHexPrimitive(u32& rValue) { mpStream->WriteLong(rValue); }
|
||||
virtual void SerializeHexPrimitive(s64& rValue) { mpStream->WriteLongLong(rValue); }
|
||||
virtual void SerializeHexPrimitive(u64& rValue) { mpStream->WriteLongLong(rValue); }
|
||||
};
|
||||
|
||||
#endif // CBASICBINARYWRITER
|
||||
|
|
@ -0,0 +1,148 @@
|
|||
#ifndef CBINARYREADER
|
||||
#define CBINARYREADER
|
||||
|
||||
#include "IArchive.h"
|
||||
#include "Common/CFourCC.h"
|
||||
|
||||
class CBinaryReader : public IArchive
|
||||
{
|
||||
struct SParameter
|
||||
{
|
||||
u32 Offset;
|
||||
u16 Size;
|
||||
bool HasChildren;
|
||||
};
|
||||
std::vector<SParameter> mParamStack;
|
||||
|
||||
IInputStream *mpStream;
|
||||
bool mOwnsStream;
|
||||
|
||||
public:
|
||||
CBinaryReader(const TString& rkFilename)
|
||||
: IArchive(true, false)
|
||||
, mOwnsStream(true)
|
||||
{
|
||||
mpStream = new CFileInStream(rkFilename.ToStdString(), IOUtil::eBigEndian);
|
||||
ASSERT(mpStream->IsValid());
|
||||
|
||||
mFileVersion = mpStream->ReadShort();
|
||||
mArchiveVersion = mpStream->ReadShort();
|
||||
mGame = GetGameForID( CFourCC(*mpStream) );
|
||||
|
||||
mParamStack.reserve(20);
|
||||
}
|
||||
|
||||
CBinaryReader(IInputStream *pStream)
|
||||
: IArchive(true, false)
|
||||
, mOwnsStream(false)
|
||||
{
|
||||
ASSERT(pStream->IsValid());
|
||||
mpStream = pStream;
|
||||
|
||||
mFileVersion = mpStream->ReadShort();
|
||||
mArchiveVersion = mpStream->ReadShort();
|
||||
mGame = GetGameForID( CFourCC(*mpStream) );
|
||||
|
||||
mParamStack.reserve(20);
|
||||
}
|
||||
|
||||
~CBinaryReader()
|
||||
{
|
||||
if (mOwnsStream) delete mpStream;
|
||||
}
|
||||
|
||||
// Interface
|
||||
virtual bool ParamBegin(const char *pkName)
|
||||
{
|
||||
// If this is the parent parameter's first child, then skip the child count
|
||||
if (!mParamStack.empty() && !mParamStack.back().HasChildren)
|
||||
{
|
||||
mpStream->Seek(0x2, SEEK_CUR);
|
||||
mParamStack.back().HasChildren = true;
|
||||
}
|
||||
|
||||
// Check the next parameter ID first and check whether it's a match for the current parameter
|
||||
u32 ParamID = TString(pkName).Hash32();
|
||||
u32 Offset = mpStream->Tell();
|
||||
u32 NextID = mpStream->ReadLong();
|
||||
u16 NextSize = mpStream->ReadShort();
|
||||
|
||||
// Does the next parameter ID match the current one?
|
||||
if (NextID == ParamID)
|
||||
{
|
||||
mParamStack.push_back( SParameter { Offset, NextSize, false } );
|
||||
return true;
|
||||
}
|
||||
|
||||
// It's not a match - return to the parent parameter's first child and check all children to find a match
|
||||
if (!mParamStack.empty())
|
||||
{
|
||||
u32 ParentOffset = mParamStack.back().Offset;
|
||||
mpStream->Seek(ParentOffset, SEEK_SET);
|
||||
mpStream->Seek(0x6, SEEK_CUR);
|
||||
u16 NumChildren = mpStream->ReadShort();
|
||||
|
||||
for (u32 iChild = 0; iChild < NumChildren; iChild++)
|
||||
{
|
||||
u32 ChildID = mpStream->ReadLong();
|
||||
u16 ChildSize = mpStream->ReadShort();
|
||||
|
||||
if (ChildID != ParamID)
|
||||
mpStream->Seek(ChildSize, SEEK_CUR);
|
||||
else
|
||||
{
|
||||
mParamStack.push_back( SParameter { mpStream->Tell() - 6, NextSize, false } );
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// None of the children were a match - this parameter isn't in the file
|
||||
mpStream->Seek(Offset, SEEK_SET);
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual void ParamEnd()
|
||||
{
|
||||
// Make sure we're at the end of the parameter
|
||||
SParameter& rParam = mParamStack.back();
|
||||
u32 EndOffset = rParam.Offset + rParam.Size + 6;
|
||||
mpStream->Seek(EndOffset, SEEK_SET);
|
||||
mParamStack.pop_back();
|
||||
}
|
||||
|
||||
void SerializeContainerSize(u32& rSize)
|
||||
{
|
||||
// Mostly handled by ParamBegin, we just need to return the size correctly so the container can be resized
|
||||
rSize = (u32) mpStream->PeekShort();
|
||||
}
|
||||
|
||||
void SerializeAbstractObjectType(u32& rType) { rType = mpStream->ReadLong(); }
|
||||
|
||||
void SerializePrimitive(bool& rValue) { rValue = mpStream->ReadBool(); }
|
||||
void SerializePrimitive(char& rValue) { rValue = mpStream->ReadByte(); }
|
||||
void SerializePrimitive(s8& rValue) { rValue = mpStream->ReadByte(); }
|
||||
void SerializePrimitive(u8& rValue) { rValue = mpStream->ReadByte(); }
|
||||
void SerializePrimitive(s16& rValue) { rValue = mpStream->ReadShort(); }
|
||||
void SerializePrimitive(u16& rValue) { rValue = mpStream->ReadShort(); }
|
||||
void SerializePrimitive(s32& rValue) { rValue = mpStream->ReadLong(); }
|
||||
void SerializePrimitive(u32& rValue) { rValue = mpStream->ReadLong(); }
|
||||
void SerializePrimitive(s64& rValue) { rValue = mpStream->ReadLongLong(); }
|
||||
void SerializePrimitive(u64& rValue) { rValue = mpStream->ReadLongLong(); }
|
||||
void SerializePrimitive(float& rValue) { rValue = mpStream->ReadFloat(); }
|
||||
void SerializePrimitive(double& rValue) { rValue = mpStream->ReadDouble(); }
|
||||
void SerializePrimitive(TString& rValue) { rValue = mpStream->ReadSizedString(); }
|
||||
void SerializePrimitive(CAssetID& rValue) { rValue = CAssetID(*mpStream, Game()); }
|
||||
|
||||
void SerializeHexPrimitive(s8& rValue) { rValue = mpStream->ReadByte(); }
|
||||
void SerializeHexPrimitive(u8& rValue) { rValue = mpStream->ReadByte(); }
|
||||
void SerializeHexPrimitive(s16& rValue) { rValue = mpStream->ReadShort(); }
|
||||
void SerializeHexPrimitive(u16& rValue) { rValue = mpStream->ReadShort(); }
|
||||
void SerializeHexPrimitive(s32& rValue) { rValue = mpStream->ReadLong(); }
|
||||
void SerializeHexPrimitive(u32& rValue) { rValue = mpStream->ReadLong(); }
|
||||
void SerializeHexPrimitive(s64& rValue) { rValue = mpStream->ReadLongLong(); }
|
||||
void SerializeHexPrimitive(u64& rValue) { rValue = mpStream->ReadLongLong(); }
|
||||
};
|
||||
|
||||
#endif // CBINARYREADER
|
||||
|
|
@ -0,0 +1,123 @@
|
|||
#ifndef CBINARYWRITER
|
||||
#define CBINARYWRITER
|
||||
|
||||
#include "IArchive.h"
|
||||
#include "Common/CFourCC.h"
|
||||
|
||||
class CBinaryWriter : public IArchive
|
||||
{
|
||||
struct SParameter
|
||||
{
|
||||
u32 Offset;
|
||||
u16 NumSubParams;
|
||||
};
|
||||
std::vector<SParameter> mParamStack;
|
||||
|
||||
IOutputStream *mpStream;
|
||||
bool mOwnsStream;
|
||||
|
||||
public:
|
||||
CBinaryWriter(const TString& rkFilename, u32 FileVersion, EGame Game = eUnknownGame)
|
||||
: IArchive(false, true)
|
||||
, mOwnsStream(true)
|
||||
{
|
||||
mpStream = new CFileOutStream(rkFilename.ToStdString(), IOUtil::eBigEndian);
|
||||
ASSERT(mpStream->IsValid());
|
||||
|
||||
mFileVersion = FileVersion;
|
||||
mGame = Game;
|
||||
|
||||
mpStream->WriteShort((u16) FileVersion);
|
||||
mpStream->WriteShort((u16) skCurrentArchiveVersion);
|
||||
GetGameID(Game).Write(*mpStream);
|
||||
}
|
||||
|
||||
CBinaryWriter(IOutputStream *pStream, u32 FileVersion, EGame Game = eUnknownGame)
|
||||
: IArchive(false, true)
|
||||
, mOwnsStream(false)
|
||||
{
|
||||
ASSERT(pStream->IsValid());
|
||||
mpStream = pStream;
|
||||
|
||||
mFileVersion = FileVersion;
|
||||
mGame = Game;
|
||||
|
||||
mpStream->WriteShort((u16) FileVersion);
|
||||
mpStream->WriteShort((u16) skCurrentArchiveVersion);
|
||||
GetGameID(Game).Write(*mpStream);
|
||||
}
|
||||
|
||||
~CBinaryWriter()
|
||||
{
|
||||
if (mOwnsStream) delete mpStream;
|
||||
}
|
||||
|
||||
// Interface
|
||||
virtual bool ParamBegin(const char *pkName)
|
||||
{
|
||||
if (!mParamStack.empty())
|
||||
{
|
||||
mParamStack.back().NumSubParams++;
|
||||
|
||||
if (mParamStack.back().NumSubParams == 1)
|
||||
mpStream->WriteShort(-1); // Sub-param count filler
|
||||
}
|
||||
|
||||
mParamStack.push_back( SParameter { mpStream->Tell(), 0 } );
|
||||
|
||||
u32 ParamID = TString(pkName).Hash32();
|
||||
mpStream->WriteLong(ParamID);
|
||||
mpStream->WriteShort((u16) 0xFFFF); // Param size filler
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual void ParamEnd()
|
||||
{
|
||||
SParameter& rParam = mParamStack.back();
|
||||
u32 StartOffset = rParam.Offset;
|
||||
u32 EndOffset = mpStream->Tell();
|
||||
u16 ParamSize = (EndOffset - StartOffset) - 6;
|
||||
|
||||
mpStream->Seek(StartOffset + 4, SEEK_SET);
|
||||
mpStream->WriteShort(ParamSize);
|
||||
if (rParam.NumSubParams > 0) mpStream->WriteShort(rParam.NumSubParams);
|
||||
mpStream->Seek(EndOffset, SEEK_SET);
|
||||
mParamStack.pop_back();
|
||||
}
|
||||
|
||||
void SerializeContainerSize(u32& rSize)
|
||||
{
|
||||
// Normally handled by ParamBegin and ParamEnd but we need to do something here to account for zero-sized containers
|
||||
if (rSize == 0)
|
||||
mpStream->WriteShort(0);
|
||||
}
|
||||
|
||||
void SerializeAbstractObjectType(u32& rType) { mpStream->WriteLong(rType); }
|
||||
|
||||
void SerializePrimitive(bool& rValue) { mpStream->WriteBool(rValue); }
|
||||
void SerializePrimitive(char& rValue) { mpStream->WriteByte(rValue); }
|
||||
void SerializePrimitive(s8& rValue) { mpStream->WriteByte(rValue); }
|
||||
void SerializePrimitive(u8& rValue) { mpStream->WriteByte(rValue); }
|
||||
void SerializePrimitive(s16& rValue) { mpStream->WriteShort(rValue); }
|
||||
void SerializePrimitive(u16& rValue) { mpStream->WriteShort(rValue); }
|
||||
void SerializePrimitive(s32& rValue) { mpStream->WriteLong(rValue); }
|
||||
void SerializePrimitive(u32& rValue) { mpStream->WriteLong(rValue); }
|
||||
void SerializePrimitive(s64& rValue) { mpStream->WriteLongLong(rValue); }
|
||||
void SerializePrimitive(u64& rValue) { mpStream->WriteLongLong(rValue); }
|
||||
void SerializePrimitive(float& rValue) { mpStream->WriteFloat(rValue); }
|
||||
void SerializePrimitive(double& rValue) { mpStream->WriteDouble(rValue); }
|
||||
void SerializePrimitive(TString& rValue) { mpStream->WriteSizedString(rValue.ToStdString()); }
|
||||
void SerializePrimitive(CAssetID& rValue) { rValue.Write(*mpStream); }
|
||||
|
||||
void SerializeHexPrimitive(s8& rValue) { mpStream->WriteByte(rValue); }
|
||||
void SerializeHexPrimitive(u8& rValue) { mpStream->WriteByte(rValue); }
|
||||
void SerializeHexPrimitive(s16& rValue) { mpStream->WriteShort(rValue); }
|
||||
void SerializeHexPrimitive(u16& rValue) { mpStream->WriteShort(rValue); }
|
||||
void SerializeHexPrimitive(s32& rValue) { mpStream->WriteLong(rValue); }
|
||||
void SerializeHexPrimitive(u32& rValue) { mpStream->WriteLong(rValue); }
|
||||
void SerializeHexPrimitive(s64& rValue) { mpStream->WriteLongLong(rValue); }
|
||||
void SerializeHexPrimitive(u64& rValue) { mpStream->WriteLongLong(rValue); }
|
||||
};
|
||||
|
||||
#endif // CBINARYWRITER
|
||||
|
|
@ -12,7 +12,7 @@ class CXMLReader : public IArchive
|
|||
|
||||
public:
|
||||
CXMLReader(const TString& rkFileName)
|
||||
: IArchive()
|
||||
: IArchive(true, false)
|
||||
, mJustEndedParam(false)
|
||||
{
|
||||
// Load XML and set current element to the root element; read version
|
||||
|
@ -26,12 +26,7 @@ public:
|
|||
mGame = pkGameAttr ? GetGameForID( CFourCC(pkGameAttr) ) : eUnknownGame;
|
||||
}
|
||||
|
||||
protected:
|
||||
// Interface Implementation
|
||||
bool IsReader() const { return true; }
|
||||
bool IsWriter() const { return false; }
|
||||
|
||||
protected:
|
||||
// Interface
|
||||
virtual bool ParamBegin(const char *pkName)
|
||||
{
|
||||
// Push new parent if needed
|
||||
|
@ -82,6 +77,7 @@ protected:
|
|||
mJustEndedParam = true;
|
||||
}
|
||||
|
||||
protected:
|
||||
TString ReadParam()
|
||||
{
|
||||
return TString(mpCurElem->GetText());
|
||||
|
|
|
@ -14,7 +14,7 @@ class CXMLWriter : public IArchive
|
|||
|
||||
public:
|
||||
CXMLWriter(const TString& rkFileName, const TString& rkRootName, u32 FileVersion, EGame Game = eUnknownGame)
|
||||
: IArchive()
|
||||
: IArchive(false, true)
|
||||
, mOutFilename(rkFileName)
|
||||
{
|
||||
mFileVersion = FileVersion;
|
||||
|
@ -38,11 +38,7 @@ public:
|
|||
mDoc.SaveFile(*mOutFilename);
|
||||
}
|
||||
|
||||
// Interface Implementation
|
||||
bool IsReader() const { return false; }
|
||||
bool IsWriter() const { return true; }
|
||||
|
||||
protected:
|
||||
// Interface
|
||||
virtual bool ParamBegin(const char *pkName)
|
||||
{
|
||||
tinyxml2::XMLElement *pElem = mDoc.NewElement(pkName);
|
||||
|
@ -56,6 +52,7 @@ protected:
|
|||
mpCurElem = mpCurElem->Parent()->ToElement();
|
||||
}
|
||||
|
||||
protected:
|
||||
void WriteParam(const char *pkValue)
|
||||
{
|
||||
mpCurElem->SetText(pkValue);
|
||||
|
|
|
@ -169,11 +169,20 @@ protected:
|
|||
s32 mFileVersion;
|
||||
s32 mArchiveVersion;
|
||||
EGame mGame;
|
||||
bool mIsReader;
|
||||
bool mIsWriter;
|
||||
|
||||
public:
|
||||
static const u32 skCurrentArchiveVersion = 0;
|
||||
|
||||
IArchive() : mFileVersion(0), mArchiveVersion(skCurrentArchiveVersion), mGame(eUnknownGame) {}
|
||||
IArchive(bool IsReader, bool IsWriter)
|
||||
: mFileVersion(0)
|
||||
, mArchiveVersion(skCurrentArchiveVersion)
|
||||
, mGame(eUnknownGame)
|
||||
, mIsReader(IsReader)
|
||||
, mIsWriter(IsWriter)
|
||||
{}
|
||||
|
||||
virtual ~IArchive() {}
|
||||
|
||||
#define ENABLE_FOR_SERIAL_TYPE(SType) typename std::enable_if<SerialType<ValType, IArchive>::Type == SerialType<ValType, IArchive>::##SType, int>::type = 0
|
||||
|
@ -355,14 +364,9 @@ public:
|
|||
}
|
||||
|
||||
// Interface
|
||||
virtual bool IsReader() const = 0;
|
||||
virtual bool IsWriter() const = 0;
|
||||
|
||||
protected:
|
||||
virtual bool ParamBegin(const char *pkName) = 0;
|
||||
virtual void ParamEnd() = 0;
|
||||
|
||||
public:
|
||||
virtual void SerializeContainerSize(u32& rSize) = 0;
|
||||
virtual void SerializeAbstractObjectType(u32& rType) = 0;
|
||||
|
||||
|
@ -394,6 +398,8 @@ public:
|
|||
inline u32 FileVersion() const { return mFileVersion; }
|
||||
inline u32 ArchiveVersion() const { return mArchiveVersion; }
|
||||
inline EGame Game() const { return mGame; }
|
||||
inline bool IsReader() const { return mIsReader; }
|
||||
inline bool IsWriter() const { return mIsWriter; }
|
||||
};
|
||||
|
||||
// Container serialize methods
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
class CResourceIterator
|
||||
{
|
||||
protected:
|
||||
CResourceStore *mpStore;
|
||||
std::map<CAssetID, CResourceEntry*>::iterator mIter;
|
||||
CResourceEntry *mpCurEntry;
|
||||
|
@ -19,7 +20,7 @@ public:
|
|||
Next();
|
||||
}
|
||||
|
||||
inline CResourceEntry* Next()
|
||||
virtual CResourceEntry* Next()
|
||||
{
|
||||
if (mIter != mpStore->mResourceEntries.end())
|
||||
{
|
||||
|
@ -65,5 +66,22 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
template<class ResType>
|
||||
class TResourceIterator : public CResourceIterator
|
||||
{
|
||||
public:
|
||||
TResourceIterator(CResourceStore *pStore = gpResourceStore)
|
||||
: CResourceIterator(pStore) {}
|
||||
|
||||
virtual CResourceEntry* Next()
|
||||
{
|
||||
do {
|
||||
CResourceIterator::Next();
|
||||
} while (mpCurEntry && mpCurEntry->ResourceType() != ResType::StaticType());
|
||||
|
||||
return mpCurEntry;
|
||||
}
|
||||
};
|
||||
|
||||
#endif // CRESOURCEITERATOR
|
||||
|
||||
|
|
|
@ -33,13 +33,10 @@ public:
|
|||
|
||||
inline void Serialize(IArchive& rArc)
|
||||
{
|
||||
bool IsReader = rArc.IsReader();
|
||||
EGame ActiveGame = gpResourceStore->ActiveProject()->Game();
|
||||
|
||||
CAssetID ID = (mpRes && !IsReader ? mpRes->ID() : (ActiveGame <= eEchoes ? CAssetID::skInvalidID32 : CAssetID::skInvalidID64));
|
||||
CAssetID ID = (mpRes && !rArc.IsReader() ? mpRes->ID() : CAssetID::InvalidID(rArc.Game()));
|
||||
rArc.SerializePrimitive(ID);
|
||||
|
||||
if (IsReader)
|
||||
if (rArc.IsReader())
|
||||
{
|
||||
CResourceEntry *pEntry = gpResourceStore->FindEntry(ID);
|
||||
*this = (pEntry ? pEntry->Load() : nullptr);
|
||||
|
|
|
@ -65,10 +65,10 @@ void CFileOutStream::Close()
|
|||
mSize = 0;
|
||||
}
|
||||
|
||||
void CFileOutStream::WriteBytes(void *pSrc, unsigned long Count)
|
||||
void CFileOutStream::WriteBytes(const void *pkSrc, unsigned long Count)
|
||||
{
|
||||
if (!IsValid()) return;
|
||||
fwrite(pSrc, 1, Count, mpFStream);
|
||||
fwrite(pkSrc, 1, Count, mpFStream);
|
||||
if ((unsigned long) Tell() > mSize) mSize = Tell();
|
||||
}
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@ public:
|
|||
void Update(const std::string& rkFile, IOUtil::EEndianness FileEndianness);
|
||||
void Close();
|
||||
|
||||
void WriteBytes(void *pSrc, unsigned long Count);
|
||||
void WriteBytes(const void *pkSrc, unsigned long Count);
|
||||
bool Seek(long Offset, long Origin);
|
||||
bool Seek64(long long Offset, long Origin);
|
||||
long Tell() const;
|
||||
|
|
|
@ -26,11 +26,11 @@ void CMemoryOutStream::SetData(void *pData, unsigned long Size, IOUtil::EEndiann
|
|||
mDataEndianness = DataEndianness;
|
||||
}
|
||||
|
||||
void CMemoryOutStream::WriteBytes(void *pSrc, unsigned long Count)
|
||||
void CMemoryOutStream::WriteBytes(const void *pkSrc, unsigned long Count)
|
||||
{
|
||||
if (!IsValid()) return;
|
||||
|
||||
memcpy(mpDataStart + mPos, pSrc, Count);
|
||||
memcpy(mpDataStart + mPos, pkSrc, Count);
|
||||
mPos += Count;
|
||||
if (mPos > mUsed) mUsed = mPos;
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@ public:
|
|||
~CMemoryOutStream();
|
||||
void SetData(void *pData, unsigned long Size, IOUtil::EEndianness mDataEndianness);
|
||||
|
||||
void WriteBytes(void *pSrc, unsigned long Count);
|
||||
void WriteBytes(const void *pkSrc, unsigned long Count);
|
||||
bool Seek(long Offset, long Origin);
|
||||
long Tell() const;
|
||||
bool EoF() const;
|
||||
|
|
|
@ -41,14 +41,14 @@ CVectorOutStream::~CVectorOutStream()
|
|||
if (mOwnsVector) delete mpVector;
|
||||
}
|
||||
|
||||
void CVectorOutStream::WriteBytes(void *pSrc, unsigned long Count)
|
||||
void CVectorOutStream::WriteBytes(const void *pkSrc, unsigned long Count)
|
||||
{
|
||||
if (!IsValid()) return;
|
||||
|
||||
if ((mPos + Count) > mpVector->size())
|
||||
mpVector->resize(mPos + Count);
|
||||
|
||||
memcpy(mpVector->data() + mPos, pSrc, Count);
|
||||
memcpy(mpVector->data() + mPos, pkSrc, Count);
|
||||
mPos += Count;
|
||||
if (mPos > mUsed) mUsed = mPos;
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@ public:
|
|||
CVectorOutStream(std::vector<char> *pVector, IOUtil::EEndianness DataEndianness);
|
||||
~CVectorOutStream();
|
||||
|
||||
void WriteBytes(void *pSrc, unsigned long Count);
|
||||
void WriteBytes(const void *pkSrc, unsigned long Count);
|
||||
bool Seek(long Offset, long Origin);
|
||||
long Tell() const;
|
||||
bool EoF() const;
|
||||
|
|
|
@ -84,6 +84,14 @@ std::string IInputStream::ReadString(unsigned long Count)
|
|||
return Str;
|
||||
}
|
||||
|
||||
std::string IInputStream::ReadSizedString()
|
||||
{
|
||||
unsigned int StringSize = ReadLong();
|
||||
std::string Str(StringSize, 0);
|
||||
ReadBytes(&Str[0], Str.size());
|
||||
return Str;
|
||||
}
|
||||
|
||||
std::wstring IInputStream::ReadWString()
|
||||
{
|
||||
std::wstring WStr;
|
||||
|
@ -108,6 +116,13 @@ std::wstring IInputStream::ReadWString(unsigned long Count)
|
|||
return WStr;
|
||||
}
|
||||
|
||||
std::wstring IInputStream::ReadSizedWString()
|
||||
{
|
||||
unsigned int StringSize = ReadLong();
|
||||
std::wstring WStr(StringSize, 0);
|
||||
ReadBytes(&WStr[0], WStr.size() * 2);
|
||||
return WStr;
|
||||
}
|
||||
|
||||
char IInputStream::PeekByte()
|
||||
{
|
||||
|
|
|
@ -21,8 +21,10 @@ public:
|
|||
double ReadDouble();
|
||||
std::string ReadString();
|
||||
std::string ReadString(unsigned long Count);
|
||||
std::string ReadSizedString();
|
||||
std::wstring ReadWString();
|
||||
std::wstring ReadWString(unsigned long Count);
|
||||
std::wstring ReadSizedWString();
|
||||
|
||||
char PeekByte();
|
||||
short PeekShort();
|
||||
|
|
|
@ -63,6 +63,12 @@ void IOutputStream::WriteString(const std::string& rkVal, unsigned long Count, b
|
|||
WriteByte(0);
|
||||
}
|
||||
|
||||
void IOutputStream::WriteSizedString(const std::string& rkVal)
|
||||
{
|
||||
WriteLong(rkVal.size());
|
||||
WriteBytes(rkVal.data(), rkVal.size());
|
||||
}
|
||||
|
||||
void IOutputStream::WriteWideString(const std::wstring& rkVal)
|
||||
{
|
||||
for (unsigned int iChr = 0; iChr < rkVal.size(); iChr++)
|
||||
|
@ -81,6 +87,12 @@ void IOutputStream::WriteWideString(const std::wstring& rkVal, unsigned long Cou
|
|||
WriteShort(0);
|
||||
}
|
||||
|
||||
void IOutputStream::WriteSizedWideString(const std::wstring& rkVal)
|
||||
{
|
||||
WriteLong(rkVal.size());
|
||||
WriteBytes(rkVal.data(), rkVal.size() * 2);
|
||||
}
|
||||
|
||||
void IOutputStream::WriteToBoundary(unsigned long Boundary, unsigned char Fill)
|
||||
{
|
||||
long Num = Boundary - (Tell() % Boundary);
|
||||
|
|
|
@ -20,8 +20,10 @@ public:
|
|||
void WriteDouble(double Val);
|
||||
void WriteString(const std::string& rkVal);
|
||||
void WriteString(const std::string& rkVal, unsigned long Count, bool Terminate = false);
|
||||
void WriteSizedString(const std::string& rkVal);
|
||||
void WriteWideString(const std::wstring& rkVal);
|
||||
void WriteWideString(const std::wstring& rkVal, unsigned long Count, bool Terminate = false);
|
||||
void WriteSizedWideString(const std::wstring& rkVal);
|
||||
|
||||
void WriteToBoundary(unsigned long Boundary, unsigned char Fill);
|
||||
void SetEndianness(IOUtil::EEndianness Endianness);
|
||||
|
@ -30,7 +32,7 @@ public:
|
|||
std::string GetDestString() const;
|
||||
|
||||
virtual ~IOutputStream();
|
||||
virtual void WriteBytes(void *pSrc, unsigned long Count) = 0;
|
||||
virtual void WriteBytes(const void *pkSrc, unsigned long Count) = 0;
|
||||
virtual bool Seek(long Offset, long Origin) = 0;
|
||||
virtual bool Seek64(long long Offset, long Origin);
|
||||
virtual long Tell() const = 0;
|
||||
|
|
Loading…
Reference in New Issue