mirror of
https://github.com/AxioDL/LibCommon.git
synced 2026-03-30 11:47:23 -07:00
10a45dd4e9
Fixes cooking the majority of string tables, since some contain strings that consist of just a space.
165 lines
6.2 KiB
C++
165 lines
6.2 KiB
C++
#ifndef AXIO_CXMLREADER_H
|
|
#define AXIO_CXMLREADER_H
|
|
|
|
#include "Common/Log.h"
|
|
#include "Common/Serialization/IArchive.h"
|
|
#include "Common/Serialization/XMLCommon.h"
|
|
#include <tinyxml2.h>
|
|
|
|
class CXMLReader : public IArchive
|
|
{
|
|
tinyxml2::XMLDocument mDoc;
|
|
tinyxml2::XMLElement *mpCurElem = nullptr; // Points to the next element being read
|
|
const char* mpAttribute = nullptr; // Name of the parameter we are reading from an attribute
|
|
bool mJustEndedParam = false; // Indicates we just ended a primitive parameter
|
|
|
|
public:
|
|
explicit CXMLReader(const TString& rkFileName)
|
|
: mDoc(true, tinyxml2::PEDANTIC_WHITESPACE)
|
|
{
|
|
mArchiveFlags = AF_Reader | AF_Text;
|
|
|
|
// Load XML and set current element to the root element; read version
|
|
tinyxml2::XMLError Error = mDoc.LoadFile(rkFileName.CString());
|
|
|
|
if (Error != tinyxml2::XML_SUCCESS)
|
|
{
|
|
NLog::Error("{}: Failed to open XML for read: {}", rkFileName, XMLErrorString(Error));
|
|
}
|
|
else
|
|
{
|
|
mpCurElem = mDoc.FirstChildElement();
|
|
ASSERT(mpCurElem != nullptr);
|
|
SerializeVersion();
|
|
}
|
|
}
|
|
|
|
bool IsValid() const
|
|
{
|
|
return mpCurElem != nullptr;
|
|
}
|
|
|
|
// Interface
|
|
bool ParamBegin(const char *pkName, uint32_t Flags) override
|
|
{
|
|
ASSERT(IsValid());
|
|
ASSERT(!mpAttribute); // Attributes cannot have sub-children
|
|
|
|
// Store as an attribute if requested
|
|
if (Flags & SH_Attribute)
|
|
{
|
|
mpAttribute = mpCurElem->Attribute(pkName);
|
|
return mpAttribute != nullptr;
|
|
}
|
|
|
|
// Push new parent if needed
|
|
if (!mJustEndedParam)
|
|
{
|
|
tinyxml2::XMLElement *pChild = mpCurElem->FirstChildElement();
|
|
if (!pChild) return false;
|
|
else mpCurElem = pChild;
|
|
}
|
|
|
|
// Verify the current element matches the name of the next serialized parameter.
|
|
if ( (Flags & SH_IgnoreName) || strcmp(mpCurElem->Name(), pkName) == 0 )
|
|
{
|
|
mJustEndedParam = false;
|
|
return true;
|
|
}
|
|
|
|
// It didn't match, so we'll try to find a sibling element that does match.
|
|
// Iterate over all sibling elements - if we find a match we will continue
|
|
// reading from that point on. Otherwise we can't load this parameter.
|
|
tinyxml2::XMLElement *pSearchElem = mpCurElem->Parent()->FirstChildElement();
|
|
|
|
while (pSearchElem)
|
|
{
|
|
if ( strcmp(pSearchElem->Name(), pkName) == 0 )
|
|
{
|
|
mpCurElem = pSearchElem;
|
|
mJustEndedParam = false;
|
|
return true;
|
|
}
|
|
|
|
pSearchElem = pSearchElem->NextSiblingElement();
|
|
}
|
|
|
|
// We couldn't find a matching element, so we can't load this parameter.
|
|
// If we pushed a parent earlier, undo it.
|
|
if (!mJustEndedParam)
|
|
mpCurElem = mpCurElem->Parent()->ToElement();
|
|
|
|
return false;
|
|
}
|
|
|
|
void ParamEnd() override
|
|
{
|
|
if (mpAttribute)
|
|
mpAttribute = nullptr;
|
|
|
|
else
|
|
{
|
|
if (mJustEndedParam)
|
|
mpCurElem = mpCurElem->Parent()->ToElement();
|
|
|
|
tinyxml2::XMLElement *pElem = mpCurElem->NextSiblingElement();
|
|
if (pElem)
|
|
mpCurElem = pElem;
|
|
|
|
mJustEndedParam = true;
|
|
}
|
|
}
|
|
|
|
protected:
|
|
TString ReadParam()
|
|
{
|
|
return TString(mpAttribute ? mpAttribute : mpCurElem->GetText());
|
|
}
|
|
|
|
public:
|
|
void SerializeArraySize(uint32_t& Value) override
|
|
{
|
|
Value = 0;
|
|
|
|
for (tinyxml2::XMLElement *pElem = mpCurElem->FirstChildElement(); pElem; pElem = pElem->NextSiblingElement())
|
|
Value++;
|
|
}
|
|
|
|
bool PreSerializePointer(void*& InPointer, uint32_t Flags) override
|
|
{
|
|
return mpCurElem->GetText() == nullptr || strcmp(mpCurElem->GetText(), "NULL") != 0;
|
|
}
|
|
|
|
void SerializePrimitive(bool& rValue, uint32_t Flags) override { rValue = ReadParam() == "true"; }
|
|
void SerializePrimitive(char& rValue, uint32_t Flags) override { rValue = ReadParam().Front(); }
|
|
void SerializePrimitive(int8_t& rValue, uint32_t Flags) override { rValue = (int8_t)ReadParam().ToInt32((Flags & SH_HexDisplay) ? 16 : 0); }
|
|
void SerializePrimitive(uint8_t& rValue, uint32_t Flags) override { rValue = (uint8_t)ReadParam().ToInt32((Flags & SH_HexDisplay) ? 16 : 0); }
|
|
void SerializePrimitive(int16_t& rValue, uint32_t Flags) override { rValue = (int16_t)ReadParam().ToInt32((Flags & SH_HexDisplay) ? 16 : 0); }
|
|
void SerializePrimitive(uint16_t& rValue, uint32_t Flags) override { rValue = (uint16_t)ReadParam().ToInt32((Flags & SH_HexDisplay) ? 16 : 0); }
|
|
void SerializePrimitive(int32_t& rValue, uint32_t Flags) override { rValue = (int32_t)ReadParam().ToInt32((Flags & SH_HexDisplay) ? 16 : 0); }
|
|
void SerializePrimitive(uint32_t& rValue, uint32_t Flags) override { rValue = (uint32_t)ReadParam().ToInt32((Flags & SH_HexDisplay) ? 16 : 0); }
|
|
void SerializePrimitive(int64_t& rValue, uint32_t Flags) override { rValue = (int64_t)ReadParam().ToInt64((Flags & SH_HexDisplay) ? 16 : 0); }
|
|
void SerializePrimitive(uint64_t& rValue, uint32_t Flags) override { rValue = (uint64_t)ReadParam().ToInt64((Flags & SH_HexDisplay) ? 16 : 0); }
|
|
void SerializePrimitive(float& rValue, uint32_t Flags) override { rValue = ReadParam().ToFloat(); }
|
|
void SerializePrimitive(double& rValue, uint32_t Flags) override { rValue = (double)ReadParam().ToFloat(); }
|
|
void SerializePrimitive(TString& rValue, uint32_t Flags) override { rValue = ReadParam(); }
|
|
void SerializePrimitive(CFourCC& rValue, uint32_t Flags) override { rValue = CFourCC(ReadParam()); }
|
|
void SerializePrimitive(CAssetID& rValue, uint32_t Flags) override { rValue = CAssetID::FromString(ReadParam()); }
|
|
|
|
void SerializeBulkData(void* pData, uint32_t Size, uint32_t Flags) override
|
|
{
|
|
char* pCharData = (char*) pData;
|
|
TString StringData = ReadParam();
|
|
ASSERT(StringData.Size() == Size*2);
|
|
|
|
for (uint32_t ByteIdx = 0; ByteIdx < Size; ByteIdx++)
|
|
{
|
|
*pCharData = (char) StringData.SubString(ByteIdx*2, 2).ToInt32(16);
|
|
pCharData++;
|
|
}
|
|
}
|
|
};
|
|
|
|
#endif // AXIO_CXMLREADER_H
|
|
|