Skip to content

Commit b9d509a

Browse files
Add xmlLoadString function (#809)
* xmlLoadString initial * Fix returning xml-node * Update server CLuaMain::ParseString * Fix spacing issue Co-Authored-By: Lpsd <[email protected]> * 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 <[email protected]> * Amend return value on failure * Implement requested change
2 parents d21c66f + 7658620 commit b9d509a

File tree

11 files changed

+140
-83
lines changed

11 files changed

+140
-83
lines changed

Client/mods/deathmatch/logic/lua/CLuaMain.cpp

Lines changed: 28 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
/*****************************************************************************
22
*
3-
* PROJECT: Multi Theft Auto v1.0
4-
* (Shared logic for modifications)
3+
* PROJECT: Multi Theft Auto
54
* LICENSE: See LICENSE in the top level directory
6-
* FILE: mods/shared_logic/lua/CLuaMain.cpp
5+
* FILE: mods/deathmatch/logic/lua/CLuaMain.cpp
76
* PURPOSE: Lua main
87
*
8+
* Multi Theft Auto is available from http://www.multitheftauto.com/
9+
*
910
*****************************************************************************/
1011

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

365-
void CLuaMain::DestroyXML(CXMLFile* pFile)
366+
CXMLNode* CLuaMain::ParseString(const char* strXmlContent)
367+
{
368+
CXMLNode* xmlNode = g_pCore->GetXML()->ParseString(strXmlContent);
369+
return xmlNode;
370+
}
371+
372+
bool CLuaMain::DestroyXML(CXMLFile* pFile)
366373
{
367-
if (!m_XMLFiles.empty())
368-
m_XMLFiles.remove(pFile);
374+
if (m_XMLFiles.empty())
375+
return false;
376+
m_XMLFiles.remove(pFile);
369377
delete pFile;
378+
return true;
370379
}
371380

372-
void CLuaMain::DestroyXML(CXMLNode* pRootNode)
381+
bool CLuaMain::DestroyXML(CXMLNode* pRootNode)
373382
{
374-
list<CXMLFile*>::iterator iter;
375-
for (iter = m_XMLFiles.begin(); iter != m_XMLFiles.end(); iter++)
383+
if (m_XMLFiles.empty())
384+
return false;
385+
for (CXMLFile* pFile : m_XMLFiles)
376386
{
377-
CXMLFile* file = (*iter);
378-
if (file)
387+
if (pFile)
379388
{
380-
if (file->GetRootNode() == pRootNode)
389+
if (pFile->GetRootNode() == pRootNode)
381390
{
382-
delete file;
383-
m_XMLFiles.erase(iter);
391+
m_XMLFiles.remove(pFile);
392+
delete pFile;
384393
break;
385394
}
386395
}
387396
}
397+
return true;
388398
}
389399

390400
bool CLuaMain::SaveXML(CXMLNode* pRootNode)
391401
{
392-
list<CXMLFile*>::iterator iter;
393-
for (iter = m_XMLFiles.begin(); iter != m_XMLFiles.end(); iter++)
394-
{
395-
CXMLFile* file = (*iter);
396-
if (file)
397-
{
398-
if (file->GetRootNode() == pRootNode)
399-
{
400-
return file->Write();
401-
}
402-
}
403-
}
402+
for (CXMLFile* pFile : m_XMLFiles)
403+
if (pFile)
404+
if (pFile->GetRootNode() == pRootNode)
405+
return pFile->Write();
404406
if (m_pResource)
405407
{
406408
list<CResourceConfigItem*>::iterator iter = m_pResource->ConfigIterBegin();
@@ -411,9 +413,7 @@ bool CLuaMain::SaveXML(CXMLNode* pRootNode)
411413
{
412414
CXMLFile* pFile = pConfigItem->GetFile();
413415
if (pFile)
414-
{
415416
return pFile->Write();
416-
}
417417
return false;
418418
}
419419
}

Client/mods/deathmatch/logic/lua/CLuaMain.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,9 @@ class CLuaMain //: public CClient
6262
class CResource* GetResource() { return m_pResource; }
6363

6464
CXMLFile* CreateXML(const char* szFilename, bool bUseIDs = true, bool bReadOnly = false);
65-
void DestroyXML(CXMLFile* pFile);
66-
void DestroyXML(CXMLNode* pRootNode);
65+
CXMLNode* ParseString(const char* strXmlContent);
66+
bool DestroyXML(CXMLFile* pFile);
67+
bool DestroyXML(CXMLNode* pRootNode);
6768
bool SaveXML(CXMLNode* pRootNode);
6869
unsigned long GetXMLFileCount() const { return m_XMLFiles.size(); };
6970
unsigned long GetTimerCount() const { return m_pLuaTimerManager ? m_pLuaTimerManager->GetTimerCount() : 0; };

Server/mods/deathmatch/logic/lua/CLuaMain.cpp

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*****************************************************************************
22
*
3-
* PROJECT: Multi Theft Auto v1.0
3+
* PROJECT: Multi Theft Auto
44
* LICENSE: See LICENSE in the top level directory
55
* FILE: mods/deathmatch/logic/lua/CLuaMain.cpp
66
* PURPOSE: Lua virtual machine container class
@@ -416,44 +416,46 @@ CXMLFile* CLuaMain::CreateXML(const char* szFilename, bool bUseIDs, bool bReadOn
416416
return pFile;
417417
}
418418

419-
void CLuaMain::DestroyXML(CXMLFile* pFile)
419+
CXMLNode* CLuaMain::ParseString(const char* strXmlContent)
420420
{
421+
CXMLNode* xmlNode = g_pServerInterface->GetXML()->ParseString(strXmlContent);
422+
return xmlNode;
423+
}
424+
425+
bool CLuaMain::DestroyXML(CXMLFile* pFile)
426+
{
427+
if (m_XMLFiles.empty())
428+
return false;
421429
m_XMLFiles.remove(pFile);
422430
delete pFile;
431+
return true;
423432
}
424433

425-
void CLuaMain::DestroyXML(CXMLNode* pRootNode)
434+
bool CLuaMain::DestroyXML(CXMLNode* pRootNode)
426435
{
427-
list<CXMLFile*>::iterator iter;
428-
for (iter = m_XMLFiles.begin(); iter != m_XMLFiles.end(); ++iter)
436+
if (m_XMLFiles.empty())
437+
return false;
438+
for (CXMLFile* pFile : m_XMLFiles)
429439
{
430-
CXMLFile* file = (*iter);
431-
if (file)
440+
if (pFile)
432441
{
433-
if (file->GetRootNode() == pRootNode)
442+
if (pFile->GetRootNode() == pRootNode)
434443
{
435-
m_XMLFiles.erase(iter);
436-
delete file;
444+
m_XMLFiles.remove(pFile);
445+
delete pFile;
437446
break;
438447
}
439448
}
440449
}
450+
return true;
441451
}
442452

443453
bool CLuaMain::SaveXML(CXMLNode* pRootNode)
444454
{
445-
list<CXMLFile*>::iterator iter;
446-
for (iter = m_XMLFiles.begin(); iter != m_XMLFiles.end(); ++iter)
447-
{
448-
CXMLFile* file = (*iter);
449-
if (file)
450-
{
451-
if (file->GetRootNode() == pRootNode)
452-
{
453-
return file->Write();
454-
}
455-
}
456-
}
455+
for (CXMLFile* pFile : m_XMLFiles)
456+
if (pFile)
457+
if (pFile->GetRootNode() == pRootNode)
458+
return pFile->Write();
457459
if (m_pResource)
458460
{
459461
list<CResourceFile*>::iterator iter = m_pResource->IterBegin();
@@ -467,9 +469,7 @@ bool CLuaMain::SaveXML(CXMLNode* pRootNode)
467469
{
468470
CXMLFile* pFile = pConfigItem->GetFile();
469471
if (pFile)
470-
{
471472
return pFile->Write();
472-
}
473473
return false;
474474
}
475475
}

Server/mods/deathmatch/logic/lua/CLuaMain.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,9 @@ class CLuaMain //: public CClient
6767
CMapManager* GetMapManager() const { return m_pMapManager; };
6868

6969
CXMLFile* CreateXML(const char* szFilename, bool bUseIDs = true, bool bReadOnly = false);
70-
void DestroyXML(CXMLFile* pFile);
71-
void DestroyXML(CXMLNode* pRootNode);
70+
CXMLNode* ParseString(const char* strXmlContent);
71+
bool DestroyXML(CXMLFile* pFile);
72+
bool DestroyXML(CXMLNode* pRootNode);
7273
bool SaveXML(CXMLNode* pRootNode);
7374
bool XMLExists(CXMLFile* pFile);
7475
unsigned long GetXMLFileCount() const { return m_XMLFiles.size(); };

Shared/XML/CXMLImpl.cpp

Lines changed: 39 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*****************************************************************************
22
*
3-
* PROJECT: Multi Theft Auto v1.0
3+
* PROJECT: Multi Theft Auto
44
* LICENSE: See LICENSE in the top level directory
55
* FILE: xml/CXMLImpl.cpp
66
* PURPOSE: XML handler class
@@ -32,65 +32,83 @@ CXMLFile* CXMLImpl::CreateXML(const char* szFilename, bool bUseIDs, bool bReadOn
3232
CXMLFile* xmlFile = new CXMLFileImpl(szFilename, bUseIDs, bReadOnly);
3333
if (xmlFile->IsValid())
3434
return xmlFile;
35-
else
36-
{
37-
delete xmlFile;
38-
return NULL;
39-
}
35+
delete xmlFile;
36+
return nullptr;
4037
}
4138

4239
void CXMLImpl::DeleteXML(CXMLFile* pFile)
4340
{
4441
delete pFile;
4542
}
4643

44+
CXMLNode* CXMLImpl::ParseString(const char* strXmlContent)
45+
{
46+
TiXmlDocument* xmlDoc = new TiXmlDocument();
47+
if (xmlDoc)
48+
{
49+
if (xmlDoc->Parse(strXmlContent, 0, TIXML_ENCODING_UTF8))
50+
{
51+
TiXmlElement* xmlDocumentRoot = xmlDoc->RootElement();
52+
CXMLNodeImpl* xmlBaseNode = new CXMLNodeImpl(nullptr, nullptr, *xmlDocumentRoot);
53+
CXMLNode* xmlRootNode = CXMLImpl::BuildNode(xmlBaseNode, xmlDocumentRoot);
54+
return xmlRootNode;
55+
}
56+
}
57+
return nullptr;
58+
}
59+
60+
CXMLNode* CXMLImpl::BuildNode(CXMLNodeImpl* xmlParent, TiXmlNode* xmlNode)
61+
{
62+
TiXmlNode* xmlChild = nullptr;
63+
TiXmlElement* xmlChildElement;
64+
CXMLNodeImpl* xmlChildNode;
65+
while (xmlChild = xmlNode->IterateChildren(xmlChild))
66+
{
67+
xmlChildElement = xmlChild->ToElement();
68+
xmlChildNode = new CXMLNodeImpl(nullptr, xmlParent, *xmlChildElement);
69+
CXMLImpl::BuildNode(xmlChildNode, xmlChildElement);
70+
}
71+
return xmlParent;
72+
}
73+
4774
CXMLNode* CXMLImpl::CreateDummyNode()
4875
{
49-
CXMLNode* xmlNode = new CXMLNodeImpl(NULL, NULL, *new TiXmlElement("dummy_storage"));
76+
CXMLNode* xmlNode = new CXMLNodeImpl(nullptr, nullptr, *new TiXmlElement("dummy_storage"));
5077
if (xmlNode->IsValid())
5178
return xmlNode;
52-
else
53-
{
54-
delete xmlNode;
55-
return NULL;
56-
}
79+
delete xmlNode;
80+
return nullptr;
5781
}
5882

5983
CXMLAttribute* CXMLImpl::GetAttrFromID(unsigned long ulID)
6084
{
6185
// Grab it and verify the type
6286
CXMLCommon* pCommon = CXMLArray::GetEntry(ulID);
6387
if (pCommon && pCommon->GetClassType() == CXML_ATTR)
64-
{
6588
return reinterpret_cast<CXMLAttribute*>(pCommon);
66-
}
6789

6890
// Doesn't exist or bad type
69-
return NULL;
91+
return nullptr;
7092
}
7193

7294
CXMLFile* CXMLImpl::GetFileFromID(unsigned long ulID)
7395
{
7496
// Grab it and verify the type
7597
CXMLCommon* pCommon = CXMLArray::GetEntry(ulID);
7698
if (pCommon && pCommon->GetClassType() == CXML_FILE)
77-
{
7899
return reinterpret_cast<CXMLFile*>(pCommon);
79-
}
80100

81101
// Doesn't exist or bad type
82-
return NULL;
102+
return nullptr;
83103
}
84104

85105
CXMLNode* CXMLImpl::GetNodeFromID(unsigned long ulID)
86106
{
87107
// Grab it and verify the type
88108
CXMLCommon* pCommon = CXMLArray::GetEntry(ulID);
89109
if (pCommon && pCommon->GetClassType() == CXML_NODE)
90-
{
91110
return reinterpret_cast<CXMLNode*>(pCommon);
92-
}
93111

94112
// Doesn't exist or bad type
95-
return NULL;
113+
return nullptr;
96114
}

Shared/XML/CXMLImpl.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*****************************************************************************
22
*
3-
* PROJECT: Multi Theft Auto v1.0
3+
* PROJECT: Multi Theft Auto
44
* LICENSE: See LICENSE in the top level directory
55
* FILE: xml/CXMLImpl.h
66
* PURPOSE: XML handler class
@@ -20,6 +20,8 @@ class CXMLImpl : public CXML
2020
virtual ~CXMLImpl();
2121

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

2527
CXMLNode* CreateDummyNode();

Shared/XML/CXMLNodeImpl.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
using std::list;
1515

1616
CXMLNodeImpl::CXMLNodeImpl(CXMLFileImpl* pFile, CXMLNodeImpl* pParent, TiXmlElement& Node)
17-
: m_ulID(INVALID_XML_ID), m_bUsingIDs(pFile && pFile->IsUsingIDs()), m_pNode(&Node), m_Attributes(Node, pFile && pFile->IsUsingIDs())
17+
: m_ulID(INVALID_XML_ID), m_bUsingIDs((!pFile) || pFile && pFile->IsUsingIDs()), m_pNode(&Node), m_Attributes(Node, (!pFile) || pFile && pFile->IsUsingIDs())
1818
{
1919
// Init
2020
m_pFile = pFile;

Shared/XML/CXMLNodeImpl.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ class CXMLNodeImpl : public CXMLNode
5959
eXMLClass GetClassType() { return CXML_NODE; };
6060
unsigned long GetID()
6161
{
62-
dassert(m_pFile && m_pFile->IsUsingIDs());
62+
dassert((!m_pFile) || m_pFile && m_pFile->IsUsingIDs());
6363
return m_ulID;
6464
};
6565
bool IsUsingIDs() { return m_bUsingIDs; };

0 commit comments

Comments
 (0)