Legacy code cleanup - part 3 (#3903)

* Legacy cleanup - part 3

Not much is left that can be easily removed,
so I think this will be last cleanup before the legacy functionality is replaced.

Signed-off-by: nemerle <96597+nemerle@users.noreply.github.com>

* fix windows build, remove a few more things, re-add one file

Signed-off-by: nemerle <96597+nemerle@users.noreply.github.com>

* Remove legacy RenderBus + more cleanups

Signed-off-by: nemerle <96597+nemerle@users.noreply.github.com>

* Remove MaterialOwnerBus.h

Clean-up in Cry_Matrix34/33

Signed-off-by: nemerle <96597+nemerle@users.noreply.github.com>
This commit is contained in:
Artur K
2021-09-07 20:14:16 +02:00
committed by GitHub
parent 4d5b047c1b
commit 2a2847b15d
161 changed files with 894 additions and 16076 deletions
@@ -1,43 +0,0 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#ifndef CRYINCLUDE_CRYSYSTEM_XML_READWRITEXMLSINK_H
#define CRYINCLUDE_CRYSYSTEM_XML_READWRITEXMLSINK_H
#pragma once
#include <ISystem.h>
#include <IReadWriteXMLSink.h>
class CReadWriteXMLSink
: public IReadWriteXMLSink
{
public:
bool ReadXML(const char* definitionFile, const char* dataFile, IReadXMLSink* pSink);
bool ReadXML(const char* definitionFile, XmlNodeRef node, IReadXMLSink* pSink);
bool ReadXML(XmlNodeRef definition, const char* dataFile, IReadXMLSink* pSink);
bool ReadXML(XmlNodeRef definition, XmlNodeRef node, IReadXMLSink* pSink);
XmlNodeRef CreateXMLFromSource(const char* definitionFile, IWriteXMLSource* pSource);
bool WriteXML(const char* definitionFile, const char* dataFile, IWriteXMLSource* pSource);
};
// helper to define the if/else chain that we need in a few locations...
// types must match IReadXMLSink::TValueTypes
#define XML_SET_PROPERTY_HELPER(ELSE_LOAD_PROPERTY) \
if (false) {; } \
ELSE_LOAD_PROPERTY(Vec3); \
ELSE_LOAD_PROPERTY(int); \
ELSE_LOAD_PROPERTY(float); \
ELSE_LOAD_PROPERTY(AZStd::string); \
ELSE_LOAD_PROPERTY(bool);
#endif // CRYINCLUDE_CRYSYSTEM_XML_READWRITEXMLSINK_H
-683
View File
@@ -1,683 +0,0 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#include "CrySystem_precompiled.h"
#include "ReadWriteXMLSink.h"
#include <ISystem.h>
#include <stack>
typedef std::map<AZStd::string, XmlNodeRef> IdTable;
struct SParseParams
{
IdTable idTable;
XmlNodeRef useAlways;
bool strict;
SParseParams()
{
strict = true;
}
};
static XmlNodeRef Clone(XmlNodeRef source);
static void CopyAttributes(const XmlNodeRef& source, XmlNodeRef& dest);
static bool IsOptionalReadXML(const SParseParams& parseParams, XmlNodeRef& definition);
static bool CheckEnum(const SParseParams& parseParams, const char* name, XmlNodeRef& definition, XmlNodeRef& data);
static bool LoadTableInner(const SParseParams& parseParams, XmlNodeRef& definition, XmlNodeRef& data, IReadXMLSink* pSink);
static bool LoadArray(const SParseParams& parseParams, XmlNodeRef& definition, XmlNodeRef& data, IReadXMLSink* pSink);
static bool LoadProperty(const SParseParams& parseParams, XmlNodeRef& definition, XmlNodeRef& data, IReadXMLSink* pSink);
static bool LoadTable(const SParseParams& parseParams, XmlNodeRef& definition, XmlNodeRef& data, IReadXMLSink* pSink);
static bool LoadReferencedId(const SParseParams& parseParams, XmlNodeRef& definition, XmlNodeRef& data, IReadXMLSink* pSink);
static bool LoadSomething(const SParseParams& parseParams, XmlNodeRef& definition, XmlNodeRef& data, IReadXMLSink* pSink);
static bool LoadArraySetValueTable(const SParseParams& parseParams, XmlNodeRef& definition, XmlNodeRef& data, IReadXMLSink* pSink, int elem);
typedef bool (* LoadArraySetValue)(const SParseParams& parseParams, XmlNodeRef& definition, XmlNodeRef& data, IReadXMLSink* pSink, int elem);
typedef bool (* LoadDefinitionFunction)(const SParseParams& parseParams, XmlNodeRef& definition, XmlNodeRef& data, IReadXMLSink* pSink);
template <class T>
struct ReadPropertyTyped;
template <class T>
struct ReadPropertyTyped
{
static bool Load(const SParseParams& parseParams, const char* name, XmlNodeRef& definition, XmlNodeRef& data, IReadXMLSink* pSink)
{
T value;
memset(&value, 0, sizeof(T));
if (!pSink->IsCreationMode())
{
if (!data->haveAttr(name))
{
return false;
}
if (!data->getAttr(name, value))
{
return false;
}
if (!CheckEnum(parseParams, name, definition, data))
{
return false;
}
}
IReadXMLSink::TValue vvalue(value);
pSink->SetValue(name, vvalue, definition);
return true;
}
static bool LoadArray([[maybe_unused]] const SParseParams& parseParams, XmlNodeRef& definition, XmlNodeRef& data, IReadXMLSink* pSink, int elem)
{
T value;
memset(&value, 0, sizeof(T));
if (!pSink->IsCreationMode())
{
if (!data->haveAttr("value"))
{
return false;
}
if (!data->getAttr("value", value))
{
return false;
}
}
IReadXMLSink::TValue vvalue(value);
pSink->SetAt(elem, vvalue, definition);
return true;
}
};
template <>
struct ReadPropertyTyped<AZStd::string>
{
static bool Load(const SParseParams& parseParams, const char* name, XmlNodeRef& definition, XmlNodeRef& data, IReadXMLSink* pSink)
{
const char* value = 0;
if (!pSink->IsCreationMode())
{
if (!data->haveAttr(name))
{
return false;
}
if (!CheckEnum(parseParams, name, definition, data))
{
return false;
}
value = data->getAttr(name);
}
IReadXMLSink::TValue vvalue(value);
pSink->SetValue(name, vvalue, definition);
return true;
}
static bool LoadArray([[maybe_unused]] const SParseParams& parseParams, XmlNodeRef& definition, XmlNodeRef& data, IReadXMLSink* pSink, int elem)
{
const char* value = 0;
if (!pSink->IsCreationMode())
{
if (!data->haveAttr("value"))
{
return false;
}
value = data->getAttr("value");
}
IReadXMLSink::TValue vvalue(value);
pSink->SetAt(elem, vvalue, definition);
return true;
}
};
XmlNodeRef Clone(XmlNodeRef source)
{
assert(source != (IXmlNode*)NULL);
// Can't use clone() on XmlNodeRef objects since they can contain a CXMLBinaryNode, which doesn't support
// clone(). Instead we just create a regular xml node and manually copy content, tag, attributes and children
XmlNodeRef cloned = GetISystem()->CreateXmlNode(source->getTag());
cloned->setContent(source->getContent());
CopyAttributes(source, cloned);
const int iChildCount = source->getChildCount();
for (int i = 0; i < iChildCount; ++i)
{
cloned->addChild(Clone(source->getChild(i)));
}
return cloned;
}
void CopyAttributes(const XmlNodeRef& source, XmlNodeRef& dest)
{
// Not as fast as CXmlNode::copyAttributes(), but that method will have undefined behavior if the XmlNodeRef contains
// a CBinaryXmlNode object
int nNumAttributes = source->getNumAttributes();
for (int i = 0; i < nNumAttributes; ++i)
{
const char* key = NULL;
const char* value = NULL;
if (source->getAttributeByIndex(i, &key, &value))
{
dest->setAttr(key, value);
}
}
}
bool IsOptionalReadXML(const SParseParams& parseParams, XmlNodeRef& definition)
{
// If strict mode is off, then everything is optional
if (parseParams.strict == false)
{
return true;
}
bool optional = false;
definition->getAttr("optional", optional);
return optional;
}
bool CheckEnum([[maybe_unused]] const SParseParams& parseParams, [[maybe_unused]] const char* name, XmlNodeRef& definition, [[maybe_unused]] XmlNodeRef& data)
{
if (XmlNodeRef enumNode = definition->findChild("Enum"))
{
// If strict mode is off, then no need to check the enum value
return true;
}
return true;
}
bool LoadProperty(const SParseParams& parseParams, XmlNodeRef& definition, XmlNodeRef& data, IReadXMLSink* pSink)
{
const char* name = definition->getAttr("name");
if (0 == strlen(name))
{
CryLog("Property has no name");
return false;
}
const char* type = definition->getAttr("type");
if (0 == strlen(type))
{
CryLog("Property '%s' has no type", type);
return false;
}
XmlNodeRef dataToRead = data;
if (!pSink->IsCreationMode())
{
// This check is done so the data xml can specify child elements instead of attributes if desired,
// since the rest of the code assume only attributes
if (XmlNodeRef childRef = data->findChild(name))
{
if (data->haveAttr(name))
{
CryLog("Duplicate definition (attribute and element) for %s", name);
return false;
}
if (childRef->getChildCount())
{
CryLog("Property-style elements can not have children (property was %s)", name);
return false;
}
dataToRead = GetISystem()->CreateXmlNode(data->getTag());
AZStd::string content = childRef->getContent();
AZ::StringFunc::TrimWhiteSpace(content, true, true);
dataToRead->setAttr(name, content.c_str());
}
if (!dataToRead->haveAttr(name))
{
if (!IsOptionalReadXML(parseParams, definition))
{
CryLog("Failed to load property %s", name);
return false;
}
return true;
}
}
bool ok = false;
#define LOAD_PROPERTY(whichType) else if (0 == strcmp(type, #whichType)) ok = ReadPropertyTyped<whichType>::Load(parseParams, name, definition, dataToRead, pSink)
XML_SET_PROPERTY_HELPER(LOAD_PROPERTY);
#undef LOAD_PROPERTY
if (!ok)
{
CryLog("Failed loading attribute %s of type %s", name, type);
}
return ok;
}
bool LoadArraySetValueTable(const SParseParams& parseParams, XmlNodeRef& definition, XmlNodeRef& data, IReadXMLSink* pSink, int elem)
{
IReadXMLSinkPtr pChildSink = pSink->BeginTableAt(elem, definition);
if (pSink->IsCreationMode() && definition->haveAttr("type"))
{
if (!LoadSomething(parseParams, definition, data, &*pChildSink))
{
return false;
}
}
else
{
if (!LoadTableInner(parseParams, definition, data, &*pChildSink))
{
return false;
}
}
if (!pChildSink->EndTableAt(elem))
{
CryLog("Failed to finish table at element %d", elem);
return false;
}
return true;
}
bool LoadArray(const SParseParams& parseParams, XmlNodeRef& definition, XmlNodeRef& data, IReadXMLSink* pSink)
{
const char* name = definition->getAttr("name");
if (0 == strlen(name))
{
CryLog("Array has no name");
return false;
}
const char* elementName = definition->getAttr("elementName");
if (0 == strlen(elementName))
{
elementName = "element";
}
bool validateArray = true;
if (definition->haveAttr(elementName))
{
definition->getAttr("validate", validateArray);
}
XmlNodeRef childData;
if (!pSink->IsCreationMode())
{
childData = data->findChild(name);
if (!childData)
{
bool ok = IsOptionalReadXML(parseParams, definition);
if (!ok)
{
CryLog("Failed to load child table %s", name);
}
return ok;
}
}
IReadXMLSinkPtr childSink = pSink->BeginArray(name, definition);
if (!childSink)
{
CryLog("Failed to begin array named %s", name);
return false;
}
LoadArraySetValue setter = NULL;
if (definition->haveAttr("type"))
{
setter = NULL;
const char* type = definition->getAttr("type");
#define SETTER_PROPERTY(whichType) else if (0 == strcmp(type, #whichType)) setter = ReadPropertyTyped<whichType>::LoadArray
XML_SET_PROPERTY_HELPER(SETTER_PROPERTY);
#undef SETTER_PROPERTY
if (!setter)
{
CryLog("Unknown type %s in array %s", type, name);
return false;
}
}
else
{
setter = LoadArraySetValueTable;
}
if (!pSink->IsCreationMode())
{
int numElems = childData->getChildCount();
int elem = 1;
for (int i = 0; i < numElems; i++)
{
XmlNodeRef elemData = childData->getChild(i);
if (0 == strcmp(elemData->getTag(), elementName))
{
int increment = 1;
if (elemData->haveAttr("_index"))
{
if (!elemData->getAttr("_index", elem))
{
CryLog("_index is not an integer in array %s (pos hint=%d)", name, elem);
return false;
}
}
if (!setter(parseParams, definition, elemData, &*childSink, elem))
{
CryLog("Failed loading element %d of array %s", elem, name);
return false;
}
elem += increment;
}
else if (validateArray)
{
CryLog("Invalid node %s in array %s", elemData->getTag(), name);
return false;
}
}
}
else
{
// only process array content for the array being created
if (0 == strcmp(name, pSink->GetCreationNode()->getAttr("name")))
{
if (!setter(parseParams, definition, data, &*childSink, 1))
{
CryLog("[ReadXML CreationMode]: Failed loading element %d of array %s", 1, name);
return false;
}
}
}
if (!pSink->EndArray(name))
{
CryLog("Failed to finish array named %s", name);
return false;
}
return true;
}
bool LoadTable(const SParseParams& parseParams, XmlNodeRef& definition, XmlNodeRef& data, IReadXMLSink* pSink)
{
const char* name = definition->getAttr("name");
if (0 == strlen(name))
{
CryLog("Child-table has no name");
return false;
}
XmlNodeRef childData;
if (!pSink->IsCreationMode())
{
childData = data->findChild(name);
if (!childData)
{
bool ok = IsOptionalReadXML(parseParams, definition);
if (!ok)
{
CryLog("Failed to load child table %s", name);
}
return ok;
}
}
IReadXMLSinkPtr childSink = pSink->BeginTable(name, definition);
if (!childSink)
{
CryLog("Sink creation failed for table %s", name);
return false;
}
if (!LoadTableInner(parseParams, definition, childData, childSink))
{
CryLog("Failed to load data for child table %s", name);
return false;
}
if (!pSink->EndTable(name))
{
CryLog("Table %s failed to complete in sink", name);
return false;
}
return true;
}
bool LoadSomething(const SParseParams& parseParams, XmlNodeRef& nodeDefinition, XmlNodeRef& data, IReadXMLSink* pSink)
{
// Ignore if it's the useAlways array
if (parseParams.useAlways == nodeDefinition)
{
return true;
}
static struct
{
const char* name;
LoadDefinitionFunction loader;
} loaderTypes[] = {
{"Property", &LoadProperty},
{"Array", &LoadArray},
{"Table", &LoadTable},
{"Use", &LoadReferencedId},
};
static const int numLoaderTypes = sizeof(loaderTypes) / sizeof(*loaderTypes);
const char* nodeDefinitionTag = nodeDefinition->getTag();
bool ok = false;
int i;
for (i = 0; i < numLoaderTypes; i++)
{
if (0 == strcmp(loaderTypes[i].name, nodeDefinitionTag))
{
ok = loaderTypes[i].loader(parseParams, nodeDefinition, data, pSink);
break;
}
}
if (0 == _stricmp("Settings", nodeDefinitionTag))
{
return true;
}
if (!ok)
{
if (i == numLoaderTypes)
{
CryLog("Invalid definition node type %s, line %d", nodeDefinitionTag, nodeDefinition->getLine());
}
}
return ok;
}
bool LoadReferencedId(const SParseParams& parseParams, XmlNodeRef& definition, XmlNodeRef& data, IReadXMLSink* pSink)
{
IdTable::const_iterator iter = parseParams.idTable.find(definition->getAttr("id"));
if (iter == parseParams.idTable.end())
{
CryLog("No definition with id '%s'", definition->getAttr("id"));
return false;
}
XmlNodeRef useDefinition = Clone(iter->second);
CopyAttributes(definition, useDefinition);
return LoadSomething(parseParams, useDefinition, data, pSink);
}
bool LoadTableInner(const SParseParams& parseParams, XmlNodeRef& definition, XmlNodeRef& data, IReadXMLSink* pSink)
{
const int nChildrenDefinition = definition->getChildCount();
for (int nChildDefinition = 0; nChildDefinition < nChildrenDefinition; nChildDefinition++)
{
XmlNodeRef nodeDefinition = definition->getChild(nChildDefinition);
if (!LoadSomething(parseParams, nodeDefinition, data, pSink))
{
return false;
}
}
if (parseParams.useAlways != (IXmlNode*)NULL)
{
assert(!definition->haveAttr("type"));
const int nUseAlwaysDefCount = parseParams.useAlways->getChildCount();
for (int i = 0; i < nUseAlwaysDefCount; ++i)
{
XmlNodeRef nodeDefinition = parseParams.useAlways->getChild(i);
// Don't continue loading useAlways nodes in creation mode
if (!pSink->IsCreationMode())
{
if (!LoadSomething(parseParams, nodeDefinition, data, pSink))
{
return false;
}
}
}
}
return true;
}
bool CReadWriteXMLSink::ReadXML(XmlNodeRef rootDefinition, XmlNodeRef rootData, IReadXMLSink* pSink)
{
if (!pSink->IsCreationMode())
{
if (0 == rootData)
{
return false;
}
if (0 != strcmp(rootDefinition->getTag(), "Definition"))
{
CryLog("Root tag of definition file was %s; expected Definition", rootDefinition->getTag());
return false;
}
if (rootDefinition->haveAttr("root"))
{
if (0 != strcmp(rootDefinition->getAttr("root"), rootData->getTag()))
{
CryLog("Root data has wrong tag; was %s expected %s", rootData->getTag(), rootDefinition->getAttr("root"));
return false;
}
}
}
SParseParams parseParams;
parseParams.useAlways = rootDefinition->findChild("AllowAlways");
if (XmlNodeRef settingsParams = rootDefinition->findChild("Settings"))
{
settingsParams->getAttr("strict", parseParams.strict);
}
// scan for id's in the structure (for the Use member)
std::stack<XmlNodeRef> scanStack;
scanStack.push(rootDefinition);
while (!scanStack.empty())
{
XmlNodeRef refNode = scanStack.top();
scanStack.pop();
int numChildren = refNode->getChildCount();
const char* tag = refNode->getTag();
for (int i = 0; i < numChildren; i++)
{
const XmlNodeRef& childNodeRef = refNode->getChild(i);
if (parseParams.useAlways != childNodeRef)
{
scanStack.push(childNodeRef);
}
}
// If the element has an attribute id="" and is not a "<Use>" element add it to the idTable map
if (refNode->haveAttr("id") && 0 != strcmp("Use", tag))
{
parseParams.idTable[refNode->getAttr("id")] = refNode;
}
}
if (pSink->IsCreationMode() && rootDefinition->haveAttr("type"))
{
// if creating from a 0-child definition node, load itself
if (!LoadSomething(parseParams, rootDefinition, rootData, pSink))
{
return false;
}
}
else
{
// load content
if (!LoadTableInner(parseParams, rootDefinition, rootData, pSink))
{
return false;
}
}
bool ok = pSink->Complete();
if (!ok)
{
CryLog("Warning: sink failed to complete reading");
}
return ok;
}
bool CReadWriteXMLSink::ReadXML(XmlNodeRef definition, const char* dataFile, IReadXMLSink* pSink)
{
XmlNodeRef rootData = GetISystem()->LoadXmlFromFile(dataFile);
if (!rootData)
{
CryLog("Unable to load XML-Lua data file: %s", dataFile);
return false;
}
return ReadXML(definition, rootData, pSink);
}
bool CReadWriteXMLSink::ReadXML(const char* definitionFile, XmlNodeRef rootData, IReadXMLSink* pSink)
{
XmlNodeRef rootDefinition = GetISystem()->LoadXmlFromFile(definitionFile);
if (!rootDefinition)
{
CryLog("Unable to load XML-Lua definition file: %s", definitionFile);
return false;
}
return ReadXML(rootDefinition, rootData, pSink);
}
bool CReadWriteXMLSink::ReadXML(const char* definitionFile, const char* dataFile, IReadXMLSink* pSink)
{
XmlNodeRef rootData = GetISystem()->LoadXmlFromFile(dataFile);
if (!rootData)
{
CryLog("Unable to load XML-Lua data file: %s", dataFile);
return false;
}
if (!ReadXML(definitionFile, rootData, pSink))
{
CryLog("Unable to load file %s", dataFile);
return false;
}
return true;
}
@@ -104,23 +104,6 @@ bool CSerializeXMLReaderImpl::Value(const char* name, CTimeValue& value)
return true;
}
bool CSerializeXMLReaderImpl::Value(const char* name, XmlNodeRef& value)
{
DefaultValue(value); // Set input value to default.
if (m_nErrors)
{
return false;
}
if (BeginOptionalGroup(name, true))
{
value = CurNode()->getChild(0);
EndGroup();
}
return true;
}
void CSerializeXMLReaderImpl::BeginGroup(const char* szName)
{
if (m_nErrors)
@@ -173,32 +156,3 @@ void CSerializeXMLReaderImpl::EndGroup()
}
assert(!m_nodeStack.empty());
}
//////////////////////////////////////////////////////////////////////////
AZStd::string CSerializeXMLReaderImpl::GetStackInfo() const
{
AZStd::string str;
for (int i = 0; i < (int)m_nodeStack.size(); i++)
{
const char* name = m_nodeStack[i].m_node->getAttr(TAG_SCRIPT_NAME);
if (name && name[0])
{
str += name;
}
else
{
str += m_nodeStack[i].m_node->getTag();
}
if (i != m_nodeStack.size() - 1)
{
str += "/";
}
}
return str;
}
void CSerializeXMLReaderImpl::GetMemoryUsage(ICrySizer* pSizer) const
{
pSizer->Add(*this);
pSizer->AddContainer(m_nodeStack);
}
+2 -27
View File
@@ -6,22 +6,16 @@
*
*/
#ifndef CRYINCLUDE_CRYSYSTEM_XML_SERIALIZEXMLREADER_H
#define CRYINCLUDE_CRYSYSTEM_XML_SERIALIZEXMLREADER_H
#pragma once
#include "SimpleSerialize.h"
#include <stack>
#include <IXml.h>
#include <ITimer.h>
#include <IValidator.h>
#include <ISystem.h>
#include "xml.h"
class CSerializeXMLReaderImpl
: public CSimpleSerializeImpl<true, eST_SaveGame>
: public CSimpleSerializeImpl<true, ESerializationTarget::eST_SaveGame>
{
public:
CSerializeXMLReaderImpl(const XmlNodeRef& nodeRef);
@@ -41,7 +35,7 @@ public:
g_pXmlStrCmp = &strcmp; // Do case-sensitive compare
bool bReturn = node->haveAttr(name);
if (bReturn)
{
{
value = node->getAttr(name);
}
g_pXmlStrCmp = pPrevCmpFunc;
@@ -51,10 +45,6 @@ public:
{
return false;
}
ILINE bool GetAttr([[maybe_unused]] const XmlNodeRef& node, [[maybe_unused]] const char* name, [[maybe_unused]] SNetObjectID& value)
{
return false;
}
template <class T_Value>
bool Value(const char* name, T_Value& value)
@@ -77,23 +67,12 @@ public:
bool Value(const char* name, int8& value);
bool Value(const char* name, AZStd::string& value);
bool Value(const char* name, CTimeValue& value);
bool Value(const char* name, XmlNodeRef& value);
template <class T_Value, class T_Policy>
bool Value(const char* name, T_Value& value, [[maybe_unused]] const T_Policy& policy)
{
return Value(name, value);
}
void BeginGroup(const char* szName);
bool BeginOptionalGroup(const char* szName, bool condition);
void EndGroup();
AZStd::string GetStackInfo() const;
void GetMemoryUsage(ICrySizer* pSizer) const;
private:
//CTimeValue m_curTime;
XmlNodeRef CurNode() { return m_nodeStack.back().m_node; }
XmlNodeRef NextOf(const char* name)
{
@@ -171,13 +150,9 @@ private:
void DefaultValue(Ang3& v) const { v.x = 0; v.y = 0; v.z = 0; }
void DefaultValue(Quat& v) const { v.w = 1.0f; v.v.x = 0; v.v.y = 0; v.v.z = 0; }
void DefaultValue(CTimeValue& v) const { v.SetValue(0); }
//void DefaultValue( char *str ) const { if (str) str[0] = 0; }
void DefaultValue(AZStd::string& str) const { str = ""; }
void DefaultValue([[maybe_unused]] const AZStd::string& str) const {}
void DefaultValue([[maybe_unused]] SNetObjectID& id) const {}
void DefaultValue([[maybe_unused]] SSerializeString& str) const {}
void DefaultValue(XmlNodeRef& ref) const { ref = NULL; }
//////////////////////////////////////////////////////////////////////////
};
#endif // CRYINCLUDE_CRYSYSTEM_XML_SERIALIZEXMLREADER_H
@@ -49,16 +49,6 @@ bool CSerializeXMLWriterImpl::Value(const char* name, CTimeValue value)
return true;
}
bool CSerializeXMLWriterImpl::Value(const char* name, XmlNodeRef& value)
{
if (BeginOptionalGroup(name, value != NULL))
{
CurNode()->addChild(value);
EndGroup();
}
return true;
}
void CSerializeXMLWriterImpl::BeginGroup(const char* szName)
{
if (strchr(szName, ' ') != 0)
@@ -104,13 +94,6 @@ void CSerializeXMLWriterImpl::EndGroup()
assert(!m_nodeStack.empty());
}
void CSerializeXMLWriterImpl::GetMemoryUsage(ICrySizer* pSizer) const
{
pSizer->Add(*this);
pSizer->AddObject(m_nodeStack);
pSizer->AddContainer(m_luaSaveStack);
}
//////////////////////////////////////////////////////////////////////////
AZStd::string CSerializeXMLWriterImpl::GetStackInfo() const
{
+1 -15
View File
@@ -15,11 +15,10 @@
#include <ISystem.h>
#include <ITimer.h>
#include <IXml.h>
#include "IValidator.h"
#include "SimpleSerialize.h"
class CSerializeXMLWriterImpl
: public CSimpleSerializeImpl<false, eST_SaveGame>
: public CSimpleSerializeImpl<false, ESerializationTarget::eST_SaveGame>
{
public:
CSerializeXMLWriterImpl(const XmlNodeRef& nodeRef);
@@ -32,21 +31,12 @@ public:
return true;
}
template <class T_Value, class T_Policy>
bool Value(const char* name, T_Value& value, [[maybe_unused]] const T_Policy& policy)
{
return Value(name, value);
}
bool Value(const char* name, CTimeValue value);
bool Value(const char* name, XmlNodeRef& value);
void BeginGroup(const char* szName);
bool BeginOptionalGroup(const char* szName, bool condition);
void EndGroup();
void GetMemoryUsage(ICrySizer* pSizer) const;
private:
//////////////////////////////////////////////////////////////////////////
// Vars.
@@ -99,10 +89,6 @@ private:
{
AddValue(name, value.c_str());
}
void AddValue([[maybe_unused]] const char* name, [[maybe_unused]] const SNetObjectID& value)
{
assert(false);
}
template <class T>
void AddTypedValue(const char* name, const T& value, const char* type)
{
@@ -1,432 +0,0 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#include "CrySystem_precompiled.h"
#include "ReadWriteXMLSink.h"
#include <stack>
typedef std::map<AZStd::string, XmlNodeRef> IdTable;
static bool IsOptionalWriteXML(XmlNodeRef& definition);
static bool SaveTableInner(const IdTable&, XmlNodeRef& definition, XmlNodeRef& data, IWriteXMLSource* pSource);
static bool SaveReferencedId(const IdTable&, XmlNodeRef& definition, XmlNodeRef& data, IWriteXMLSource* pSource);
static bool SaveSomething(const IdTable&, XmlNodeRef& definition, XmlNodeRef& data, IWriteXMLSource* pSource);
static bool SaveArray(const IdTable&, XmlNodeRef& definition, XmlNodeRef& data, IWriteXMLSource* pSource);
static bool SaveProperty(const IdTable&, XmlNodeRef& definition, XmlNodeRef& data, IWriteXMLSource* pSource);
static bool SaveTable(const IdTable&, XmlNodeRef& definition, XmlNodeRef& data, IWriteXMLSource* pSource);
static bool SaveArraySetValueTable(const IdTable&, XmlNodeRef& definition, XmlNodeRef& data, IWriteXMLSource* pSource, int elem);
typedef bool (* SaveArraySetValue)(const IdTable&, XmlNodeRef& definition, XmlNodeRef& data, IWriteXMLSource* pSource, int elem);
typedef bool (* SaveDefinitionFunction)(const IdTable&, XmlNodeRef& definition, XmlNodeRef& data, IWriteXMLSource* pSource);
template <class T>
struct WritePropertyTyped;
template <class T>
struct WritePropertyTyped
{
static bool Save(const char* name, XmlNodeRef& definition, XmlNodeRef& data, IWriteXMLSource* pSource)
{
IWriteXMLSource::TValue vvalue((T()));
if (!pSource->GetValue(name, vvalue, definition))
{
return false;
}
T* pValue = AZStd::get_if<T>(&vvalue);
if (!pValue)
{
return false;
}
data->setAttr(name, *pValue);
return true;
}
static bool SaveArray([[maybe_unused]] const IdTable& idTable, XmlNodeRef& definition, XmlNodeRef& data, IWriteXMLSource* pSource, int elem)
{
IWriteXMLSource::TValue vvalue((T()));
if (!pSource->GetAt(elem, vvalue, definition))
{
return false;
}
T* pValue = AZStd::get_if<T>(&vvalue);
if (!pValue)
{
return false;
}
data->setAttr("value", *pValue);
return true;
}
};
template <>
struct WritePropertyTyped<AZStd::string>
: public WritePropertyTyped<const char*>
{
};
bool IsOptionalWriteXML(XmlNodeRef& definition)
{
bool optional = false;
definition->getAttr("optional", optional);
return optional;
}
bool SaveProperty([[maybe_unused]] const IdTable& idTable, XmlNodeRef& definition, XmlNodeRef& data, IWriteXMLSource* pSource)
{
const char* name = definition->getAttr("name");
if (0 == strlen(name))
{
CryLog("Property has no name");
return false;
}
const char* type = definition->getAttr("type");
if (0 == strlen(type))
{
CryLog("Property '%s' has no type", type);
return false;
}
if (IsOptionalWriteXML(definition) && !pSource->HaveValue(name))
{
return true;
}
bool ok = false;
#define SAVE_PROPERTY(whichType) else if (0 == strcmp(type, #whichType)) ok = WritePropertyTyped<whichType>::Save(name, definition, data, pSource)
XML_SET_PROPERTY_HELPER(SAVE_PROPERTY);
#undef SAVE_PROPERTY
if (!ok)
{
CryLog("Failed loading attribute %s of type %s", name, type);
}
return ok;
}
bool SaveArraySetValueTable(const IdTable& idTable, XmlNodeRef& definition, XmlNodeRef& data, IWriteXMLSource* pSource, int elem)
{
IWriteXMLSourcePtr pChildSource = pSource->BeginTableAt(elem);
if (!pChildSource)
{
CryLog("Failed to find source table at %d", elem);
return false;
}
if (!SaveTableInner(idTable, definition, data, &*pChildSource))
{
return false;
}
if (!pChildSource->EndTableAt(elem))
{
CryLog("Failed to finish table at element %d", elem);
return false;
}
return true;
}
bool SaveArray(const IdTable& idTable, XmlNodeRef& definition, XmlNodeRef& data, IWriteXMLSource* pSource)
{
const char* name = definition->getAttr("name");
if (0 == strlen(name))
{
CryLog("Array has no name");
return false;
}
const char* elementName = definition->getAttr("elementName");
if (0 == strlen(elementName))
{
elementName = "element";
}
bool validateArray = true;
if (definition->haveAttr(elementName))
{
definition->getAttr("validate", validateArray);
}
size_t numElems = 0;
IWriteXMLSourcePtr childSource = pSource->BeginArray(name, &numElems, definition);
if (!childSource)
{
bool ok = IsOptionalWriteXML(definition);
if (!ok)
{
CryLog("Failed to begin array named %s", name);
}
return ok;
}
XmlNodeRef childData = data->createNode(name);
SaveArraySetValue setter = NULL;
if (definition->haveAttr("type"))
{
setter = NULL;
const char* type = definition->getAttr("type");
#define SETTER_PROPERTY(whichType) else if (0 == strcmp(type, #whichType)) setter = WritePropertyTyped<whichType>::SaveArray
XML_SET_PROPERTY_HELPER(SETTER_PROPERTY);
#undef SETTER_PROPERTY
if (!setter)
{
CryLog("Unknown type %s in array %s", type, name);
return false;
}
}
else
{
setter = SaveArraySetValueTable;
}
bool needIndex = false;
for (size_t sizei = 1; sizei <= numElems; sizei++)
{
const int i = static_cast<int>(sizei);
if (!childSource->HaveElemAt(i))
{
needIndex = true;
}
else
{
XmlNodeRef elemData = childData->createNode(elementName);
if (needIndex)
{
elemData->setAttr("_index", i);
}
needIndex = false;
if (!setter(idTable, definition, elemData, &*childSource, i))
{
CryLog("Failed saving element %d of array %s", int(i), name);
return false;
}
childData->addChild(elemData);
}
}
if (!pSource->EndArray(name))
{
CryLog("Failed to finish array named %s", name);
return false;
}
data->addChild(childData);
return true;
}
bool SaveTable(const IdTable& idTable, XmlNodeRef& definition, XmlNodeRef& data, IWriteXMLSource* pSource)
{
const char* name = definition->getAttr("name");
if (0 == strlen(name))
{
CryLog("Child-table has no name");
return false;
}
IWriteXMLSourcePtr childSource = pSource->BeginTable(name);
if (!childSource)
{
bool ok = IsOptionalWriteXML(definition);
if (!ok)
{
CryLog("Source creation failed for table %s", name);
}
return ok;
}
XmlNodeRef childData = data->createNode(name);
if (!SaveTableInner(idTable, definition, childData, childSource))
{
CryLog("Failed to load data for child table %s", name);
return false;
}
if (!pSource->EndTable(name))
{
CryLog("Table %s failed to complete in sink", name);
return false;
}
data->addChild(childData);
return true;
}
bool SaveSomething(const IdTable& idTable, XmlNodeRef& nodeDefinition, XmlNodeRef& data, IWriteXMLSource* pSource)
{
static struct
{
const char* name;
SaveDefinitionFunction saver;
} saverTypes[] = {
{"Property", &SaveProperty},
{"Array", &SaveArray},
{"Table", &SaveTable},
{"Use", &SaveReferencedId},
};
static const int numSaverTypes = sizeof(saverTypes) / sizeof(*saverTypes);
const char* nodeDefinitionTag = nodeDefinition->getTag();
bool ok = false;
int i;
for (i = 0; i < numSaverTypes; i++)
{
if (0 == strcmp(saverTypes[i].name, nodeDefinitionTag))
{
ok = saverTypes[i].saver(idTable, nodeDefinition, data, pSource);
break;
}
}
if (!ok)
{
if (i == numSaverTypes)
{
CryLog("Invalid definition node type %s", nodeDefinitionTag);
}
}
return ok;
}
bool SaveReferencedId(const IdTable& idTable, XmlNodeRef& definition, XmlNodeRef& data, IWriteXMLSource* pSource)
{
IdTable::const_iterator iter = idTable.find(definition->getAttr("id"));
if (iter == idTable.end())
{
CryLog("No definition with id '%s'", definition->getAttr("id"));
return false;
}
XmlNodeRef useDefinition = iter->second;
useDefinition = useDefinition->clone();
int numAttrs = definition->getNumAttributes();
for (int i = 0; i < numAttrs; i++)
{
const char* key, * value;
definition->getAttributeByIndex(i, &key, &value);
useDefinition->setAttr(key, value);
}
return SaveSomething(idTable, useDefinition, data, pSource);
}
bool SaveTableInner(const IdTable& idTable, XmlNodeRef& definition, XmlNodeRef& data, IWriteXMLSource* pSource)
{
const int nChildrenDefinition = definition->getChildCount();
for (int nChildDefinition = 0; nChildDefinition < nChildrenDefinition; nChildDefinition++)
{
XmlNodeRef nodeDefinition = definition->getChild(nChildDefinition);
if (!SaveSomething(idTable, nodeDefinition, data, pSource))
{
return false;
}
}
return true;
}
XmlNodeRef CReadWriteXMLSink::CreateXMLFromSource(const char* definitionFile, IWriteXMLSource* pSource)
{
XmlNodeRef rootDefinition = GetISystem()->LoadXmlFromFile(definitionFile);
if (!rootDefinition)
{
CryLog("Unable to load XML-Lua definition file: %s", definitionFile);
return 0;
}
if (0 != strcmp(rootDefinition->getTag(), "Definition"))
{
CryLog("Root tag of definition file was %s; expected Definition", rootDefinition->getTag());
return 0;
}
const char* rootNode = "Root";
if (rootDefinition->haveAttr("root"))
{
rootNode = rootDefinition->getAttr("root");
}
XmlNodeRef rootData = GetISystem()->CreateXmlNode(rootNode);
XmlNodeRef allowAlways = rootDefinition->findChild("AllowAlways");
if (allowAlways != 0)
{
rootDefinition->removeChild(allowAlways);
}
XmlNodeRef settingsParams = rootDefinition->findChild("Settings");
if (settingsParams != 0)
{
rootDefinition->removeChild(settingsParams);
}
// scan for id's in the structure (for the Use member)
IdTable idTable;
std::stack<XmlNodeRef> scanStack;
scanStack.push(rootDefinition);
while (!scanStack.empty())
{
XmlNodeRef refNode = scanStack.top();
scanStack.pop();
int numChildren = refNode->getChildCount();
const char* tag = refNode->getTag();
for (int i = 0; i < numChildren; i++)
{
scanStack.push(refNode->getChild(i));
}
if (refNode->haveAttr("id") && 0 != strcmp("Use", tag))
{
idTable[refNode->getAttr("id")] = refNode;
}
if (allowAlways != 0 && (!strcmp("Table", tag) || !strcmp("Array", tag)))
{
for (int i = 0; i < allowAlways->getChildCount(); ++i)
{
refNode->addChild(allowAlways->getChild(i)->clone());
}
}
}
if (!SaveTableInner(idTable, rootDefinition, rootData, pSource))
{
CryLog("Error createing xml using definition %s", definitionFile);
return 0;
}
bool ok = pSource->Complete();
if (!ok)
{
CryLog("Warning: sink failed to complete writing");
return 0;
}
return rootData;
}
bool CReadWriteXMLSink::WriteXML(const char* definitionFile, const char* dataFile, IWriteXMLSource* pSource)
{
XmlNodeRef data = CreateXMLFromSource(definitionFile, pSource);
if (!data)
{
CryLog("Failed creating %s", dataFile);
return false;
}
if (!data->saveToFile(dataFile))
{
CryLog("Failed saving %s", dataFile);
return false;
}
return true;
}
+1 -46
View File
@@ -8,8 +8,8 @@
#include <platform.h>
#include "Cry_Color.h"
#include "XMLBinaryNode.h"
#include <CrySizer.h>
//////////////////////////////////////////////////////////////////////////
CBinaryXmlData::CBinaryXmlData()
@@ -38,24 +38,10 @@ CBinaryXmlData::~CBinaryXmlData()
pBinaryNodes = 0;
}
void CBinaryXmlData::GetMemoryUsage(ICrySizer* pSizer) const
{
pSizer->AddObject(pFileContents, nFileSize);
const XMLBinary::BinaryFileHeader* pHeader = reinterpret_cast<const XMLBinary::BinaryFileHeader*>(pFileContents);
pSizer->AddObject(pBinaryNodes, sizeof(CBinaryXmlNode) * pHeader->nNodeCount);
}
//////////////////////////////////////////////////////////////////////////
// CBinaryXmlNode implementation.
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
// collect allocated memory informations
void CBinaryXmlNode::GetMemoryUsage(ICrySizer* pSizer) const
{
pSizer->AddObject(m_pData);
}
//////////////////////////////////////////////////////////////////////////
XmlNodeRef CBinaryXmlNode::getParent() const
{
@@ -244,21 +230,6 @@ bool CBinaryXmlNode::getAttr(const char* key, Vec4& value) const
return false;
}
bool CBinaryXmlNode::getAttr(const char* key, Vec3d& value) const
{
const char* svalue = GetValue(key);
if (svalue)
{
double x, y, z;
if (azsscanf(svalue, "%lf,%lf,%lf", &x, &y, &z) == 3)
{
value = Vec3d(x, y, z);
return true;
}
}
return false;
}
//////////////////////////////////////////////////////////////////////////
bool CBinaryXmlNode::getAttr(const char* key, Vec2& value) const
{
@@ -275,22 +246,6 @@ bool CBinaryXmlNode::getAttr(const char* key, Vec2& value) const
return false;
}
//////////////////////////////////////////////////////////////////////////
bool CBinaryXmlNode::getAttr(const char* key, Vec2d& value) const
{
const char* svalue = GetValue(key);
if (svalue)
{
double x, y;
if (azsscanf(svalue, "%lf,%lf", &x, &y) == 2)
{
value = Vec2d(x, y);
return true;
}
}
return false;
}
//////////////////////////////////////////////////////////////////////////
bool CBinaryXmlNode::getAttr(const char* key, Quat& value) const
{
@@ -41,8 +41,6 @@ public:
CBinaryXmlData();
~CBinaryXmlData();
void GetMemoryUsage(ICrySizer* pSizer) const;
};
// forward declaration
@@ -59,9 +57,6 @@ class CBinaryXmlNode
{
public:
// collect allocated memory informations
void GetMemoryUsage(ICrySizer* pSizer) const;
//////////////////////////////////////////////////////////////////////////
// Custom new/delete with pool allocator.
//////////////////////////////////////////////////////////////////////////
@@ -163,11 +158,9 @@ public:
void setAttr([[maybe_unused]] const char* key, [[maybe_unused]] float value) { assert(0); };
void setAttr([[maybe_unused]] const char* key, [[maybe_unused]] f64 value) { assert(0); };
void setAttr([[maybe_unused]] const char* key, [[maybe_unused]] const Vec2& value) { assert(0); };
void setAttr([[maybe_unused]] const char* key, [[maybe_unused]] const Vec2d& value) { assert(0); };
void setAttr([[maybe_unused]] const char* key, [[maybe_unused]] const Ang3& value) { assert(0); };
void setAttr([[maybe_unused]] const char* key, [[maybe_unused]] const Vec3& value) { assert(0); };
void setAttr([[maybe_unused]] const char* key, [[maybe_unused]] const Vec4& value) { assert(0); };
void setAttr([[maybe_unused]] const char* key, [[maybe_unused]] const Vec3d& value) { assert(0); };
void setAttr([[maybe_unused]] const char* key, [[maybe_unused]] const Quat& value) { assert(0); };
void delAttr([[maybe_unused]] const char* key) { assert(0); };
void removeAllAttributes() { assert(0); };
@@ -182,11 +175,9 @@ public:
bool getAttr(const char* key, bool& value) const;
bool getAttr(const char* key, XmlString& value) const {const char* v(NULL); bool boHasAttribute(getAttr(key, &v)); value = v; return boHasAttribute; }
bool getAttr(const char* key, Vec2& value) const;
bool getAttr(const char* key, Vec2d& value) const;
bool getAttr(const char* key, Ang3& value) const;
bool getAttr(const char* key, Vec3& value) const;
bool getAttr(const char* key, Vec4& value) const;
bool getAttr(const char* key, Vec3d& value) const;
bool getAttr(const char* key, Quat& value) const;
bool getAttr(const char* key, ColorB& value) const;
+1 -53
View File
@@ -12,40 +12,6 @@
#include "CryEndian.h"
#include <string.h> // memcpy()
//////////////////////////////////////////////////////////////////////////
namespace XMLBinary
{
void SwapEndianness_Node(Node& t)
{
SwapEndian(t.nTagStringOffset, true);
SwapEndian(t.nContentStringOffset, true);
SwapEndian(t.nAttributeCount, true);
SwapEndian(t.nChildCount, true);
SwapEndian(t.nParentIndex, true);
SwapEndian(t.nFirstAttributeIndex, true);
SwapEndian(t.nFirstChildIndex, true);
}
void SwapEndianness_Attribute(Attribute& t)
{
SwapEndian(t.nKeyStringOffset, true);
SwapEndian(t.nValueStringOffset, true);
}
void SwapEndianness_Header(BinaryFileHeader& t)
{
SwapEndian(t.nXMLSize, true);
SwapEndian(t.nNodeTablePosition, true);
SwapEndian(t.nNodeCount, true);
SwapEndian(t.nAttributeTablePosition, true);
SwapEndian(t.nAttributeCount, true);
SwapEndian(t.nChildTablePosition, true);
SwapEndian(t.nChildCount, true);
SwapEndian(t.nStringDataPosition, true);
SwapEndian(t.nStringDataSize, true);
}
}
//////////////////////////////////////////////////////////////////////////
XMLBinary::CXMLBinaryWriter::CXMLBinaryWriter()
{
@@ -84,7 +50,7 @@ static void write(XMLBinary::IDataWriter* const pFile, size_t& nPosition, const
}
//////////////////////////////////////////////////////////////////////////
bool XMLBinary::CXMLBinaryWriter::WriteNode(IDataWriter* pFile, XmlNodeRef node, bool bNeedSwapEndian, XMLBinary::IFilter* pFilter, AZStd::string& error)
bool XMLBinary::CXMLBinaryWriter::WriteNode(IDataWriter* pFile, XmlNodeRef node, XMLBinary::IFilter* pFilter, AZStd::string& error)
{
error = "";
@@ -135,24 +101,6 @@ bool XMLBinary::CXMLBinaryWriter::WriteNode(IDataWriter* pFile, XmlNodeRef node,
header.nXMLSize = static_cast<uint32>(nTheoreticalPosition);
// Swap endianness of the data structures
if (bNeedSwapEndian)
{
SwapEndianness_Header(header);
for (size_t i = 0, iCount = m_nodes.size(); i < iCount; ++i)
{
SwapEndianness_Node(m_nodes[i]);
}
for (size_t i = 0, iCount = m_attributes.size(); i < iCount; ++i)
{
SwapEndianness_Attribute(m_attributes[i]);
}
for (size_t i = 0, iCount = m_childs.size(); i < iCount; ++i)
{
SwapEndian(m_childs[i], true);
}
}
// Write file
{
nTheoreticalPosition = 0;
+1 -1
View File
@@ -25,7 +25,7 @@ namespace XMLBinary
{
public:
CXMLBinaryWriter();
bool WriteNode(IDataWriter* pFile, XmlNodeRef node, bool bNeedSwapEndian, XMLBinary::IFilter* pFilter, AZStd::string & error);
bool WriteNode(IDataWriter* pFile, XmlNodeRef node, XMLBinary::IFilter* pFilter, AZStd::string & error);
private:
bool CompileTables(XmlNodeRef node, XMLBinary::IFilter* pFilter, AZStd::string& error);
-423
View File
@@ -1,423 +0,0 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#include "CrySystem_precompiled.h"
#include "XMLPatcher.h"
CXMLPatcher::CXMLPatcher(XmlNodeRef& patchXML)
{
m_patchXML = patchXML;
#if DATA_PATCH_DEBUG
m_pDumpFilesCVar = REGISTER_INT("g_datapatcher_dumpfiles", 0, NULL, "will dump a copy of every file data patched, before and after patching");
#endif
}
CXMLPatcher::~CXMLPatcher()
{
#if DATA_PATCH_DEBUG
if (IConsole* pIC = gEnv->pConsole)
{
pIC->UnregisterVariable(m_pDumpFilesCVar->GetName());
}
#endif
}
XmlNodeRef CXMLPatcher::DuplicateForPatching(
const XmlNodeRef& inOrig,
bool inShareChildren)
{
XmlNodeRef newNode(0);
if (m_patchXML)
{
newNode = m_patchXML->createNode(inOrig->getTag());
if (newNode)
{
// copy attributes in a safe way, copyAttributes() itself assumes the node being copied from is of the same type
int numAttr = inOrig->getNumAttributes();
for (int i = 0; i < numAttr; i++)
{
const char* pKey, * pValue;
if (inOrig->getAttributeByIndex(i, &pKey, &pValue))
{
newNode->setAttr(pKey, pValue);
}
}
if (inShareChildren)
{
newNode->shareChildren(inOrig);
}
}
}
return newNode;
}
void CXMLPatcher::PatchFail(
const char* pInReason)
{
CryLogAlways("Failed to apply data patch for file '%s' - reason '%s'", m_pFileBeingPatched, pInReason);
}
XmlNodeRef CXMLPatcher::FindPatchForFile(
const char* pInFileToPatch)
{
XmlNodeRef result;
if (m_patchXML)
{
for (int i = 0, m = m_patchXML->getChildCount(); i < m; i++)
{
XmlNodeRef child = m_patchXML->getChild(i);
if (child->isTag("patch"))
{
const char* pForFile = child->getAttr("forfile");
if (pForFile && AZ::StringFunc::Find(pForFile, pInFileToPatch) != AZStd::string::npos)
{
result = child;
break;
}
}
}
}
return result;
}
XmlNodeRef CXMLPatcher::ApplyPatchToNode(
const XmlNodeRef& inNode,
const XmlNodeRef& inPatch)
{
XmlNodeRef result = inNode;
for (int i = 0, m = inPatch->getChildCount(); i < m; i++)
{
XmlNodeRef patchNode = inPatch->getChild(i);
if (!patchNode || _stricmp(patchNode->getTag(), "patchnode") != 0)
{
continue;
}
int indexToPatch;
if (!patchNode->getAttr("index", indexToPatch))
{
PatchFail("found patchnode missing index");
continue;
}
int maxChildren = result->getChildCount();
if ((indexToPatch < 0 || indexToPatch >= maxChildren) && indexToPatch != -1)
{
PatchFail("patchnode index out of valid range");
continue;
}
XmlNodeRef childToPatch = (indexToPatch != -1) ? result->getChild(indexToPatch) : XmlNodeRef(0);
XmlNodeRef matchTag = GetMatchTag(patchNode);
if (childToPatch && matchTag && !CompareTags(matchTag, childToPatch))
{
PatchFail("patch failed to apply, data did not match what was expected");
continue;
}
// we need to apply a patch to this child, make it patchable by duplicating the node
if (inNode == result)
{
// make parent patchable if not already
result = DuplicateForPatching(inNode, true);
}
if (XmlNodeRef insertTag = GetInsertTag(patchNode))
{
// insert a new child after this node
XmlNodeRef newChild = DuplicateForPatching(insertTag, true); // have to duplicate it as we don't have an 'insert shared child' function
result->insertChild(indexToPatch + 1, newChild);
}
else
{
if (indexToPatch == -1)
{
PatchFail("child indices of -1 can only be used when inserting new nodes");
continue;
}
}
bool shouldReplaceChildren = false;
if (XmlNodeRef replaceTag = GetReplaceTag(patchNode, &shouldReplaceChildren))
{
XmlNodeRef newChild = DuplicateForPatching(replaceTag, false);
if (!shouldReplaceChildren)
{
newChild->shareChildren(childToPatch);
}
else
{
// note: this is inserting children that belong to the data patcher into the data being patched
// this is fine to do, as long as the caller doesn't make any permanent changes to the xml tree
// returned. if they did they would alter the patcher's nodes and thus affect future patches
// applied using the same patch
// as most callers are working with binary xmls they don't try and modify them - as this is not
// a supported operation
// note, if a second patch was applied to this patched tree containing the patch nodes, it
// wouldn't mess up the patch, as patching a tree never modifies it, it always returns a new tree
// that may share parts of the original tree
newChild->shareChildren(replaceTag);
}
result->replaceChild(indexToPatch, newChild);
childToPatch = newChild;
}
if (XmlNodeRef deleteTag = GetDeleteTag(patchNode))
{
result->deleteChildAt(indexToPatch);
childToPatch = 0; // deleted - don't recurse into it
}
if (childToPatch)
{
// Apply recursively
XmlNodeRef newChild = ApplyPatchToNode(childToPatch, patchNode);
// child has been patched, insert new child into parent
if (newChild != childToPatch)
{
result->replaceChild(indexToPatch, newChild);
}
}
}
return result;
}
XmlNodeRef CXMLPatcher::ApplyXMLDataPatch(
const XmlNodeRef& inNode,
const char* pInXMLFileName)
{
XmlNodeRef result = inNode;
if (m_patchingEnabled)
{
if (m_patchXML)
{
XmlNodeRef patchForFile = FindPatchForFile(pInXMLFileName);
if (patchForFile)
{
m_pFileBeingPatched = pInXMLFileName;
CryLog("Applying game data patch to %s", pInXMLFileName);
XmlNodeRef containerNode = m_patchXML->createNode("");
containerNode->addChild(inNode);
containerNode = ApplyPatchToNode(containerNode, patchForFile);
result = containerNode->getChild(0);
m_pFileBeingPatched = NULL;
#if DATA_PATCH_DEBUG
if (inNode != result)
{
DumpFiles(pInXMLFileName, inNode, result);
}
#endif
}
}
}
return result;
}
XmlNodeRef CXMLPatcher::GetMatchTag(
const XmlNodeRef& inNode)
{
XmlNodeRef result;
XmlNodeRef nr = inNode->findChild("match");
if (nr && nr->getChildCount() == 1)
{
result = nr->getChild(0);
}
return result;
}
XmlNodeRef CXMLPatcher::GetReplaceTag(
const XmlNodeRef& inNode,
bool* outShouldReplaceChildren)
{
XmlNodeRef result;
XmlNodeRef nr = inNode->findChild("replacewith");
if (nr && nr->getChildCount() == 1)
{
if (!nr->getAttr("replaceChildren", *outShouldReplaceChildren))
{
*outShouldReplaceChildren = false;
}
result = nr->getChild(0);
}
return result;
}
XmlNodeRef CXMLPatcher::GetInsertTag(
const XmlNodeRef& inNode)
{
XmlNodeRef result;
XmlNodeRef nr = inNode->findChild("insertAfter");
if (nr && nr->getChildCount() == 1)
{
result = nr->getChild(0);
}
return result;
}
XmlNodeRef CXMLPatcher::GetDeleteTag(
const XmlNodeRef& inNode)
{
XmlNodeRef result = inNode->findChild("delete");
return result;
}
// compares the two tags for equality of tag and attributes
// used to ensure the source data being patched meets the patches expectations
// only compares tag and attribs, doesn't do deep compare of children
bool CXMLPatcher::CompareTags(
const XmlNodeRef& inA,
const XmlNodeRef& inB)
{
bool result = true;
if (inA != inB)
{
result = false;
if (_stricmp(inA->getTag(), inB->getTag()) == 0)
{
if (inA->getNumAttributes() == inB->getNumAttributes())
{
result = true;
for (int i = 0, m = inA->getNumAttributes(); i < m; i++)
{
const char* pAKey, * pBKey;
const char* pAValue, * pBValue;
inA->getAttributeByIndex(i, &pAKey, &pAValue);
inB->getAttributeByIndex(i, &pBKey, &pBValue);
if (_stricmp(pAKey, pBKey) || _stricmp(pAValue, pBValue))
{
result = false;
break;
}
}
}
}
}
return result;
}
#if DATA_PATCH_DEBUG
static const char* k_lotsOfTabs = "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t";
#define INDENT() \
if (inIndent > 0) \
{ \
pPak->FWrite(k_lotsOfTabs, inIndent, inFileHandle); \
}
void CXMLPatcher::DumpXMLNodes(
AZ::IO::HandleType inFileHandle,
int inIndent,
const XmlNodeRef& inNode,
AZStd::fixed_string<512>* ioTempString)
{
auto pPak = gEnv->pCryPak;
inIndent = min(inIndent, int(sizeof(k_lotsOfTabs) - 1));
INDENT();
*ioTempString = AZStd::fixed_string<512>::format("<%s ", inNode->getTag());
pPak->FWrite(ioTempString->c_str(), ioTempString->length(), inFileHandle);
for (int i = 0, m = inNode->getNumAttributes(); i < m; i++)
{
const char* pKey, * pVal;
inNode->getAttributeByIndex(i, &pKey, &pVal);
*ioTempString = AZStd::fixed_string<512>::format("%s=\"%s\" ", pKey, pVal);
pPak->FWrite(ioTempString->c_str(), ioTempString->length(), inFileHandle);
}
pPak->FWrite(">\n", 2, inFileHandle);
for (int i = 0, m = inNode->getChildCount(); i < m; i++)
{
DumpXMLNodes(inFileHandle, inIndent + 1, inNode->getChild(i), ioTempString);
}
INDENT();
*ioTempString = AZStd::fixed_string<512>::format("</%s>\n", inNode->getTag());
pPak->FWrite(ioTempString->c_str(), ioTempString->length(), inFileHandle);
}
void CXMLPatcher::DumpFiles(
const char* pInXMLFileName,
const XmlNodeRef& inBefore,
const XmlNodeRef& inAfter)
{
if (m_pDumpFilesCVar->GetIVal())
{
CryLog("Dumping before and after data files for '%s'", pInXMLFileName);
const char* pOrigFileName = strrchr(pInXMLFileName, '/');
if (pOrigFileName)
{
pOrigFileName++;
DumpXMLFile(AZStd::string::format("PATCH_%s", pOrigFileName).c_str(), inBefore);
AZStd::string newFileName(pOrigFileName);
AZ::StringFunc::Replace(newFileName, ".xml", "_patched.xml");
DumpXMLFile(AZStd::string::format("PATCH_%s", newFileName.c_str()).c_str(), inAfter);
}
else
{
CryLog("Couldn't determine file name for path '%s' can't output diffs", pInXMLFileName);
}
}
}
void CXMLPatcher::DumpXMLFile(
const char* pInFilePath,
const XmlNodeRef& inNode)
{
auto pIPak = GetISystem()->GetIPak();
AZ::IO::HandleType fileHandle = pIPak->FOpen(pInFilePath, "wb");
if (fileHandle != AZ::IO::InvalidHandle)
{
AZStd::fixed_string<512> tempStr;
DumpXMLNodes(fileHandle, 0, inNode, &tempStr);
pIPak->FClose(fileHandle);
}
}
#endif
-81
View File
@@ -1,81 +0,0 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#ifndef CRYINCLUDE_CRYSYSTEM_XML_XMLPATCHER_H
#define CRYINCLUDE_CRYSYSTEM_XML_XMLPATCHER_H
#pragma once
#if defined(WIN32) && !defined(_RELEASE)
#define DATA_PATCH_DEBUG 1
#else
#define DATA_PATCH_DEBUG 0
#endif
class CXMLPatcher
{
protected:
#if DATA_PATCH_DEBUG
ICVar * m_pDumpFilesCVar;
#endif
XmlNodeRef m_patchXML;
const char* m_pFileBeingPatched;
bool m_patchingEnabled;
void PatchFail(
const char* pInReason);
XmlNodeRef ApplyPatchToNode(
const XmlNodeRef& inNode,
const XmlNodeRef& inPatch);
XmlNodeRef DuplicateForPatching(
const XmlNodeRef& inOrig,
bool inShareChildren);
bool CompareTags(
const XmlNodeRef& inA,
const XmlNodeRef& inB);
XmlNodeRef GetMatchTag(
const XmlNodeRef& inNode);
XmlNodeRef GetReplaceTag(
const XmlNodeRef& inNode,
bool* outShouldReplaceChildren);
XmlNodeRef GetInsertTag(
const XmlNodeRef& inNode);
XmlNodeRef GetDeleteTag(
const XmlNodeRef& inNode);
XmlNodeRef FindPatchForFile(
const char* pInFileToPatch);
#if DATA_PATCH_DEBUG
void DumpXMLNodes(
AZ::IO::HandleType inFileHandle,
int inIndent,
const XmlNodeRef& inNode,
AZStd::fixed_string<512>* ioTempString);
void DumpFiles(
const char* pInXMLFileName,
const XmlNodeRef& inBefore,
const XmlNodeRef& inAfter);
void DumpXMLFile(
const char* pInFilePath,
const XmlNodeRef& inNode);
#endif
public:
CXMLPatcher(XmlNodeRef& patchXML);
~CXMLPatcher();
XmlNodeRef ApplyXMLDataPatch(
const XmlNodeRef& inNode,
const char* pInXMLFileName);
};
#endif // CRYINCLUDE_CRYSYSTEM_XML_XMLPATCHER_H
+4 -222
View File
@@ -11,7 +11,6 @@
#include <IXml.h>
#include "xml.h"
#include "XmlUtils.h"
#include "ReadWriteXMLSink.h"
#include "../SimpleStringPool.h"
#include "SerializeXMLReader.h"
@@ -20,7 +19,6 @@
#include "XMLBinaryWriter.h"
#include "XMLBinaryReader.h"
#include "XMLPatcher.h"
#include <md5.h>
//////////////////////////////////////////////////////////////////////////
@@ -28,23 +26,14 @@
SXmlNodeStats* g_pCXmlNode_Stats = 0;
#endif
extern bool g_bEnableBinaryXmlLoading;
//////////////////////////////////////////////////////////////////////////
CXmlUtils::CXmlUtils(ISystem* pSystem)
{
m_pSystem = pSystem;
// create IReadWriteXMLSink object
m_pReadWriteXMLSink = new CReadWriteXMLSink();
#ifdef CRY_COLLECT_XML_NODE_STATS
g_pCXmlNode_Stats = new SXmlNodeStats();
#endif
m_pStatsXmlNodePool = 0;
#ifndef _RELEASE
m_statsThreadOwner = CryGetCurrentThreadId();
#endif
m_pXMLPatcher = NULL;
}
//////////////////////////////////////////////////////////////////////////
@@ -53,8 +42,6 @@ CXmlUtils::~CXmlUtils()
#ifdef CRY_COLLECT_XML_NODE_STATS
delete g_pCXmlNode_Stats;
#endif
SAFE_DELETE(m_pStatsXmlNodePool);
SAFE_DELETE(m_pXMLPatcher);
}
//////////////////////////////////////////////////////////////////////////
@@ -65,21 +52,13 @@ IXmlParser* CXmlUtils::CreateXmlParser()
}
//////////////////////////////////////////////////////////////////////////
XmlNodeRef CXmlUtils::LoadXmlFromFile(const char* sFilename, bool bReuseStrings, bool bEnablePatching)
XmlNodeRef CXmlUtils::LoadXmlFromFile(const char* sFilename, bool bReuseStrings)
{
XmlParser parser(bReuseStrings);
XmlNodeRef node = parser.ParseFile(sFilename, true);
// XmlParser is supposed to log warnings and errors (if any),
// so we don't need to call parser.getErrorString(),
// CryLog() etc here.
if (node && bEnablePatching && m_pXMLPatcher)
{
node = m_pXMLPatcher->ApplyXMLDataPatch(node, sFilename);
}
return node;
XmlParser parser(bReuseStrings);
return parser.ParseFile(sFilename, true);
}
//////////////////////////////////////////////////////////////////////////
@@ -99,29 +78,6 @@ void GetMD5(const char* pSrcBuffer, int nSrcSize, char signatureMD5[16])
MD5Final((unsigned char*)signatureMD5, &md5c);
}
//////////////////////////////////////////////////////////////////////////
const char* CXmlUtils::HashXml(XmlNodeRef node)
{
static char signature[16 * 2 + 1];
static char temp[16];
static const char* hex = "0123456789abcdef";
XmlString str = node->getXML();
GetMD5(str.data(), static_cast<int>(str.length()), temp);
for (int i = 0; i < 16; i++)
{
signature[2 * i + 0] = hex[((uint8)temp[i]) >> 4];
signature[2 * i + 1] = hex[((uint8)temp[i]) & 0xf];
}
signature[16 * 2] = 0;
return signature;
}
//////////////////////////////////////////////////////////////////////////
IReadWriteXMLSink* CXmlUtils::GetIReadWriteXMLSink()
{
return m_pReadWriteXMLSink;
}
//////////////////////////////////////////////////////////////////////////
class CXmlSerializer
: public IXmlSerializer
@@ -172,12 +128,6 @@ public:
return m_pReaderSer;
}
virtual void GetMemoryUsage(ICrySizer* pSizer) const
{
pSizer->Add(*this);
pSizer->AddObject(m_pReaderImpl);
pSizer->AddObject(m_pWriterImpl);
}
//////////////////////////////////////////////////////////////////////////
private:
int m_nRefCount;
@@ -194,62 +144,6 @@ IXmlSerializer* CXmlUtils::CreateXmlSerializer()
return new CXmlSerializer;
}
//////////////////////////////////////////////////////////////////////////
void CXmlUtils::GetMemoryUsage([[maybe_unused]] ICrySizer* pSizer)
{
#ifdef CRY_COLLECT_XML_NODE_STATS
// yes, slow
std::vector<const CXmlNode*> rootNodes;
{
TXmlNodeSet::const_iterator iter = g_pCXmlNode_Stats->nodeSet.begin();
TXmlNodeSet::const_iterator iterEnd = g_pCXmlNode_Stats->nodeSet.end();
while (iter != iterEnd)
{
const CXmlNode* pNode = *iter;
if (pNode->getParent() == 0)
{
rootNodes.push_back(pNode);
}
++iter;
}
}
// use the following to log to console
#if 0
CryLogAlways("NumXMLRootNodes=%d NumXMLNodes=%d TotalAllocs=%d TotalFrees=%d",
rootNodes.size(), g_pCXmlNode_Stats->nodeSet.size(),
g_pCXmlNode_Stats->nAllocs, g_pCXmlNode_Stats->nFrees);
#endif
// use the following to debug the nodes in the system
#if 0
{
std::vector<const CXmlNode*>::const_iterator iter = rootNodes.begin();
std::vector<const CXmlNode*>::const_iterator iterEnd = rootNodes.end();
while (iter != iterEnd)
{
const CXmlNode* pNode = *iter;
CryLogAlways("Node 0x%p Tag='%s'", pNode, pNode->getTag());
++iter;
}
}
#endif
// only for debugging, add it as pseudo numbers to the CrySizer.
// shift it by 10, so we get the actual number
{
SIZER_COMPONENT_NAME(pSizer, "#NumTotalNodes");
pSizer->Add("#NumTotalNodes", g_pCXmlNode_Stats->nodeSet.size() << 10);
}
{
SIZER_COMPONENT_NAME(pSizer, "#NumRootNodes");
pSizer->Add("#NumRootNodes", rootNodes.size() << 10);
}
#endif
}
//////////////////////////////////////////////////////////////////////////
class CXmlBinaryDataWriterFile
: public XMLBinary::IDataWriter
@@ -282,49 +176,13 @@ private:
AZ::IO::HandleType m_fileHandle;
};
//////////////////////////////////////////////////////////////////////////
bool CXmlUtils::SaveBinaryXmlFile(const char* filename, XmlNodeRef root)
{
CXmlBinaryDataWriterFile fileSink(filename);
if (!fileSink.IsOk())
{
return false;
}
XMLBinary::CXMLBinaryWriter writer;
AZStd::string error;
return writer.WriteNode(&fileSink, root, false, 0, error);
}
//////////////////////////////////////////////////////////////////////////
XmlNodeRef CXmlUtils::LoadBinaryXmlFile(const char* filename, bool bEnablePatching)
{
XMLBinary::XMLBinaryReader reader;
XMLBinary::XMLBinaryReader::EResult result;
XmlNodeRef root = reader.LoadFromFile(filename, result);
if (result == XMLBinary::XMLBinaryReader::eResult_Success && bEnablePatching == true && m_pXMLPatcher != NULL)
{
root = m_pXMLPatcher->ApplyXMLDataPatch(root, filename);
}
return root;
}
//////////////////////////////////////////////////////////////////////////
bool CXmlUtils::EnableBinaryXmlLoading(bool bEnable)
{
bool bPrev = g_bEnableBinaryXmlLoading;
g_bEnableBinaryXmlLoading = bEnable;
return bPrev;
}
//////////////////////////////////////////////////////////////////////////
class CXmlTableReader
: public IXmlTableReader
{
public:
CXmlTableReader();
virtual ~CXmlTableReader();
~CXmlTableReader() override;
virtual void Release();
@@ -332,7 +190,6 @@ public:
virtual int GetEstimatedRowCount();
virtual bool ReadRow(int& rowIndex);
virtual bool ReadCell(int& columnIndex, const char*& pContent, size_t& contentSize);
float GetCurrentRowHeight() override;
private:
bool m_bExcel;
@@ -341,7 +198,6 @@ private:
XmlNodeRef m_rowNode;
float m_currentRowHeight;
int m_rowNodeIndex;
int m_row;
@@ -411,7 +267,6 @@ int CXmlTableReader::GetEstimatedRowCount()
//////////////////////////////////////////////////////////////////////////
bool CXmlTableReader::ReadRow(int& rowIndex)
{
m_currentRowHeight = 0.0f;
if (!m_tableNode)
{
return false;
@@ -459,12 +314,6 @@ bool CXmlTableReader::ReadRow(int& rowIndex)
}
m_row = index;
}
float height;
if (m_rowNode->getAttr("ss:Height", height))
{
m_currentRowHeight = height;
}
rowIndex = m_row;
return true;
}
@@ -617,75 +466,8 @@ bool CXmlTableReader::ReadCell(int& columnIndex, const char*& pContent, size_t&
}
}
float CXmlTableReader::GetCurrentRowHeight()
{
return m_currentRowHeight;
}
//////////////////////////////////////////////////////////////////////////
IXmlTableReader* CXmlUtils::CreateXmlTableReader()
{
return new CXmlTableReader;
}
//////////////////////////////////////////////////////////////////////////
// Init xml stats nodes pool
void CXmlUtils::InitStatsXmlNodePool(uint32 nPoolSize)
{
CHECK_STATS_THREAD_OWNERSHIP();
if (0 == m_pStatsXmlNodePool)
{
// create special xml node pools for game statistics
const bool bReuseStrings = true; // TODO parameterise?
m_pStatsXmlNodePool = new CXmlNodePool(nPoolSize, bReuseStrings);
assert(m_pStatsXmlNodePool);
}
else
{
CryLog("[CXmlNodePool]: Xml stats nodes pool already initialized");
}
}
//////////////////////////////////////////////////////////////////////////
// Creates new xml node for statistics.
XmlNodeRef CXmlUtils::CreateStatsXmlNode(const char* sNodeName)
{
CHECK_STATS_THREAD_OWNERSHIP();
if (0 == m_pStatsXmlNodePool)
{
CryLog("[CXmlNodePool]: Xml stats nodes pool isn't initialized. Perform default initialization.");
InitStatsXmlNodePool();
}
return m_pStatsXmlNodePool->GetXmlNode(sNodeName);
}
void CXmlUtils::SetStatsOwnerThread([[maybe_unused]] threadID threadId)
{
#ifndef _RELEASE
m_statsThreadOwner = threadId;
#endif
}
void CXmlUtils::FlushStatsXmlNodePool()
{
CHECK_STATS_THREAD_OWNERSHIP();
if (m_pStatsXmlNodePool)
{
if (m_pStatsXmlNodePool->empty())
{
SAFE_DELETE(m_pStatsXmlNodePool);
}
}
}
void CXmlUtils::SetXMLPatcher(XmlNodeRef* pPatcher)
{
SAFE_DELETE(m_pXMLPatcher);
if (pPatcher != NULL)
{
m_pXMLPatcher = new CXMLPatcher(*pPatcher);
}
}
+1 -42
View File
@@ -20,7 +20,6 @@
#endif
class CXmlNodePool;
class CXMLPatcher;
//////////////////////////////////////////////////////////////////////////
// Implements IXmlUtils interface.
@@ -39,57 +38,17 @@ public:
virtual IXmlParser* CreateXmlParser();
// Load xml from file, returns 0 if load failed.
virtual XmlNodeRef LoadXmlFromFile(const char* sFilename, bool bReuseStrings = false, bool bEnablePatching = true);
virtual XmlNodeRef LoadXmlFromFile(const char* sFilename, bool bReuseStrings = false);
// Load xml from memory buffer, returns 0 if load failed.
virtual XmlNodeRef LoadXmlFromBuffer(const char* buffer, size_t size, bool bReuseStrings = false, bool bSuppressWarnings = false);
// create an MD5 hash of an XML file
virtual const char* HashXml(XmlNodeRef node);
// Get an object that can read a xml into a IReadXMLSink
// and write a xml from a IWriteXMLSource
virtual IReadWriteXMLSink* GetIReadWriteXMLSink();
virtual IXmlSerializer* CreateXmlSerializer();
virtual bool SaveBinaryXmlFile(const char* sFilename, XmlNodeRef root);
virtual XmlNodeRef LoadBinaryXmlFile(const char* sFilename, bool bEnablePatching = true);
virtual bool EnableBinaryXmlLoading(bool bEnable);
// Create XML Table reader.
virtual IXmlTableReader* CreateXmlTableReader();
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
virtual void GetMemoryUsage(ICrySizer* pSizer);
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
// Init xml stats nodes pool
virtual void InitStatsXmlNodePool(uint32 nPoolSize = 1024*1024);
// Create new xml node for statistics
virtual XmlNodeRef CreateStatsXmlNode(const char* sNodeName = "");
// Set owner thread
virtual void SetStatsOwnerThread(threadID threadId);
// Free memory if stats xml node pool is empty
virtual void FlushStatsXmlNodePool();
// Set the XML Patcher. This is an XML object that modifies named XML files as they are loaded
// EXCEPT for xml files loaded from a buffer, for which names aren't passed in
virtual void SetXMLPatcher(XmlNodeRef* pPatcher);
private:
ISystem* m_pSystem;
IReadWriteXMLSink* m_pReadWriteXMLSink;
CXmlNodePool* m_pStatsXmlNodePool;
CXMLPatcher* m_pXMLPatcher; //If set, applies data patches to any XML file that is loaded by this class
#ifndef _RELEASE
threadID m_statsThreadOwner;
#endif
};
#endif // CRYINCLUDE_CRYSYSTEM_XML_XMLUTILS_H
+25 -117
View File
@@ -9,8 +9,6 @@
#include "CrySystem_precompiled.h"
//#define _CRT_SECURE_NO_DEPRECATE 1
//#define _CRT_NONSTDC_NO_DEPRECATE
#include <stdlib.h>
#define XML_STATIC // Alternative to defining this here would be setting it project-wide
@@ -19,6 +17,7 @@
#include <algorithm>
#include <stdio.h>
#include <AzFramework/Archive/IArchive.h>
#include <CryCommon/Cry_Color.h>
#include "XMLBinaryReader.h"
#define FLOAT_FMT "%.8g"
@@ -77,7 +76,6 @@ static int __cdecl ascii_stricmp(const char* dst, const char* src)
//////////////////////////////////////////////////////////////////////////
XmlStrCmpFunc g_pXmlStrCmp = &ascii_stricmp;
bool g_bEnableBinaryXmlLoading = true;
//////////////////////////////////////////////////////////////////////////
class CXmlStringData
@@ -113,10 +111,6 @@ public:
void Clear() { m_stringPool.Clear(); }
void SetBlockSize(unsigned int nBlockSize) { m_stringPool.SetBlockSize(nBlockSize); }
void GetMemoryUsage(ICrySizer* pSizer) const
{
pSizer->AddObject(m_stringPool);
}
private:
CSimpleStringPool m_stringPool;
};
@@ -174,23 +168,6 @@ CXmlNode::CXmlNode(const char* tag, bool bReuseStrings, bool bIsProcessingInstru
m_tag = m_pStringPool->AddString(tag);
}
//////////////////////////////////////////////////////////////////////////
// collect allocated memory informations
void CXmlNode::GetMemoryUsage(ICrySizer* pSizer) const
{
pSizer->AddObject(this, sizeof(*this));
pSizer->AddObject(m_pStringPool);
if (m_pChilds)
{
pSizer->AddObject(*m_pChilds);
}
if (m_pAttributes)
{
pSizer->AddContainer(*m_pAttributes);
}
}
//////////////////////////////////////////////////////////////////////////
XmlNodeRef CXmlNode::createNode(const char* tag)
{
@@ -378,13 +355,6 @@ void CXmlNode::setAttr(const char* key, const Vec4& value)
setAttr(key, str);
}
void CXmlNode::setAttr(const char* key, const Vec3d& value)
{
char str[128];
SCOPED_LOCALE_RESETTER;
sprintf_s(str, DOUBLE_FMT "," DOUBLE_FMT "," DOUBLE_FMT, value.x, value.y, value.z);
setAttr(key, str);
}
void CXmlNode::setAttr(const char* key, const Vec2& value)
{
char str[128];
@@ -392,13 +362,6 @@ void CXmlNode::setAttr(const char* key, const Vec2& value)
sprintf_s(str, FLOAT_FMT "," FLOAT_FMT, value.x, value.y);
setAttr(key, str);
}
void CXmlNode::setAttr(const char* key, const Vec2d& value)
{
char str[128];
SCOPED_LOCALE_RESETTER;
sprintf_s(str, DOUBLE_FMT "," DOUBLE_FMT, value.x, value.y);
setAttr(key, str);
}
void CXmlNode::setAttr(const char* key, const Quat& value)
{
@@ -557,22 +520,6 @@ bool CXmlNode::getAttr(const char* key, Vec4& value) const
return false;
}
bool CXmlNode::getAttr(const char* key, Vec3d& value) const
{
const char* svalue = GetValue(key);
if (svalue)
{
SCOPED_LOCALE_RESETTER;
double x, y, z;
if (azsscanf(svalue, "%lf,%lf,%lf", &x, &y, &z) == 3)
{
value = Vec3d(x, y, z);
return true;
}
}
return false;
}
//////////////////////////////////////////////////////////////////////////
bool CXmlNode::getAttr(const char* key, Vec2& value) const
{
@@ -590,22 +537,6 @@ bool CXmlNode::getAttr(const char* key, Vec2& value) const
return false;
}
bool CXmlNode::getAttr(const char* key, Vec2d& value) const
{
const char* svalue = GetValue(key);
if (svalue)
{
SCOPED_LOCALE_RESETTER;
double x, y;
if (azsscanf(svalue, "%lf,%lf", &x, &y) == 2)
{
value = Vec2d(x, y);
return true;
}
}
return false;
}
//////////////////////////////////////////////////////////////////////////
bool CXmlNode::getAttr(const char* key, Quat& value) const
{
@@ -1369,14 +1300,6 @@ public:
// Add new string to pool.
const char* AddString(const char* str) { return m_stringPool.Append(str, (int)strlen(str)); }
//char* AddString( const char *str ) { return (char*)str; }
void GetMemoryUsage(ICrySizer* pSizer) const
{
pSizer->AddObject(this, sizeof(*this));
pSizer->AddObject(m_stringPool);
pSizer->AddObject(m_nodeStack);
}
protected:
void onStartElement(const char* tagName, const char** atts);
void onEndElement(const char* tagName);
@@ -1410,12 +1333,6 @@ protected:
{
XmlNodeRef node;
std::vector<IXmlNode*> childs; //TODO: is it worth lazily initializing this, like CXmlNode::m_pChilds?
void GetMemoryUsage(ICrySizer* pSizer) const
{
pSizer->AddObject(node);
pSizer->AddObject(childs);
}
};
// First node will become root node.
@@ -1735,38 +1652,35 @@ XmlNodeRef XmlParserImp::ParseFile(const char* filename, XmlString& errorString,
AZStd::replace(pakPath.begin(), pakPath.end(), '\\', '/');
}
if (g_bEnableBinaryXmlLoading)
XMLBinary::XMLBinaryReader reader;
XMLBinary::XMLBinaryReader::EResult result;
root = reader.LoadFromBuffer(XMLBinary::XMLBinaryReader::eBufferMemoryHandling_TakeOwnership, pFileContents, fileSize, result);
if (root)
{
XMLBinary::XMLBinaryReader reader;
XMLBinary::XMLBinaryReader::EResult result;
root = reader.LoadFromBuffer(XMLBinary::XMLBinaryReader::eBufferMemoryHandling_TakeOwnership, pFileContents, fileSize, result);
if (root)
return root;
}
if (result != XMLBinary::XMLBinaryReader::eResult_NotBinXml)
{
delete [] pFileContents;
sprintf_s(str, "%s%s (%s)", errorPrefix, reader.GetErrorDescription(), filename);
errorString = str;
CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "%s", str);
return 0;
}
else
{
// not binary XML - refuse to load if in scripts dir and not in bin xml to help reduce hacking
// wish we could compile the text xml parser out, but too much work to get everything moved over
constexpr AZStd::fixed_string<32> strScripts{"Scripts/"};
// exclude files and PAKs from Mods folder
constexpr AZStd::fixed_string<8> modsStr{"Mods/"};
if (_strnicmp(filename, strScripts.c_str(), strScripts.length()) == 0 &&
_strnicmp(adjustedFilename.c_str(), modsStr.c_str(), modsStr.length()) != 0 &&
_strnicmp(pakPath.c_str(), modsStr.c_str(), modsStr.length()) != 0)
{
return root;
}
if (result != XMLBinary::XMLBinaryReader::eResult_NotBinXml)
{
delete [] pFileContents;
sprintf_s(str, "%s%s (%s)", errorPrefix, reader.GetErrorDescription(), filename);
errorString = str;
CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "%s", str);
return 0;
}
else
{
// not binary XML - refuse to load if in scripts dir and not in bin xml to help reduce hacking
// wish we could compile the text xml parser out, but too much work to get everything moved over
constexpr AZStd::fixed_string<32> strScripts{"Scripts/"};
// exclude files and PAKs from Mods folder
constexpr AZStd::fixed_string<8> modsStr{"Mods/"};
if (_strnicmp(filename, strScripts.c_str(), strScripts.length()) == 0 &&
_strnicmp(adjustedFilename.c_str(), modsStr.c_str(), modsStr.length()) != 0 &&
_strnicmp(pakPath.c_str(), modsStr.c_str(), modsStr.length()) != 0)
{
#ifdef _RELEASE
CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "Non binary XML found in scripts dir (%s)", filename);
#endif
}
}
}
@@ -1806,12 +1720,6 @@ XmlParser::~XmlParser()
m_pImpl->Release();
}
void XmlParser::GetMemoryUsage(ICrySizer* pSizer) const
{
pSizer->AddObject(this, sizeof(*this));
pSizer->AddObject(m_pImpl);
}
//////////////////////////////////////////////////////////////////////////
XmlNodeRef XmlParser::ParseBuffer(const char* buffer, int nBufLen, bool bCleanPools, bool bSuppressWarnings)
{
-12
View File
@@ -34,7 +34,6 @@ public:
}
};
virtual const char* AddString(const char* str) = 0;
virtual void GetMemoryUsage(ICrySizer* pSizer) const = 0;
private:
int m_refCount;
};
@@ -68,8 +67,6 @@ public:
const char* getErrorString() const { return m_errorString; }
void GetMemoryUsage(ICrySizer* pSizer) const;
private:
int m_nRefCount;
XmlString m_errorString;
@@ -88,8 +85,6 @@ struct XmlAttribute
const char* key;
const char* value;
void GetMemoryUsage([[maybe_unused]] ICrySizer* pSizer) const{}
bool operator<(const XmlAttribute& attr) const { return g_pXmlStrCmp(key, attr.key) < 0; }
bool operator>(const XmlAttribute& attr) const { return g_pXmlStrCmp(key, attr.key) > 0; }
bool operator==(const XmlAttribute& attr) const { return g_pXmlStrCmp(key, attr.key) == 0; }
@@ -119,9 +114,6 @@ public:
//! Destructor.
~CXmlNode();
// collect allocated memory informations
void GetMemoryUsage(ICrySizer* pSizer) const;
//////////////////////////////////////////////////////////////////////////
// Custom new/delete with pool allocator.
//////////////////////////////////////////////////////////////////////////
@@ -219,11 +211,9 @@ public:
void setAttr(const char* key, float value);
void setAttr(const char* key, double value);
void setAttr(const char* key, const Vec2& value);
void setAttr(const char* key, const Vec2d& value);
void setAttr(const char* key, const Ang3& value);
void setAttr(const char* key, const Vec3& value);
void setAttr(const char* key, const Vec4& value);
void setAttr(const char* key, const Vec3d& value);
void setAttr(const char* key, const Quat& value);
//! Delete attrbute.
@@ -243,11 +233,9 @@ public:
bool getAttr(const char* key, XmlString& value) const {const char* v(NULL); bool boHasAttribute(getAttr(key, &v)); value = v; return boHasAttribute; }
bool getAttr(const char* key, Vec2& value) const;
bool getAttr(const char* key, Vec2d& value) const;
bool getAttr(const char* key, Ang3& value) const;
bool getAttr(const char* key, Vec3& value) const;
bool getAttr(const char* key, Vec4& value) const;
bool getAttr(const char* key, Vec3d& value) const;
bool getAttr(const char* key, Quat& value) const;
bool getAttr(const char* key, ColorB& value) const;
-17
View File
@@ -1,17 +0,0 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#ifndef CRYINCLUDE_CRYSYSTEM_XML_XML_STRING_H
#define CRYINCLUDE_CRYSYSTEM_XML_XML_STRING_H
#pragma once
typedef string xml_string;
#endif // CRYINCLUDE_CRYSYSTEM_XML_XML_STRING_H