mirror of https://github.com/axmolengine/axmol.git
added ccuserdefault tinyxml2 ver
This commit is contained in:
parent
684b46dd74
commit
05bece9d07
|
@ -24,8 +24,7 @@ THE SOFTWARE.
|
||||||
#include "CCUserDefault.h"
|
#include "CCUserDefault.h"
|
||||||
#include "platform/CCCommon.h"
|
#include "platform/CCCommon.h"
|
||||||
#include "platform/CCFileUtils.h"
|
#include "platform/CCFileUtils.h"
|
||||||
#include <libxml/parser.h>
|
#include "tinyxml2/tinyxml2.h"
|
||||||
#include <libxml/tree.h>
|
|
||||||
|
|
||||||
// root name of xml
|
// root name of xml
|
||||||
#define USERDEFAULT_ROOT_NAME "userDefaultRoot"
|
#define USERDEFAULT_ROOT_NAME "userDefaultRoot"
|
||||||
|
@ -36,8 +35,6 @@ using namespace std;
|
||||||
|
|
||||||
NS_CC_BEGIN
|
NS_CC_BEGIN
|
||||||
|
|
||||||
static xmlDocPtr g_sharedDoc = NULL;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* define the functions here because we don't want to
|
* define the functions here because we don't want to
|
||||||
* export xmlNodePtr and other types in "CCUserDefault.h"
|
* export xmlNodePtr and other types in "CCUserDefault.h"
|
||||||
|
@ -45,7 +42,7 @@ static xmlDocPtr g_sharedDoc = NULL;
|
||||||
|
|
||||||
static xmlNodePtr getXMLNodeForKey(const char* pKey, xmlNodePtr *rootNode)
|
static xmlNodePtr getXMLNodeForKey(const char* pKey, xmlNodePtr *rootNode)
|
||||||
{
|
{
|
||||||
xmlNodePtr curNode = NULL;
|
tinyxml2::XMLElement* curNode = NULL;
|
||||||
|
|
||||||
// check the key value
|
// check the key value
|
||||||
if (! pKey)
|
if (! pKey)
|
||||||
|
@ -55,76 +52,78 @@ static xmlNodePtr getXMLNodeForKey(const char* pKey, xmlNodePtr *rootNode)
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
// get root node
|
tinyxml2::XMLDocument* xmlDoc = new tinyxml2::XMLDocument();
|
||||||
*rootNode = xmlDocGetRootElement(g_sharedDoc);
|
*doc = xmlDoc;
|
||||||
if (NULL == *rootNode)
|
CCFileData data(CCUserDefault::sharedUserDefault()->getXMLFilePath().c_str(),"rt");
|
||||||
{
|
const char* pXmlBuffer = (const char*)data.getBuffer();
|
||||||
CCLOG("read root node error");
|
if(NULL == pXmlBuffer)
|
||||||
break;
|
{
|
||||||
}
|
CCLOG("can not read xml file");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
xmlDoc->Parse(pXmlBuffer);
|
||||||
|
// get root node
|
||||||
|
*rootNode = xmlDoc->RootElement();
|
||||||
|
if (NULL == *rootNode)
|
||||||
|
{
|
||||||
|
CCLOG("read root node error");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// find the node
|
||||||
|
curNode = (*rootNode)->FirstChildElement();
|
||||||
|
while (NULL != curNode)
|
||||||
|
{
|
||||||
|
const char* nodeName = curNode->Value();
|
||||||
|
if (!strcmp(nodeName, pKey))
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
// find the node
|
curNode = curNode->NextSiblingElement();
|
||||||
curNode = (*rootNode)->xmlChildrenNode;
|
}
|
||||||
while (NULL != curNode)
|
} while (0);
|
||||||
{
|
|
||||||
if (! xmlStrcmp(curNode->name, BAD_CAST pKey))
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
curNode = curNode->next;
|
return curNode;
|
||||||
}
|
|
||||||
} while (0);
|
|
||||||
|
|
||||||
return curNode;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline const char* getValueForKey(const char* pKey)
|
|
||||||
{
|
|
||||||
const char* ret = NULL;
|
|
||||||
xmlNodePtr rootNode;
|
|
||||||
xmlNodePtr node = getXMLNodeForKey(pKey, &rootNode);
|
|
||||||
|
|
||||||
// find the node
|
|
||||||
if (node)
|
|
||||||
{
|
|
||||||
ret = (const char*)xmlNodeGetContent(node);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void setValueForKey(const char* pKey, const char* pValue)
|
static void setValueForKey(const char* pKey, const char* pValue)
|
||||||
{
|
{
|
||||||
xmlNodePtr rootNode;
|
tinyxml2::XMLElement* rootNode;
|
||||||
xmlNodePtr node;
|
tinyxml2::XMLDocument* doc;
|
||||||
|
tinyxml2::XMLElement* node;
|
||||||
|
// check the params
|
||||||
|
if (! pKey || ! pValue)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// find the node
|
||||||
|
node = getXMLNodeForKey(pKey, &rootNode, &doc);
|
||||||
|
// if node exist, change the content
|
||||||
|
if (node)
|
||||||
|
{
|
||||||
|
node->FirstChild()->SetValue(pValue);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (rootNode)
|
||||||
|
{
|
||||||
|
|
||||||
|
tinyxml2::XMLElement* tmpNode = doc->NewElement(pKey);//new tinyxml2::XMLElement(pKey);
|
||||||
|
rootNode->LinkEndChild(tmpNode);
|
||||||
|
tinyxml2::XMLText* content = doc->NewText(pValue);//new tinyxml2::XMLText(pValue);
|
||||||
|
tmpNode->LinkEndChild(content);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// check the params
|
|
||||||
if (! pKey || ! pValue)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// find the node
|
// save file and free doc
|
||||||
node = getXMLNodeForKey(pKey, &rootNode);
|
if (doc)
|
||||||
|
{
|
||||||
// if node exist, change the content
|
|
||||||
if (node)
|
doc->SaveFile(CCUserDefault::sharedUserDefault()->getXMLFilePath().c_str());
|
||||||
{
|
delete doc;
|
||||||
xmlNodeSetContent(node, BAD_CAST pValue);
|
}
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (rootNode)
|
|
||||||
{
|
|
||||||
// the node doesn't exist, add a new one
|
|
||||||
// libxml in android doesn't support xmlNewTextChild, so use this approach
|
|
||||||
xmlNodePtr tmpNode = xmlNewNode(NULL, BAD_CAST pKey);
|
|
||||||
xmlNodePtr content = xmlNewText(BAD_CAST pValue);
|
|
||||||
xmlAddChild(rootNode, tmpNode);
|
|
||||||
xmlAddChild(tmpNode, content);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -141,19 +140,13 @@ bool CCUserDefault::m_sbIsFilePathInitialized = false;
|
||||||
*/
|
*/
|
||||||
CCUserDefault::~CCUserDefault()
|
CCUserDefault::~CCUserDefault()
|
||||||
{
|
{
|
||||||
flush();
|
CC_SAFE_DELETE(m_spUserDefault);
|
||||||
if (g_sharedDoc)
|
|
||||||
{
|
|
||||||
xmlFreeDoc(g_sharedDoc);
|
|
||||||
g_sharedDoc = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_spUserDefault = NULL;
|
m_spUserDefault = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
CCUserDefault::CCUserDefault()
|
CCUserDefault::CCUserDefault()
|
||||||
{
|
{
|
||||||
g_sharedDoc = xmlReadFile(getXMLFilePath().c_str(), "utf-8", XML_PARSE_RECOVER);
|
m_spUserDefault = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CCUserDefault::purgeSharedUserDefault()
|
void CCUserDefault::purgeSharedUserDefault()
|
||||||
|
@ -169,16 +162,27 @@ void CCUserDefault::purgeSharedUserDefault()
|
||||||
|
|
||||||
bool CCUserDefault::getBoolForKey(const char* pKey, bool defaultValue)
|
bool CCUserDefault::getBoolForKey(const char* pKey, bool defaultValue)
|
||||||
{
|
{
|
||||||
const char* value = getValueForKey(pKey);
|
const char* value = NULL;
|
||||||
bool ret = defaultValue;
|
tinyxml2::XMLElement* rootNode;
|
||||||
|
tinyxml2::XMLDocument* doc;
|
||||||
|
tinyxml2::XMLElement* node;
|
||||||
|
node = getXMLNodeForKey(pKey, &rootNode, &doc);
|
||||||
|
// find the node
|
||||||
|
if (node)
|
||||||
|
{
|
||||||
|
value = (const char*)(node->FirstChild()->Value());
|
||||||
|
}
|
||||||
|
|
||||||
if (value)
|
bool ret = defaultValue;
|
||||||
{
|
|
||||||
ret = (! strcmp(value, "true"));
|
|
||||||
xmlFree((void*)value);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
if (value)
|
||||||
|
{
|
||||||
|
ret = (! strcmp(value, "true"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (doc) delete doc;
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int CCUserDefault::getIntegerForKey(const char* pKey)
|
int CCUserDefault::getIntegerForKey(const char* pKey)
|
||||||
|
@ -188,16 +192,31 @@ int CCUserDefault::getIntegerForKey(const char* pKey)
|
||||||
|
|
||||||
int CCUserDefault::getIntegerForKey(const char* pKey, int defaultValue)
|
int CCUserDefault::getIntegerForKey(const char* pKey, int defaultValue)
|
||||||
{
|
{
|
||||||
const char* value = getValueForKey(pKey);
|
const char* value = NULL;
|
||||||
int ret = defaultValue;
|
tinyxml2::XMLElement* rootNode;
|
||||||
|
tinyxml2::XMLDocument* doc;
|
||||||
|
tinyxml2::XMLElement* node;
|
||||||
|
node = getXMLNodeForKey(pKey, &rootNode, &doc);
|
||||||
|
// find the node
|
||||||
|
if (node)
|
||||||
|
{
|
||||||
|
value = (const char*)(node->FirstChild()->Value());
|
||||||
|
}
|
||||||
|
|
||||||
if (value)
|
int ret = defaultValue;
|
||||||
{
|
|
||||||
ret = atoi(value);
|
|
||||||
xmlFree((void*)value);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
if (value)
|
||||||
|
{
|
||||||
|
ret = atoi(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(doc)
|
||||||
|
{
|
||||||
|
delete doc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
float CCUserDefault::getFloatForKey(const char* pKey)
|
float CCUserDefault::getFloatForKey(const char* pKey)
|
||||||
|
@ -219,16 +238,27 @@ double CCUserDefault::getDoubleForKey(const char* pKey)
|
||||||
|
|
||||||
double CCUserDefault::getDoubleForKey(const char* pKey, double defaultValue)
|
double CCUserDefault::getDoubleForKey(const char* pKey, double defaultValue)
|
||||||
{
|
{
|
||||||
const char* value = getValueForKey(pKey);
|
const char* value = NULL;
|
||||||
double ret = defaultValue;
|
tinyxml2::XMLElement* rootNode;
|
||||||
|
tinyxml2::XMLDocument* doc;
|
||||||
|
tinyxml2::XMLElement* node;
|
||||||
|
node = getXMLNodeForKey(pKey, &rootNode, &doc);
|
||||||
|
// find the node
|
||||||
|
if (node)
|
||||||
|
{
|
||||||
|
value = (const char*)(node->FirstChild()->Value());
|
||||||
|
}
|
||||||
|
|
||||||
if (value)
|
double ret = defaultValue;
|
||||||
{
|
|
||||||
ret = atof(value);
|
|
||||||
xmlFree((void*)value);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
if (value)
|
||||||
|
{
|
||||||
|
ret = atof(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (doc) delete doc;
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string CCUserDefault::getStringForKey(const char* pKey)
|
std::string CCUserDefault::getStringForKey(const char* pKey)
|
||||||
|
@ -238,16 +268,27 @@ std::string CCUserDefault::getStringForKey(const char* pKey)
|
||||||
|
|
||||||
string CCUserDefault::getStringForKey(const char* pKey, const std::string & defaultValue)
|
string CCUserDefault::getStringForKey(const char* pKey, const std::string & defaultValue)
|
||||||
{
|
{
|
||||||
const char* value = getValueForKey(pKey);
|
const char* value = NULL;
|
||||||
string ret = defaultValue;
|
tinyxml2::XMLElement* rootNode;
|
||||||
|
tinyxml2::XMLDocument* doc;
|
||||||
|
tinyxml2::XMLElement* node;
|
||||||
|
node = getXMLNodeForKey(pKey, &rootNode, &doc);
|
||||||
|
// find the node
|
||||||
|
if (node)
|
||||||
|
{
|
||||||
|
value = (const char*)(node->FirstChild()->Value());
|
||||||
|
}
|
||||||
|
|
||||||
if (value)
|
string ret = defaultValue;
|
||||||
{
|
|
||||||
ret = string(value);
|
|
||||||
xmlFree((void*)value);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
if (value)
|
||||||
|
{
|
||||||
|
ret = string(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (doc) delete doc;
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CCUserDefault::setBoolForKey(const char* pKey, bool value)
|
void CCUserDefault::setBoolForKey(const char* pKey, bool value)
|
||||||
|
@ -334,15 +375,15 @@ CCUserDefault* CCUserDefault::sharedUserDefault()
|
||||||
bool CCUserDefault::isXMLFileExist()
|
bool CCUserDefault::isXMLFileExist()
|
||||||
{
|
{
|
||||||
FILE *fp = fopen(m_sFilePath.c_str(), "r");
|
FILE *fp = fopen(m_sFilePath.c_str(), "r");
|
||||||
bool bRet = false;
|
bool bRet = false;
|
||||||
|
|
||||||
if (fp)
|
if (fp)
|
||||||
{
|
{
|
||||||
bRet = true;
|
bRet = true;
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
}
|
}
|
||||||
|
|
||||||
return bRet;
|
return bRet;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CCUserDefault::initXMLFilePath()
|
void CCUserDefault::initXMLFilePath()
|
||||||
|
@ -357,43 +398,32 @@ void CCUserDefault::initXMLFilePath()
|
||||||
// create new xml file
|
// create new xml file
|
||||||
bool CCUserDefault::createXMLFile()
|
bool CCUserDefault::createXMLFile()
|
||||||
{
|
{
|
||||||
bool bRet = false;
|
bool bRet = false;
|
||||||
xmlDocPtr doc = NULL;
|
tinyxml2::XMLDocument *pDoc = new tinyxml2::XMLDocument();
|
||||||
|
if (NULL==pDoc)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
tinyxml2::XMLDeclaration *pDeclaration = pDoc->NewDeclaration("1.0");
|
||||||
|
if (NULL==pDeclaration)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
pDoc->LinkEndChild(pDeclaration);
|
||||||
|
tinyxml2::XMLElement *pRootEle = pDoc->NewElement(USERDEFAULT_ROOT_NAME);
|
||||||
|
if (NULL==pRootEle)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
pDoc->LinkEndChild(pRootEle);
|
||||||
|
bRet = pDoc->SaveFile(m_sFilePath.c_str());
|
||||||
|
|
||||||
do
|
if(pDoc)
|
||||||
{
|
{
|
||||||
// new doc
|
delete pDoc;
|
||||||
doc = xmlNewDoc(BAD_CAST"1.0");
|
}
|
||||||
if (doc == NULL)
|
|
||||||
{
|
|
||||||
CCLOG("can not create xml doc");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// new root node
|
return bRet;
|
||||||
xmlNodePtr rootNode = xmlNewNode(NULL, BAD_CAST USERDEFAULT_ROOT_NAME);
|
|
||||||
if (rootNode == NULL)
|
|
||||||
{
|
|
||||||
CCLOG("can not create root node");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// set root node
|
|
||||||
xmlDocSetRootElement(doc, rootNode);
|
|
||||||
|
|
||||||
// save xml file
|
|
||||||
xmlSaveFile(m_sFilePath.c_str(), doc);
|
|
||||||
|
|
||||||
bRet = true;
|
|
||||||
} while (0);
|
|
||||||
|
|
||||||
// if doc is not null, free it
|
|
||||||
if (doc)
|
|
||||||
{
|
|
||||||
xmlFreeDoc(doc);
|
|
||||||
}
|
|
||||||
|
|
||||||
return bRet;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const string& CCUserDefault::getXMLFilePath()
|
const string& CCUserDefault::getXMLFilePath()
|
||||||
|
@ -403,11 +433,6 @@ const string& CCUserDefault::getXMLFilePath()
|
||||||
|
|
||||||
void CCUserDefault::flush()
|
void CCUserDefault::flush()
|
||||||
{
|
{
|
||||||
// save to file
|
|
||||||
if (g_sharedDoc)
|
|
||||||
{
|
|
||||||
xmlSaveFile(CCUserDefault::sharedUserDefault()->getXMLFilePath().c_str(), g_sharedDoc);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_CC_END
|
NS_CC_END
|
||||||
|
|
Loading…
Reference in New Issue