Skip to content
Permalink
Browse files

Add xmlLoadString function (#809)

* xmlLoadString initial

* Fix returning xml-node

* Update server CLuaMain::ParseString

* Fix spacing issue

Co-Authored-By: Lpsd <40902730+Lpsd@users.noreply.github.com>

* Fix handling of non-file XML nodes

Ensures that XML file functions (xmlSaveFile, xmlUnloadFile) do not work with XML nodes created without a file (via xmLoadString) and returns correctly to reflect this.

* Implement short-circuit suggestion

* Untabify code

* Clean up SaveXML loop

* Fix node iteration & return errors on invalid XML string

* Fix formatting in CXMLImpl::ParseString

* Clean up a for loop and some misc small things

Co-Authored-By: LopSided <lpsd@users.noreply.github.com>

* Amend return value on failure

* Implement requested change
  • Loading branch information...
patrikjuvonen committed Sep 2, 2019
2 parents d21c66f + 7658620 commit b9d509a6855c285df9439016604782bea1ae8440
@@ -1,11 +1,12 @@
/*****************************************************************************
*
* PROJECT: Multi Theft Auto v1.0
* (Shared logic for modifications)
* PROJECT: Multi Theft Auto
* LICENSE: See LICENSE in the top level directory
* FILE: mods/shared_logic/lua/CLuaMain.cpp
* FILE: mods/deathmatch/logic/lua/CLuaMain.cpp
* PURPOSE: Lua main
*
* Multi Theft Auto is available from http://www.multitheftauto.com/
*
*****************************************************************************/

#include "StdInc.h"
@@ -362,45 +363,46 @@ CXMLFile* CLuaMain::CreateXML(const char* szFilename, bool bUseIDs, bool bReadOn
return pFile;
}

void CLuaMain::DestroyXML(CXMLFile* pFile)
CXMLNode* CLuaMain::ParseString(const char* strXmlContent)
{
CXMLNode* xmlNode = g_pCore->GetXML()->ParseString(strXmlContent);
return xmlNode;
}

bool CLuaMain::DestroyXML(CXMLFile* pFile)
{
if (!m_XMLFiles.empty())
m_XMLFiles.remove(pFile);
if (m_XMLFiles.empty())
return false;
m_XMLFiles.remove(pFile);
delete pFile;
return true;
}

void CLuaMain::DestroyXML(CXMLNode* pRootNode)
bool CLuaMain::DestroyXML(CXMLNode* pRootNode)
{
list<CXMLFile*>::iterator iter;
for (iter = m_XMLFiles.begin(); iter != m_XMLFiles.end(); iter++)
if (m_XMLFiles.empty())
return false;
for (CXMLFile* pFile : m_XMLFiles)
{
CXMLFile* file = (*iter);
if (file)
if (pFile)
{
if (file->GetRootNode() == pRootNode)
if (pFile->GetRootNode() == pRootNode)
{
delete file;
m_XMLFiles.erase(iter);
m_XMLFiles.remove(pFile);
delete pFile;
break;
}
}
}
return true;
}

bool CLuaMain::SaveXML(CXMLNode* pRootNode)
{
list<CXMLFile*>::iterator iter;
for (iter = m_XMLFiles.begin(); iter != m_XMLFiles.end(); iter++)
{
CXMLFile* file = (*iter);
if (file)
{
if (file->GetRootNode() == pRootNode)
{
return file->Write();
}
}
}
for (CXMLFile* pFile : m_XMLFiles)
if (pFile)
if (pFile->GetRootNode() == pRootNode)
return pFile->Write();
if (m_pResource)
{
list<CResourceConfigItem*>::iterator iter = m_pResource->ConfigIterBegin();
@@ -411,9 +413,7 @@ bool CLuaMain::SaveXML(CXMLNode* pRootNode)
{
CXMLFile* pFile = pConfigItem->GetFile();
if (pFile)
{
return pFile->Write();
}
return false;
}
}
@@ -62,8 +62,9 @@ class CLuaMain //: public CClient
class CResource* GetResource() { return m_pResource; }

CXMLFile* CreateXML(const char* szFilename, bool bUseIDs = true, bool bReadOnly = false);
void DestroyXML(CXMLFile* pFile);
void DestroyXML(CXMLNode* pRootNode);
CXMLNode* ParseString(const char* strXmlContent);
bool DestroyXML(CXMLFile* pFile);
bool DestroyXML(CXMLNode* pRootNode);
bool SaveXML(CXMLNode* pRootNode);
unsigned long GetXMLFileCount() const { return m_XMLFiles.size(); };
unsigned long GetTimerCount() const { return m_pLuaTimerManager ? m_pLuaTimerManager->GetTimerCount() : 0; };
@@ -1,6 +1,6 @@
/*****************************************************************************
*
* PROJECT: Multi Theft Auto v1.0
* PROJECT: Multi Theft Auto
* LICENSE: See LICENSE in the top level directory
* FILE: mods/deathmatch/logic/lua/CLuaMain.cpp
* PURPOSE: Lua virtual machine container class
@@ -416,44 +416,46 @@ CXMLFile* CLuaMain::CreateXML(const char* szFilename, bool bUseIDs, bool bReadOn
return pFile;
}

void CLuaMain::DestroyXML(CXMLFile* pFile)
CXMLNode* CLuaMain::ParseString(const char* strXmlContent)
{
CXMLNode* xmlNode = g_pServerInterface->GetXML()->ParseString(strXmlContent);
return xmlNode;
}

bool CLuaMain::DestroyXML(CXMLFile* pFile)
{
if (m_XMLFiles.empty())
return false;
m_XMLFiles.remove(pFile);
delete pFile;
return true;
}

void CLuaMain::DestroyXML(CXMLNode* pRootNode)
bool CLuaMain::DestroyXML(CXMLNode* pRootNode)
{
list<CXMLFile*>::iterator iter;
for (iter = m_XMLFiles.begin(); iter != m_XMLFiles.end(); ++iter)
if (m_XMLFiles.empty())
return false;
for (CXMLFile* pFile : m_XMLFiles)
{
CXMLFile* file = (*iter);
if (file)
if (pFile)
{
if (file->GetRootNode() == pRootNode)
if (pFile->GetRootNode() == pRootNode)
{
m_XMLFiles.erase(iter);
delete file;
m_XMLFiles.remove(pFile);
delete pFile;
break;
}
}
}
return true;
}

bool CLuaMain::SaveXML(CXMLNode* pRootNode)
{
list<CXMLFile*>::iterator iter;
for (iter = m_XMLFiles.begin(); iter != m_XMLFiles.end(); ++iter)
{
CXMLFile* file = (*iter);
if (file)
{
if (file->GetRootNode() == pRootNode)
{
return file->Write();
}
}
}
for (CXMLFile* pFile : m_XMLFiles)
if (pFile)
if (pFile->GetRootNode() == pRootNode)
return pFile->Write();
if (m_pResource)
{
list<CResourceFile*>::iterator iter = m_pResource->IterBegin();
@@ -467,9 +469,7 @@ bool CLuaMain::SaveXML(CXMLNode* pRootNode)
{
CXMLFile* pFile = pConfigItem->GetFile();
if (pFile)
{
return pFile->Write();
}
return false;
}
}
@@ -67,8 +67,9 @@ class CLuaMain //: public CClient
CMapManager* GetMapManager() const { return m_pMapManager; };

CXMLFile* CreateXML(const char* szFilename, bool bUseIDs = true, bool bReadOnly = false);
void DestroyXML(CXMLFile* pFile);
void DestroyXML(CXMLNode* pRootNode);
CXMLNode* ParseString(const char* strXmlContent);
bool DestroyXML(CXMLFile* pFile);
bool DestroyXML(CXMLNode* pRootNode);
bool SaveXML(CXMLNode* pRootNode);
bool XMLExists(CXMLFile* pFile);
unsigned long GetXMLFileCount() const { return m_XMLFiles.size(); };
@@ -1,6 +1,6 @@
/*****************************************************************************
*
* PROJECT: Multi Theft Auto v1.0
* PROJECT: Multi Theft Auto
* LICENSE: See LICENSE in the top level directory
* FILE: xml/CXMLImpl.cpp
* PURPOSE: XML handler class
@@ -32,65 +32,83 @@ CXMLFile* CXMLImpl::CreateXML(const char* szFilename, bool bUseIDs, bool bReadOn
CXMLFile* xmlFile = new CXMLFileImpl(szFilename, bUseIDs, bReadOnly);
if (xmlFile->IsValid())
return xmlFile;
else
{
delete xmlFile;
return NULL;
}
delete xmlFile;
return nullptr;
}

void CXMLImpl::DeleteXML(CXMLFile* pFile)
{
delete pFile;
}

CXMLNode* CXMLImpl::ParseString(const char* strXmlContent)
{
TiXmlDocument* xmlDoc = new TiXmlDocument();
if (xmlDoc)
{
if (xmlDoc->Parse(strXmlContent, 0, TIXML_ENCODING_UTF8))
{
TiXmlElement* xmlDocumentRoot = xmlDoc->RootElement();
CXMLNodeImpl* xmlBaseNode = new CXMLNodeImpl(nullptr, nullptr, *xmlDocumentRoot);
CXMLNode* xmlRootNode = CXMLImpl::BuildNode(xmlBaseNode, xmlDocumentRoot);
return xmlRootNode;
}
}
return nullptr;
}

CXMLNode* CXMLImpl::BuildNode(CXMLNodeImpl* xmlParent, TiXmlNode* xmlNode)
{
TiXmlNode* xmlChild = nullptr;
TiXmlElement* xmlChildElement;
CXMLNodeImpl* xmlChildNode;
while (xmlChild = xmlNode->IterateChildren(xmlChild))
{
xmlChildElement = xmlChild->ToElement();
xmlChildNode = new CXMLNodeImpl(nullptr, xmlParent, *xmlChildElement);
CXMLImpl::BuildNode(xmlChildNode, xmlChildElement);
}
return xmlParent;
}

CXMLNode* CXMLImpl::CreateDummyNode()
{
CXMLNode* xmlNode = new CXMLNodeImpl(NULL, NULL, *new TiXmlElement("dummy_storage"));
CXMLNode* xmlNode = new CXMLNodeImpl(nullptr, nullptr, *new TiXmlElement("dummy_storage"));
if (xmlNode->IsValid())
return xmlNode;
else
{
delete xmlNode;
return NULL;
}
delete xmlNode;
return nullptr;
}

CXMLAttribute* CXMLImpl::GetAttrFromID(unsigned long ulID)
{
// Grab it and verify the type
CXMLCommon* pCommon = CXMLArray::GetEntry(ulID);
if (pCommon && pCommon->GetClassType() == CXML_ATTR)
{
return reinterpret_cast<CXMLAttribute*>(pCommon);
}

// Doesn't exist or bad type
return NULL;
return nullptr;
}

CXMLFile* CXMLImpl::GetFileFromID(unsigned long ulID)
{
// Grab it and verify the type
CXMLCommon* pCommon = CXMLArray::GetEntry(ulID);
if (pCommon && pCommon->GetClassType() == CXML_FILE)
{
return reinterpret_cast<CXMLFile*>(pCommon);
}

// Doesn't exist or bad type
return NULL;
return nullptr;
}

CXMLNode* CXMLImpl::GetNodeFromID(unsigned long ulID)
{
// Grab it and verify the type
CXMLCommon* pCommon = CXMLArray::GetEntry(ulID);
if (pCommon && pCommon->GetClassType() == CXML_NODE)
{
return reinterpret_cast<CXMLNode*>(pCommon);
}

// Doesn't exist or bad type
return NULL;
return nullptr;
}
@@ -1,6 +1,6 @@
/*****************************************************************************
*
* PROJECT: Multi Theft Auto v1.0
* PROJECT: Multi Theft Auto
* LICENSE: See LICENSE in the top level directory
* FILE: xml/CXMLImpl.h
* PURPOSE: XML handler class
@@ -20,6 +20,8 @@ class CXMLImpl : public CXML
virtual ~CXMLImpl();

CXMLFile* CreateXML(const char* szFilename, bool bUseIDs, bool bReadOnly);
CXMLNode* ParseString(const char* strXmlContent);
CXMLNode* BuildNode(CXMLNodeImpl* xmlParent, TiXmlNode* xmlNode);
void DeleteXML(CXMLFile* pFile);

CXMLNode* CreateDummyNode();
@@ -14,7 +14,7 @@
using std::list;

CXMLNodeImpl::CXMLNodeImpl(CXMLFileImpl* pFile, CXMLNodeImpl* pParent, TiXmlElement& Node)
: m_ulID(INVALID_XML_ID), m_bUsingIDs(pFile && pFile->IsUsingIDs()), m_pNode(&Node), m_Attributes(Node, pFile && pFile->IsUsingIDs())
: m_ulID(INVALID_XML_ID), m_bUsingIDs((!pFile) || pFile && pFile->IsUsingIDs()), m_pNode(&Node), m_Attributes(Node, (!pFile) || pFile && pFile->IsUsingIDs())
{
// Init
m_pFile = pFile;
@@ -59,7 +59,7 @@ class CXMLNodeImpl : public CXMLNode
eXMLClass GetClassType() { return CXML_NODE; };
unsigned long GetID()
{
dassert(m_pFile && m_pFile->IsUsingIDs());
dassert((!m_pFile) || m_pFile && m_pFile->IsUsingIDs());
return m_ulID;
};
bool IsUsingIDs() { return m_bUsingIDs; };

0 comments on commit b9d509a

Please sign in to comment.
You can’t perform that action at this time.