본문 바로가기
English

How to use pugixml in android cocos2d develop enviroment (pugixml singleton / pugixml local path)

by 해피류 2016. 10. 5.



Pugi xml usablity



In previous posting we've checked how to download and setup pugixml enviroment.


Okay, We are ready to use pugixml.  

To use a pugixml I usually create singleton class which managing all input/output of XML stream. here my case is just reference. There will be bundle of different way to use pugixml with more efficiency.



Here is a basic code to use pugixml.


//----------------------------------------------------------------- Pugixml API

#include "pugixml.hpp"


//------------------------------------------------------------------------ Json

#include "json\document.h"

#include "json\writer.h"

#include "json\reader.h"

#include "json\prettywriter.h"

#include "json\stringbuffer.h"


//-----------------------------------------------------------Cocos2d Name space

USING_NS_CC;

using namespace rapidjson;



include header file as like upper box

then implement code like below.

(this code is load local xml file and get data)


void MainScene::getPugixmlSample()

{

pugi::xml_document _xmlDoc;

pugi::xml_node _xmlNode;


std::string path = CCFileUtils::sharedFileUtils()->getWritablePath();

path.append("data.xml");


if (!FileUtils::sharedFileUtils()->isFileExist(path))

{

auto data = FileUtils::getInstance()->getDataFromFile("data/data.xml");

std::string dbPath = FileUtils::getInstance()->getWritablePath() + "data.xml";


FILE* dest = fopen(dbPath.c_str(), "wb");

fwrite(data.getBytes(), 1, data.getSize(), dest);

fclose(dest);

}


unsigned char* pBuffer = NULL;

ssize_t bufferSize = 0;

pBuffer = CCFileUtils::sharedFileUtils()->getFileData(path.c_str(), "r", &bufferSize);

if (_xmlDoc.load_buffer(pBuffer, bufferSize))

_xmlNode = _xmlDoc.child("root");


  // read data from xml file

pugi::xml_node stage = _xmlNode.child("stage");

        int world = stage.attribute("world").as_int();

int slot = stage.attribute("slot").as_int();

}



oh. I forget to show local xml file. XML file structure is like this.



<?xml version="1.0" encoding="UTF-8" standalone="yes"?>

<root>

<stage world="0" slot="0"/>

</root>




Here is attached singleton class what i used for development. Once you have this kind of singleton class, will be reduce develop time in another project. 


here code is header file named as "XmlMngt.h"


#ifndef __XmlMngt_H__

#define __XmlMngt_H__


//--------------------------------------------------------------Cocos2d Include

#include "cocos2d.h"


//----------------------------------------------------------------- Pugixml API

#include "pugixml.hpp"


//------------------------------------------------------------------------ Json

#include "json\document.h"

#include "json\writer.h"

#include "json\reader.h"

#include "json\prettywriter.h"

#include "json\stringbuffer.h"


//-----------------------------------------------------------Cocos2d Name space

USING_NS_CC;

using namespace rapidjson;


//-----------------------------------------------------------------------------

class XmlMngt

{

public:

XmlMngt();

~XmlMngt();


// Singleton object

static XmlMngt& getInstance();

static void releaseInstance();

static XmlMngt* m_pInstance;


void loadXml();


int getHighScore();

  void setHighScore(const int &iScore);


void saveXml();


private:

pugi::xml_document _xmlDoc;

pugi::xml_node _xmlNode;

};


#endif




here code is cpp file named as "XmlMngt.cpp"


#pragma execution_character_set("utf-8")



#include "XmlMngt.h"


XmlMngt *XmlMngt::m_pInstance = nullptr;


XmlMngt::XmlMngt()

{

loadXml();

}


XmlMngt::~XmlMngt() {}


XmlMngt& XmlMngt::getInstance()

{

if (m_pInstance == nullptr)

m_pInstance = new XmlMngt();


return *m_pInstance;

}


void XmlMngt::releaseInstance()

{

if (m_pInstance != nullptr)

delete m_pInstance;

}



void XmlMngt::loadXml()

{

std::string path = CCFileUtils::sharedFileUtils()->getWritablePath();

path.append("data.xml");


if (!FileUtils::sharedFileUtils()->isFileExist(path))

{

auto data = FileUtils::getInstance()->getDataFromFile("data/data.xml");

std::string dbPath = FileUtils::getInstance()->getWritablePath() + "data.xml";


FILE* dest = fopen(dbPath.c_str(), "wb");

fwrite(data.getBytes(), 1, data.getSize(), dest);

fclose(dest);

}


unsigned char* pBuffer = NULL;

ssize_t bufferSize = 0;

pBuffer = CCFileUtils::sharedFileUtils()->getFileData(path.c_str(), "r", &bufferSize);

if (_xmlDoc.load_buffer(pBuffer, bufferSize))

_xmlNode = _xmlDoc.child("root");

}


void XmlMngt::saveXml()

{

std::string configPath = CCFileUtils::sharedFileUtils()->getWritablePath();

configPath.append("data.xml");

_xmlDoc.save_file(configPath.c_str());

}


int XmlMngt::getHighScore(const int &iScore)

{

pugi::xml_node highscore = _xmlNode.child("highscore");

_gHighScore = highscore.attribute("score").as_llong();

if (iScore > _gHighScore)

{

_gHighScore = iScore;

highscore.attribute("score").set_value(_gHighScore);

saveXml();

}

}


void XmlMngt::setHighScore(const int &iScore)

{

pugi::xml_node highscore = _xmlNode.child("highscore");

_gHighScore = highscore.attribute("score").as_int();

if (iScore > _gHighScore)

{

_gHighScore = iScore;

highscore.attribute("score").set_value(_gHighScore);

saveXml();

}

}



last point is that, where wil be copied this local xml file.

Especilly in Cocos2d enviroment(in Windows) , xml file copied under "c:/user/AppData/Local/[Your Project Name]


By default, AppData folder is hidden. you need to check show option first.