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
|
bool CAssetID::IsValid() const
|
||||||
{
|
{
|
||||||
if (mLength == e32Bit)
|
return *this != InvalidID(mLength);
|
||||||
return (*this != skInvalidID32);
|
|
||||||
|
|
||||||
else if (mLength == e64Bit)
|
|
||||||
return (*this != skInvalidID64);
|
|
||||||
|
|
||||||
else return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ************ STATIC ************
|
// ************ STATIC ************
|
||||||
|
|
|
@ -81,7 +81,11 @@ HEADERS += \
|
||||||
Serialization/IArchive.h \
|
Serialization/IArchive.h \
|
||||||
Serialization/CXMLWriter.h \
|
Serialization/CXMLWriter.h \
|
||||||
Serialization/CXMLReader.h \
|
Serialization/CXMLReader.h \
|
||||||
EGame.h
|
EGame.h \
|
||||||
|
Serialization/CBasicBinaryWriter.h \
|
||||||
|
Serialization/CBasicBinaryReader.h \
|
||||||
|
Serialization/CBinaryWriter.h \
|
||||||
|
Serialization/CBinaryReader.h
|
||||||
|
|
||||||
# Source Files
|
# Source Files
|
||||||
SOURCES += \
|
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:
|
public:
|
||||||
CXMLReader(const TString& rkFileName)
|
CXMLReader(const TString& rkFileName)
|
||||||
: IArchive()
|
: IArchive(true, false)
|
||||||
, mJustEndedParam(false)
|
, mJustEndedParam(false)
|
||||||
{
|
{
|
||||||
// Load XML and set current element to the root element; read version
|
// Load XML and set current element to the root element; read version
|
||||||
|
@ -26,12 +26,7 @@ public:
|
||||||
mGame = pkGameAttr ? GetGameForID( CFourCC(pkGameAttr) ) : eUnknownGame;
|
mGame = pkGameAttr ? GetGameForID( CFourCC(pkGameAttr) ) : eUnknownGame;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
// Interface
|
||||||
// Interface Implementation
|
|
||||||
bool IsReader() const { return true; }
|
|
||||||
bool IsWriter() const { return false; }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
virtual bool ParamBegin(const char *pkName)
|
virtual bool ParamBegin(const char *pkName)
|
||||||
{
|
{
|
||||||
// Push new parent if needed
|
// Push new parent if needed
|
||||||
|
@ -82,6 +77,7 @@ protected:
|
||||||
mJustEndedParam = true;
|
mJustEndedParam = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
TString ReadParam()
|
TString ReadParam()
|
||||||
{
|
{
|
||||||
return TString(mpCurElem->GetText());
|
return TString(mpCurElem->GetText());
|
||||||
|
|
|
@ -14,7 +14,7 @@ class CXMLWriter : public IArchive
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CXMLWriter(const TString& rkFileName, const TString& rkRootName, u32 FileVersion, EGame Game = eUnknownGame)
|
CXMLWriter(const TString& rkFileName, const TString& rkRootName, u32 FileVersion, EGame Game = eUnknownGame)
|
||||||
: IArchive()
|
: IArchive(false, true)
|
||||||
, mOutFilename(rkFileName)
|
, mOutFilename(rkFileName)
|
||||||
{
|
{
|
||||||
mFileVersion = FileVersion;
|
mFileVersion = FileVersion;
|
||||||
|
@ -38,11 +38,7 @@ public:
|
||||||
mDoc.SaveFile(*mOutFilename);
|
mDoc.SaveFile(*mOutFilename);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Interface Implementation
|
// Interface
|
||||||
bool IsReader() const { return false; }
|
|
||||||
bool IsWriter() const { return true; }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
virtual bool ParamBegin(const char *pkName)
|
virtual bool ParamBegin(const char *pkName)
|
||||||
{
|
{
|
||||||
tinyxml2::XMLElement *pElem = mDoc.NewElement(pkName);
|
tinyxml2::XMLElement *pElem = mDoc.NewElement(pkName);
|
||||||
|
@ -56,6 +52,7 @@ protected:
|
||||||
mpCurElem = mpCurElem->Parent()->ToElement();
|
mpCurElem = mpCurElem->Parent()->ToElement();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
void WriteParam(const char *pkValue)
|
void WriteParam(const char *pkValue)
|
||||||
{
|
{
|
||||||
mpCurElem->SetText(pkValue);
|
mpCurElem->SetText(pkValue);
|
||||||
|
|
|
@ -169,11 +169,20 @@ protected:
|
||||||
s32 mFileVersion;
|
s32 mFileVersion;
|
||||||
s32 mArchiveVersion;
|
s32 mArchiveVersion;
|
||||||
EGame mGame;
|
EGame mGame;
|
||||||
|
bool mIsReader;
|
||||||
|
bool mIsWriter;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static const u32 skCurrentArchiveVersion = 0;
|
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() {}
|
virtual ~IArchive() {}
|
||||||
|
|
||||||
#define ENABLE_FOR_SERIAL_TYPE(SType) typename std::enable_if<SerialType<ValType, IArchive>::Type == SerialType<ValType, IArchive>::##SType, int>::type = 0
|
#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
|
// Interface
|
||||||
virtual bool IsReader() const = 0;
|
|
||||||
virtual bool IsWriter() const = 0;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
virtual bool ParamBegin(const char *pkName) = 0;
|
virtual bool ParamBegin(const char *pkName) = 0;
|
||||||
virtual void ParamEnd() = 0;
|
virtual void ParamEnd() = 0;
|
||||||
|
|
||||||
public:
|
|
||||||
virtual void SerializeContainerSize(u32& rSize) = 0;
|
virtual void SerializeContainerSize(u32& rSize) = 0;
|
||||||
virtual void SerializeAbstractObjectType(u32& rType) = 0;
|
virtual void SerializeAbstractObjectType(u32& rType) = 0;
|
||||||
|
|
||||||
|
@ -394,6 +398,8 @@ public:
|
||||||
inline u32 FileVersion() const { return mFileVersion; }
|
inline u32 FileVersion() const { return mFileVersion; }
|
||||||
inline u32 ArchiveVersion() const { return mArchiveVersion; }
|
inline u32 ArchiveVersion() const { return mArchiveVersion; }
|
||||||
inline EGame Game() const { return mGame; }
|
inline EGame Game() const { return mGame; }
|
||||||
|
inline bool IsReader() const { return mIsReader; }
|
||||||
|
inline bool IsWriter() const { return mIsWriter; }
|
||||||
};
|
};
|
||||||
|
|
||||||
// Container serialize methods
|
// Container serialize methods
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
|
|
||||||
class CResourceIterator
|
class CResourceIterator
|
||||||
{
|
{
|
||||||
|
protected:
|
||||||
CResourceStore *mpStore;
|
CResourceStore *mpStore;
|
||||||
std::map<CAssetID, CResourceEntry*>::iterator mIter;
|
std::map<CAssetID, CResourceEntry*>::iterator mIter;
|
||||||
CResourceEntry *mpCurEntry;
|
CResourceEntry *mpCurEntry;
|
||||||
|
@ -19,7 +20,7 @@ public:
|
||||||
Next();
|
Next();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline CResourceEntry* Next()
|
virtual CResourceEntry* Next()
|
||||||
{
|
{
|
||||||
if (mIter != mpStore->mResourceEntries.end())
|
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
|
#endif // CRESOURCEITERATOR
|
||||||
|
|
||||||
|
|
|
@ -33,13 +33,10 @@ public:
|
||||||
|
|
||||||
inline void Serialize(IArchive& rArc)
|
inline void Serialize(IArchive& rArc)
|
||||||
{
|
{
|
||||||
bool IsReader = rArc.IsReader();
|
CAssetID ID = (mpRes && !rArc.IsReader() ? mpRes->ID() : CAssetID::InvalidID(rArc.Game()));
|
||||||
EGame ActiveGame = gpResourceStore->ActiveProject()->Game();
|
|
||||||
|
|
||||||
CAssetID ID = (mpRes && !IsReader ? mpRes->ID() : (ActiveGame <= eEchoes ? CAssetID::skInvalidID32 : CAssetID::skInvalidID64));
|
|
||||||
rArc.SerializePrimitive(ID);
|
rArc.SerializePrimitive(ID);
|
||||||
|
|
||||||
if (IsReader)
|
if (rArc.IsReader())
|
||||||
{
|
{
|
||||||
CResourceEntry *pEntry = gpResourceStore->FindEntry(ID);
|
CResourceEntry *pEntry = gpResourceStore->FindEntry(ID);
|
||||||
*this = (pEntry ? pEntry->Load() : nullptr);
|
*this = (pEntry ? pEntry->Load() : nullptr);
|
||||||
|
|
|
@ -65,10 +65,10 @@ void CFileOutStream::Close()
|
||||||
mSize = 0;
|
mSize = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CFileOutStream::WriteBytes(void *pSrc, unsigned long Count)
|
void CFileOutStream::WriteBytes(const void *pkSrc, unsigned long Count)
|
||||||
{
|
{
|
||||||
if (!IsValid()) return;
|
if (!IsValid()) return;
|
||||||
fwrite(pSrc, 1, Count, mpFStream);
|
fwrite(pkSrc, 1, Count, mpFStream);
|
||||||
if ((unsigned long) Tell() > mSize) mSize = Tell();
|
if ((unsigned long) Tell() > mSize) mSize = Tell();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,7 @@ public:
|
||||||
void Update(const std::string& rkFile, IOUtil::EEndianness FileEndianness);
|
void Update(const std::string& rkFile, IOUtil::EEndianness FileEndianness);
|
||||||
void Close();
|
void Close();
|
||||||
|
|
||||||
void WriteBytes(void *pSrc, unsigned long Count);
|
void WriteBytes(const void *pkSrc, unsigned long Count);
|
||||||
bool Seek(long Offset, long Origin);
|
bool Seek(long Offset, long Origin);
|
||||||
bool Seek64(long long Offset, long Origin);
|
bool Seek64(long long Offset, long Origin);
|
||||||
long Tell() const;
|
long Tell() const;
|
||||||
|
|
|
@ -26,11 +26,11 @@ void CMemoryOutStream::SetData(void *pData, unsigned long Size, IOUtil::EEndiann
|
||||||
mDataEndianness = DataEndianness;
|
mDataEndianness = DataEndianness;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMemoryOutStream::WriteBytes(void *pSrc, unsigned long Count)
|
void CMemoryOutStream::WriteBytes(const void *pkSrc, unsigned long Count)
|
||||||
{
|
{
|
||||||
if (!IsValid()) return;
|
if (!IsValid()) return;
|
||||||
|
|
||||||
memcpy(mpDataStart + mPos, pSrc, Count);
|
memcpy(mpDataStart + mPos, pkSrc, Count);
|
||||||
mPos += Count;
|
mPos += Count;
|
||||||
if (mPos > mUsed) mUsed = mPos;
|
if (mPos > mUsed) mUsed = mPos;
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,7 @@ public:
|
||||||
~CMemoryOutStream();
|
~CMemoryOutStream();
|
||||||
void SetData(void *pData, unsigned long Size, IOUtil::EEndianness mDataEndianness);
|
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);
|
bool Seek(long Offset, long Origin);
|
||||||
long Tell() const;
|
long Tell() const;
|
||||||
bool EoF() const;
|
bool EoF() const;
|
||||||
|
|
|
@ -41,14 +41,14 @@ CVectorOutStream::~CVectorOutStream()
|
||||||
if (mOwnsVector) delete mpVector;
|
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 (!IsValid()) return;
|
||||||
|
|
||||||
if ((mPos + Count) > mpVector->size())
|
if ((mPos + Count) > mpVector->size())
|
||||||
mpVector->resize(mPos + Count);
|
mpVector->resize(mPos + Count);
|
||||||
|
|
||||||
memcpy(mpVector->data() + mPos, pSrc, Count);
|
memcpy(mpVector->data() + mPos, pkSrc, Count);
|
||||||
mPos += Count;
|
mPos += Count;
|
||||||
if (mPos > mUsed) mUsed = mPos;
|
if (mPos > mUsed) mUsed = mPos;
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,7 @@ public:
|
||||||
CVectorOutStream(std::vector<char> *pVector, IOUtil::EEndianness DataEndianness);
|
CVectorOutStream(std::vector<char> *pVector, IOUtil::EEndianness DataEndianness);
|
||||||
~CVectorOutStream();
|
~CVectorOutStream();
|
||||||
|
|
||||||
void WriteBytes(void *pSrc, unsigned long Count);
|
void WriteBytes(const void *pkSrc, unsigned long Count);
|
||||||
bool Seek(long Offset, long Origin);
|
bool Seek(long Offset, long Origin);
|
||||||
long Tell() const;
|
long Tell() const;
|
||||||
bool EoF() const;
|
bool EoF() const;
|
||||||
|
|
|
@ -84,6 +84,14 @@ std::string IInputStream::ReadString(unsigned long Count)
|
||||||
return Str;
|
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 IInputStream::ReadWString()
|
||||||
{
|
{
|
||||||
std::wstring WStr;
|
std::wstring WStr;
|
||||||
|
@ -108,6 +116,13 @@ std::wstring IInputStream::ReadWString(unsigned long Count)
|
||||||
return WStr;
|
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()
|
char IInputStream::PeekByte()
|
||||||
{
|
{
|
||||||
|
|
|
@ -21,8 +21,10 @@ public:
|
||||||
double ReadDouble();
|
double ReadDouble();
|
||||||
std::string ReadString();
|
std::string ReadString();
|
||||||
std::string ReadString(unsigned long Count);
|
std::string ReadString(unsigned long Count);
|
||||||
|
std::string ReadSizedString();
|
||||||
std::wstring ReadWString();
|
std::wstring ReadWString();
|
||||||
std::wstring ReadWString(unsigned long Count);
|
std::wstring ReadWString(unsigned long Count);
|
||||||
|
std::wstring ReadSizedWString();
|
||||||
|
|
||||||
char PeekByte();
|
char PeekByte();
|
||||||
short PeekShort();
|
short PeekShort();
|
||||||
|
|
|
@ -63,6 +63,12 @@ void IOutputStream::WriteString(const std::string& rkVal, unsigned long Count, b
|
||||||
WriteByte(0);
|
WriteByte(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void IOutputStream::WriteSizedString(const std::string& rkVal)
|
||||||
|
{
|
||||||
|
WriteLong(rkVal.size());
|
||||||
|
WriteBytes(rkVal.data(), rkVal.size());
|
||||||
|
}
|
||||||
|
|
||||||
void IOutputStream::WriteWideString(const std::wstring& rkVal)
|
void IOutputStream::WriteWideString(const std::wstring& rkVal)
|
||||||
{
|
{
|
||||||
for (unsigned int iChr = 0; iChr < rkVal.size(); iChr++)
|
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);
|
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)
|
void IOutputStream::WriteToBoundary(unsigned long Boundary, unsigned char Fill)
|
||||||
{
|
{
|
||||||
long Num = Boundary - (Tell() % Boundary);
|
long Num = Boundary - (Tell() % Boundary);
|
||||||
|
|
|
@ -20,8 +20,10 @@ public:
|
||||||
void WriteDouble(double Val);
|
void WriteDouble(double Val);
|
||||||
void WriteString(const std::string& rkVal);
|
void WriteString(const std::string& rkVal);
|
||||||
void WriteString(const std::string& rkVal, unsigned long Count, bool Terminate = false);
|
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);
|
||||||
void WriteWideString(const std::wstring& rkVal, unsigned long Count, bool Terminate = false);
|
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 WriteToBoundary(unsigned long Boundary, unsigned char Fill);
|
||||||
void SetEndianness(IOUtil::EEndianness Endianness);
|
void SetEndianness(IOUtil::EEndianness Endianness);
|
||||||
|
@ -30,7 +32,7 @@ public:
|
||||||
std::string GetDestString() const;
|
std::string GetDestString() const;
|
||||||
|
|
||||||
virtual ~IOutputStream();
|
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 Seek(long Offset, long Origin) = 0;
|
||||||
virtual bool Seek64(long long Offset, long Origin);
|
virtual bool Seek64(long long Offset, long Origin);
|
||||||
virtual long Tell() const = 0;
|
virtual long Tell() const = 0;
|
||||||
|
|
Loading…
Reference in New Issue