Implemented binary serializer classes

This commit is contained in:
parax0 2016-08-23 20:42:05 -06:00
parent 9a243f94ac
commit 3dc0d71403
21 changed files with 519 additions and 43 deletions

View File

@ -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 ************

View File

@ -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 += \

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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());

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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);

View File

@ -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();
}

View File

@ -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;

View File

@ -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;
}

View File

@ -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;

View File

@ -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;
}

View File

@ -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;

View File

@ -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()
{

View File

@ -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();

View File

@ -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);

View File

@ -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;