added ccuserdefault tinyxml2 ver

This commit is contained in:
martell 2013-01-26 02:41:27 +00:00
parent 684b46dd74
commit 05bece9d07
1 changed files with 179 additions and 154 deletions

View File

@ -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