[DEV] base of the exml parser ==> start to work corectly ==> some good ideas

This commit is contained in:
Edouard Dupin 2013-06-20 21:43:49 +02:00
parent 4600e688b4
commit 31482734a7
14 changed files with 748 additions and 71 deletions

View File

@ -0,0 +1,98 @@
/**
* @author Edouard DUPIN
*
* @copyright 2011, Edouard DUPIN, all right reserved
*
* @license BSD v3 (see license file)
*/
#include <exml/EXmlAttribute.h>
#include <exml/debug.h>
bool exml::EXmlAttribute::Parse(const etk::UString& _data, int32_t& _pos, bool _caseSensitive, ivec2& _filePos)
{
EXML_DEBUG("start parse : 'attribute'");
// search end of the comment :
int32_t lastElementName = _pos;
for (int32_t iii=_pos; iii<_data.Size(); iii++) {
_filePos += ivec2(1,0);
DrawElementParsed(_data[iii], _filePos);
if (_data[iii] == '\n') {
_filePos.setValue(1, _filePos.y()+1);
EXML_ERROR("unexpected '\\n' in an attribute parsing");
return false;
}
if (true==CheckAvaillable(_data[iii], false) ) {
lastElementName = iii;
} else {
break;
}
}
m_name = _data.Extract(_pos, lastElementName+1);
if (lastElementName+1>=_data.Size()) {
EXML_ERROR(" parse an xml end with an attribute parsing...");
return false;
}
if (_data[lastElementName+1] != '=') {
EXML_ERROR(" error attribute parsing ==> missing '=' ...");
return false;
}
if (lastElementName+2>=_data.Size()) {
EXML_ERROR(" parse an xml end with an attribute parsing...");
return false;
}
if (_data[lastElementName+2] != '"') {
// parse with no element " ==> direct value separate with space ...
_filePos += ivec2(2,0);
int32_t lastAttributePos = lastElementName+3;
for (int32_t iii=lastElementName+2; iii<_data.Size(); iii++) {
_filePos += ivec2(1,0);
DrawElementParsed(_data[iii], _filePos);
if (_data[iii] == '\n') {
_filePos.setValue(1, _filePos.y()+1);
EXML_ERROR("unexpected '\\n' in an attribute parsing");
return false;
}
if (_data[iii]!=' ') {
lastAttributePos = iii;
} else {
break;
}
}
m_value = _data.Extract(lastElementName+2, lastAttributePos+1);
_pos = lastAttributePos+1;
return true;
}
_filePos += ivec2(2,0);
int32_t lastAttributePos = lastElementName+3;
for (int32_t iii=lastElementName+3; iii<_data.Size(); iii++) {
_filePos += ivec2(1,0);
DrawElementParsed(_data[iii], _filePos);
if (_data[iii] == '\n') {
_filePos.setValue(1, _filePos.y()+1);
EXML_ERROR("unexpected '\\n' in an attribute parsing");
return false;
}
if (_data[iii]!='"') {
lastAttributePos = iii;
} else {
break;
}
}
m_value = _data.Extract(lastElementName+3, lastAttributePos+1);
_pos = lastAttributePos+1;
return true;
}
bool exml::EXmlAttribute::Generate(etk::UString& _data, int32_t _indent)
{
_data += " ";
_data += m_name;
_data += "=\"";
_data += m_value;
_data += "\"";
return true;
}

View File

@ -20,6 +20,8 @@ namespace exml
EXmlAttribute(void) { }; EXmlAttribute(void) { };
virtual ~EXmlAttribute(void) { }; virtual ~EXmlAttribute(void) { };
virtual nodeType_te GetType(void) { return exml::typeAttribute; }; virtual nodeType_te GetType(void) { return exml::typeAttribute; };
virtual bool Parse(const etk::UString& _data, int32_t& _pos, bool _caseSensitive, ivec2& _filePos);
virtual bool Generate(etk::UString& _data, int32_t _indent);
}; };
}; };

View File

@ -0,0 +1,45 @@
/**
* @author Edouard DUPIN
*
* @copyright 2011, Edouard DUPIN, all right reserved
*
* @license BSD v3 (see license file)
*/
#include <exml/EXmlComment.h>
#include <exml/debug.h>
bool exml::EXmlComment::Parse(const etk::UString& _data, int32_t& _pos, bool _caseSensitive, ivec2& _filePos)
{
EXML_DEBUG("start parse : 'comment'");
// search end of the comment :
for (int32_t iii=_pos; iii+2<_data.Size(); iii++) {
_filePos += ivec2(1,0);
DrawElementParsed(_data[iii], _filePos);
if (_data[iii] == '\n') {
_filePos.setValue(1, _filePos.y()+1);
continue;
}
if( _data[iii] == '-'
&& _data[iii+1] == '-'
&& _data[iii+2] == '>') {
// find end of value:
m_value = _data.Extract(_pos, iii-1);
EXML_DEBUG(" find comment '" << m_value << "'");
_pos = iii+2;
return true;
}
}
_pos = _data.Size();
EXML_ERROR("comment got end of file without finding end node");
return false;
}
bool exml::EXmlComment::Generate(etk::UString& _data, int32_t _indent)
{
AddIndent(_data, _indent);
_data += "<!--";
_data += m_value;
_data += "-->\n";
return true;
}

View File

@ -14,12 +14,14 @@
namespace exml namespace exml
{ {
class EXmlElement : public EXmlNode class EXmlComment : public EXmlNode
{ {
public: public:
EXmlElement(void) { }; EXmlComment(void) { };
virtual ~EXmlElement(void) { }; virtual ~EXmlComment(void) { };
virtual nodeType_te GetType(void) { return typeAttribute; }; virtual nodeType_te GetType(void) { return typeAttribute; };
virtual bool Parse(const etk::UString& _data, int32_t& _pos, bool _caseSensitive, ivec2& _filePos);
virtual bool Generate(etk::UString& _data, int32_t _indent);
}; };
}; };

View File

@ -0,0 +1,55 @@
/**
* @author Edouard DUPIN
*
* @copyright 2011, Edouard DUPIN, all right reserved
*
* @license BSD v3 (see license file)
*/
#include <exml/EXmlDeclaration.h>
#include <exml/debug.h>
bool exml::EXmlDeclaration::Generate(etk::UString& _data, int32_t _indent)
{
AddIndent(_data, _indent);
_data += "<?";
_data += m_name;
if (m_value.Size()!=0) {
_data += " ";
_data += m_value;
}
_data += "?>\n";
return true;
}
bool exml::EXmlDeclaration::Parse(const etk::UString& _data, int32_t& _pos, bool _caseSensitive, ivec2& _filePos)
{
EXML_DEBUG("start parse : 'declaration'");
// search end of the comment :
for (int32_t iii=_pos; iii+1<_data.Size(); iii++) {
_filePos += ivec2(1,0);
DrawElementParsed(_data[iii], _filePos);
if (_data[iii] == '\n') {
_filePos.setValue(1, _filePos.y()+1);
continue;
}
if( _data[iii] == '>'
|| _data[iii] == '<') {
// an error occured :
EXML_ERROR(_filePos << " find '>' or '<' instead of '?>'");
return false;
}
if( _data[iii] == '?'
&& _data[iii+1] == '>') {
// find end of value:
m_value = _data.Extract(_pos, iii-1);
EXML_DEBUG(" find declaration '" << m_value << "'");
_pos = iii;
return true;
}
}
_pos = _data.Size();
EXML_ERROR("Text got end of file without finding end node");
return false;
}

View File

@ -20,6 +20,9 @@ namespace exml
EXmlDeclaration(void) { }; EXmlDeclaration(void) { };
virtual ~EXmlDeclaration(void) { }; virtual ~EXmlDeclaration(void) { };
virtual nodeType_te GetType(void) { return typeAttribute; }; virtual nodeType_te GetType(void) { return typeAttribute; };
virtual bool Generate(etk::UString& _data, int32_t _indent);
virtual bool Parse(const etk::UString& _data, int32_t& _pos, bool _caseSensitive, ivec2& _filePos);
}; };
}; };

View File

@ -7,6 +7,7 @@
*/ */
#include <exml/EXmlDocument.h> #include <exml/EXmlDocument.h>
#include <exml/debug.h>
exml::EXmlDocument::EXmlDocument(void) : exml::EXmlDocument::EXmlDocument(void) :
@ -16,13 +17,35 @@ exml::EXmlDocument::EXmlDocument(void) :
} }
bool exml::EXmlDocument::Generate(etk::UString& _data, int32_t _indent)
{
for (int32_t iii=0; iii<m_listSub.Size(); iii++) {
if (NULL!=m_listSub[iii]) {
m_listSub[iii]->Generate(_data, _indent);
}
}
return true;
}
bool exml::EXmlDocument::Parse(const etk::UString& _data, int32_t& _pos, bool _caseSensitive, ivec2& _filePos)
{
EXML_DEBUG("start parse : 'document'");
// in this case : no main node ...
SubParse(_data, _pos, _caseSensitive, _filePos, true);
return true;
}
bool exml::EXmlDocument::Parse(const etk::UString& _data) bool exml::EXmlDocument::Parse(const etk::UString& _data)
{ {
EXML_DEBUG("Start parsing document (type: string) size=" << _data.Size());
// came from char ==> force in utf8 ... // came from char ==> force in utf8 ...
m_charset = unicode::EDN_CHARSET_UTF8; m_charset = unicode::EDN_CHARSET_UTF8;
ivec2 filePos(1,1); ivec2 filePos(0,1);
int32_t ret = exml::EXmlElement::Parse(_data, 0, m_caseSensitive, filePos); int32_t parsePos = 0;
return false; return Parse(_data, parsePos, m_caseSensitive, filePos);
} }
bool exml::EXmlDocument::Generate(etk::UString& _data) bool exml::EXmlDocument::Generate(etk::UString& _data)
@ -40,4 +63,10 @@ bool exml::EXmlDocument::Store(const etk::UString& _file)
return false; return false;
} }
void exml::EXmlDocument::Display(void)
{
etk::UString tmpp;
Generate(tmpp, 0);
EXML_INFO("Generated XML : \n" << tmpp);
}

View File

@ -61,6 +61,9 @@ namespace exml
*/ */
bool Store(const etk::UString& _file); bool Store(const etk::UString& _file);
void Display(void);
bool Parse(const etk::UString& _data, int32_t& _pos, bool _caseSensitive, ivec2& _filePos);
bool Generate(etk::UString& _data, int32_t _indent);
}; };
}; };

View File

@ -8,6 +8,10 @@
#include <exml/EXmlElement.h> #include <exml/EXmlElement.h>
#include <exml/debug.h> #include <exml/debug.h>
#include <exml/EXmlText.h>
#include <exml/EXmlComment.h>
#include <exml/EXmlAttribute.h>
#include <exml/EXmlDeclaration.h>
exml::EXmlNode* exml::EXmlElement::GetSub(int32_t _id) exml::EXmlNode* exml::EXmlElement::GetSub(int32_t _id)
@ -55,77 +59,308 @@ void exml::EXmlElement::AppendAttribute(exml::EXmlAttribute* _node)
m_listAttribute.PushBack(_node); m_listAttribute.PushBack(_node);
} }
bool exml::EXmlElement::Parse(const etk::UString& _data, int32_t _pos, bool _caseSensitive, ivec2& _filePos, int32_t& findLen)
bool exml::EXmlElement::Generate(etk::UString& _data, int32_t _indent)
{ {
for (int32_t iii=_pos; iii<_data.Size(); iii++) { AddIndent(_data, _indent);
if (_data[iii] == '<') { _data += "<";
if (iii+1>=_data.Size()) { _data += m_name;
// TODO : an error occured ... for (int32_t iii=0; iii<m_listAttribute.Size(); iii++) {
return iii; if (NULL!=m_listAttribute[iii]) {
} m_listAttribute[iii]->Generate(_data, _indent);
// find the end of the balise : }
int32_t endPos = iii; }
for (int32_t jjj=iii+1; jjj<_data.Size(); jjj++) {
if(_data[jjj] == '>') {
endPos = jjj;
break;
}
}
if (endPos == iii) {
// TODO : an error occured ...
return iii;
}
int32_t sizeElement = endPos-iii;
if( sizeElement>2
&& _data[iii+1] == '?'
&& _data[endPos-1] == '?') {
// find declaration
// TODO : ... if (m_listSub.Size()>0) {
if( m_listSub.Size()==1
iii = endPos; && m_listSub[0] != NULL
continue; && m_listSub[0]->GetType() == exml::typeText
} && static_cast<exml::EXmlText*>(m_listSub[0])->CountLines()==1) {
if( sizeElement>5 _data += ">";
&& _data[iii+1] == '!' m_listSub[0]->Generate(_data,0);
&& _data[iii+2] == '-'
&& _data[iii+3] == '-'
&& _data[endPos-2] == '-'
&& _data[endPos-1] == '-') {
// find comment
// TODO : Change the end parsing ...
// TODO : ...
iii = endPos;
continue;
}
// find a normal node ...
// TODO : ...
for (int32_t jjj=iii+1; jjj<_data.Size(); jjj++) {
if(_data[jjj] == '>') {
// we find the end ...
iii = jjj;
break;
}
}
} else { } else {
_data += ">\n";
for (int32_t iii=0; iii<m_listSub.Size(); iii++) {
if (NULL!=m_listSub[iii]) {
m_listSub[iii]->Generate(_data, _indent+1);
}
}
AddIndent(_data, _indent);
}
_data += "</";
_data += m_name;
_data += ">\n";
} else {
_data += "/>\n";
}
return true;
}
bool exml::EXmlElement::SubParse(const etk::UString& _data, int32_t& _pos, bool _caseSensitive, ivec2& _filePos, bool _mainNode)
{
EXML_DEBUG(" start subParse ... " << _pos << " " << _filePos);
for (int32_t iii=_pos; iii<_data.Size(); iii++) {
_filePos += ivec2(1,0);
DrawElementParsed(_data[iii], _filePos);
if (_data[iii] == '<') {
int32_t white = CountWhiteChar(_data, iii+1);
if (iii+white+1>=_data.Size()) {
EXML_ERROR(_filePos << " ==> end file with '<' char ==> invalide XML");
_pos = iii+white;
return false;
}
// Detect type of the element:
if(_data[iii+white+1] == '>') {
EXML_ERROR(_filePos << " find '>' with no element in the element...");
_pos = iii+white+1;
return false;
}
if(_data[iii+white+1] == '?') {
// Find declaration balise
exml::EXmlDeclaration* declaration = new exml::EXmlDeclaration();
if (NULL==declaration) {
EXML_ERROR(_filePos << " Allocation error ...");
return false;
}
_pos = iii+white+2;
_filePos += ivec2(3+white,0);
if (false==declaration->Parse(_data, _pos, _caseSensitive, _filePos)) {
delete(declaration);
return false;
}
m_listSub.PushBack(declaration);
continue;
}
if(_data[iii+white+1] == '!') {
// Find special block element
if (iii+white+2>=_data.Size()) {
EXML_ERROR(_filePos << " ==> end file with '<!' chars ==> invalide XML");
return false;
}
if(_data[iii+white+2] == '-') {
if (iii+white+3>=_data.Size()) {
EXML_ERROR(_filePos << " ==> end file with '<!-' chars ==> invalide XML");
return false;
}
if(_data[iii+white+3] != '-') {
EXML_ERROR(_filePos << " ==> element parse with '<!-" << _data[iii+3] << "' chars ==> invalide XML");
return false;
}
// find comment:
exml::EXmlComment* comment = new exml::EXmlComment();
if (NULL==comment) {
EXML_ERROR(_filePos << " Allocation error ...");
return false;
}
_pos = iii+white+4;
_filePos += ivec2(3+white,0);
if (false==comment->Parse(_data, _pos, _caseSensitive, _filePos)) {
delete(comment);
return false;
}
iii = _pos;
m_listSub.PushBack(comment);
} else if (_data[iii+white+2] == '[') {
if (iii+white+8>=_data.Size()) {
EXML_ERROR(_filePos << " ==> end file with '<![' chars ==> invalide XML");
return false;
}
if( _data[iii+white+3] != 'C'
|| _data[iii+white+4] != 'D'
|| _data[iii+white+5] != 'A'
|| _data[iii+white+6] != 'T'
|| _data[iii+white+7] != 'A'
|| _data[iii+white+8] != '[') {
EXML_ERROR(_filePos << " ==> element parse with '<![" << _data[iii+white+3] << _data[iii+white+4] << _data[iii+white+5] << _data[iii+white+6] << _data[iii+white+7] << _data[iii+white+8] << "' chars ==> invalide XML");
return false;
}
// find text:
exml::EXmlTextCDATA* text = new exml::EXmlTextCDATA();
if (NULL==text) {
EXML_ERROR(_filePos << " Allocation error ...");
return false;
}
_pos = iii+9+white;
_filePos += ivec2(8+white,0);
if (false==text->Parse(_data, _pos, _caseSensitive, _filePos)) {
delete(text);
return false;
}
iii = _pos;
m_listSub.PushBack(text);
} else {
EXML_ERROR(_filePos << " ==> end file with '<!" << _data[iii+white+2] << "' chars ==> invalide XML");
return false;
}
continue;
}
if(_data[iii+white+1] == '/') {
//EXML_DEBUG("Generate node name : '" << _data[iii+1] << "'");
int32_t endPosName = iii+white+1;
// Generate element name ...
for (int32_t jjj=iii+white+2; jjj<_data.Size(); jjj++) {
if(true == CheckAvaillable(_data[jjj], false) ) {
// we find the end ...
endPosName = jjj;
} else {
break;
}
}
etk::UString tmpname = _data.Extract(iii+white+2, endPosName+1);
if( tmpname == m_name) {
// find end of node :
// find > element ...
for (int32_t jjj=endPosName+1; jjj<_data.Size(); jjj++) {
_filePos += ivec2(1,0);
DrawElementParsed(_data[jjj], _filePos);
if (_data[jjj] == '\n') {
_filePos.setValue(0, _filePos.y()+1);
continue;
}
if(_data[jjj] == '>') {
_pos = jjj;
return true;
}
}
} else {
EXML_ERROR(_filePos << " ==> end node error : '" << tmpname << "' != '" << m_name << "'");
return false;
}
}
if (_data[iii+white+1] == '>') {
// end of something ==> this is really bad
EXML_ERROR(_filePos << " ==> find '>' chars ==> invalide XML");
return false;
}
if( true == CheckAvaillable(_data[iii+white+1], true) ) {
//EXML_DEBUG("Generate node name : '" << _data[iii+1] << "'");
int32_t endPosName = iii+white+1;
// Generate element name ...
for (int32_t jjj=iii+white+2; jjj<_data.Size(); jjj++) {
if(true == CheckAvaillable(_data[jjj], false) ) {
// we find the end ...
endPosName = jjj;
} else {
break;
}
}
etk::UString tmpname = _data.Extract(iii+white+1, endPosName+1);
//EXML_INFO("find node named : '" << tmpname << "'");
// find text:
exml::EXmlElement* element = new exml::EXmlElement();
if (NULL==element) {
EXML_ERROR(_filePos << " Allocation error ...");
return false;
}
element->SetName(tmpname);
_pos = endPosName+1;
_filePos += ivec2(endPosName,0);
if (false==element->Parse(_data, _pos, _caseSensitive, _filePos)) {
delete(element);
return false;
}
iii = _pos;
m_listSub.PushBack(element);
continue;
}
} else {
if (_data[iii] == '>') {
EXML_ERROR(_filePos << " find elemement '>' ==> no reason to be here ...");
return false;
}
// might to be data text ... // might to be data text ...
if( _data[iii] == ' ' if (_data[iii] == '\n') {
&& _data[iii] == '\t' _filePos.setValue(1, _filePos.y()+1);
&& _data[iii] == '\n' }else if( _data[iii] == ' '
&& _data[iii] == '\r') { || _data[iii] == '\t'
|| _data[iii] == '\r') {
// empty spaces ==> nothing to do .... // empty spaces ==> nothing to do ....
} else { } else {
// find data ==> parse it... // find data ==> parse it...
exml::EXmlText* text = new exml::EXmlText();
if (NULL==text) {
EXML_ERROR(_filePos << " Allocation error ...");
return false;
}
_pos = iii;
_filePos += ivec2(1,0);
if (false==text->Parse(_data, _pos, _caseSensitive, _filePos)) {
delete(text);
return false;
}
iii = _pos;
m_listSub.PushBack(text);
} }
} }
} }
return _pos; return false;
}
bool exml::EXmlElement::Parse(const etk::UString& _data, int32_t& _pos, bool _caseSensitive, ivec2& _filePos)
{
EXML_DEBUG("start parse : 'element' named='" << m_name << "'");
// note : When start parsing the upper element must have set the value of the element and set the position after this one
// find a normal node ...
for (int32_t iii=_pos; iii<_data.Size(); iii++) {
_filePos += ivec2(1,0);
if (_data[iii] == '\n') {
_filePos.setValue(1, _filePos.y()+1);
}
EXML_DEBUG("parse : '" << _data[iii] << "'");
if(_data[iii] == '>') {
// we find the end ...
_pos = iii+1;
return exml::EXmlElement::SubParse(_data, _pos, _caseSensitive, _filePos, false);
}
if (_data[iii] == '/') {
// standalone node or error...
if (iii+1>=_data.Size()) {
EXML_ERROR(" find end of files ... ==> bad case");
return false;
}
if (_data[iii+1] == '>') {
_pos = iii+1;
return true;
}
// error
EXML_ERROR("find / without > char ...");
return false;
}
if (true == CheckAvaillable(_data[iii], true)) {
// we find an attibute ==> create a new and parse it :
exml::EXmlAttribute* attribute = new exml::EXmlAttribute();
if (NULL==attribute) {
EXML_ERROR(_filePos << " Allocation error ...");
return false;
}
_pos = iii;
if (false==attribute->Parse(_data, _pos, _caseSensitive, _filePos)) {
delete(attribute);
return false;
}
iii = _pos;
m_listAttribute.PushBack(attribute);
continue;
}
// TODO : Else ==> if not white ==> create an error ...
}
return false;
} }

View File

@ -21,20 +21,23 @@ namespace exml
EXmlElement(void) { }; EXmlElement(void) { };
virtual ~EXmlElement(void) { }; virtual ~EXmlElement(void) { };
virtual nodeType_te GetType(void) { return typeElement; }; virtual nodeType_te GetType(void) { return typeElement; };
private: protected:
etk::Vector<EXmlNode*> m_listSub; etk::Vector<exml::EXmlNode*> m_listSub;
public: public:
int32_t SizeSub(void) const { return m_listSub.Size(); }; int32_t SizeSub(void) const { return m_listSub.Size(); };
EXmlNode* GetSub(int32_t _id); EXmlNode* GetSub(int32_t _id);
void AppendSub(EXmlNode* _node); void AppendSub(EXmlNode* _node);
private: protected:
etk::Vector<EXmlAttribute*> m_listAttribute; etk::Vector<exml::EXmlAttribute*> m_listAttribute;
public: public:
int32_t SizeAttribute(void) const { return m_listSub.Size(); }; int32_t SizeAttribute(void) const { return m_listSub.Size(); };
EXmlAttribute* GetAttribute(int32_t _id); EXmlAttribute* GetAttribute(int32_t _id);
void AppendAttribute(EXmlAttribute* _node); void AppendAttribute(EXmlAttribute* _node);
public: public:
virtual bool Parse(const etk::UString& _data, int32_t _pos, bool _caseSensitive, ivec2& _filePos, int32_t& findLen); virtual bool Parse(const etk::UString& _data, int32_t& _pos, bool _caseSensitive, ivec2& _filePos);
virtual bool Generate(etk::UString& _data, int32_t _indent);
protected:
bool SubParse(const etk::UString& _data, int32_t& _pos, bool _caseSensitive, ivec2& _filePos, bool _mainNode=false);
}; };
}; };

View File

@ -0,0 +1,93 @@
/**
* @author Edouard DUPIN
*
* @copyright 2011, Edouard DUPIN, all right reserved
*
* @license BSD v3 (see license file)
*/
#include <exml/EXmlNode.h>
#include <exml/debug.h>
void exml::EXmlNode::AddIndent(etk::UString& _data, int32_t _indent)
{
for (int32_t iii=0; iii<_indent; iii++) {
_data+="\t";
}
}
void exml::EXmlNode::DrawElementParsed(const etk::UniChar& _val, const ivec2& _filePos)
{
if (_val=='\n') {
EXML_DEBUG(_filePos << " Parse '\\n'");
} else if (_val=='\t') {
EXML_DEBUG(_filePos << " Parse '\\t'");
} else {
EXML_DEBUG(_filePos << " Parse '" << _val << "'");
}
}
// !"#$%&'()*+,/;<=>?@[\]^`{|}~ ou une espace et ne peut pas commencer par -. ou un chiffre.
bool exml::EXmlNode::CheckAvaillable(const etk::UniChar& _val, bool _firstChar)
{
if( _val == '!'
|| _val == '"'
|| _val == '#'
|| _val == '$'
|| _val == '%'
|| _val == '&'
|| _val == '\'' // '
|| _val == '('
|| _val == ')'
|| _val == '*'
|| _val == '+'
|| _val == ','
|| _val == '/'
|| _val == ';'
|| _val == '<'
|| _val == '='
|| _val == '>'
|| _val == '?'
|| _val == '@'
|| _val == '['
|| _val == '\\'
|| _val == ']'
|| _val == '^'
|| _val == '`'
|| _val == '{'
|| _val == '|'
|| _val == '}'
|| _val == '~'
|| _val == ' '
|| _val == '\n'
|| _val == '\t'
|| _val == '\r') {
return false;
}
if (true == _firstChar) {
if( _val == '-'
|| _val == '.'
|| ( _val >= '0'
&& _val <= '9') ) {
return false;
}
}
return true;
}
int32_t exml::EXmlNode::CountWhiteChar(const etk::UString& _data, int32_t _pos)
{
int32_t white=0;
for (int32_t iii=_pos; iii<_data.Size(); iii++) {
if( _data[iii] == ' '
|| _data[iii] == '\t'
|| _data[iii] == '\n'
|| _data[iii] == '\r') {
white++;
} else {
break;
}
}
return white;
}

View File

@ -30,11 +30,14 @@ namespace exml
public: public:
EXmlNode(void) { }; EXmlNode(void) { };
virtual ~EXmlNode(void) { }; virtual ~EXmlNode(void) { };
protected:
void AddIndent(etk::UString& _data, int32_t _indent);
public: public:
/** /**
* Parse the sub nodes and current nodes ... * Parse the sub nodes and current nodes ...
*/ */
virtual bool Parse(const etk::UString& _data, int32_t _pos, bool _caseSensitive, ivec2& _filePos, int32_t& findLen) = 0; virtual bool Parse(const etk::UString& _data, int32_t& _pos, bool _caseSensitive, ivec2& _filePos) = 0;
virtual bool Generate(etk::UString& _data, int32_t _indent) { return true; };
protected: protected:
etk::UString m_name; etk::UString m_name;
public: public:
@ -47,6 +50,10 @@ namespace exml
virtual const etk::UString& GetValue(void) { return m_value; }; virtual const etk::UString& GetValue(void) { return m_value; };
public: public:
virtual nodeType_te GetType(void) { return typeNode; }; virtual nodeType_te GetType(void) { return typeNode; };
protected:
void DrawElementParsed(const etk::UniChar& _val, const ivec2& _firstChar);
bool CheckAvaillable(const etk::UniChar& _val, bool _firstChar);
int32_t CountWhiteChar(const etk::UString& _data, int32_t _pos);
}; };
}; };

View File

@ -0,0 +1,91 @@
/**
* @author Edouard DUPIN
*
* @copyright 2011, Edouard DUPIN, all right reserved
*
* @license BSD v3 (see license file)
*/
#include <exml/EXmlText.h>
#include <exml/debug.h>
bool exml::EXmlText::Generate(etk::UString& _data, int32_t _indent)
{
_data += m_value;
return true;
}
int32_t exml::EXmlText::CountLines(void)
{
int32_t count = 1;
for (int32_t iii=0; iii<m_value.Size(); iii++) {
if(m_value[iii] == '\n') {
count++;
}
}
return count;
}
bool exml::EXmlText::Parse(const etk::UString& _data, int32_t& _pos, bool _caseSensitive, ivec2& _filePos)
{
EXML_DEBUG("start parse : 'text'");
// search end of the comment :
for (int32_t iii=_pos; iii<_data.Size(); iii++) {
_filePos += ivec2(1,0);
DrawElementParsed(_data[iii], _filePos);
if (_data[iii] == '\n') {
_filePos.setValue(0, _filePos.y()+1);
continue;
}
if( _data[iii] == '>'
|| _data[iii] == '<') {
// search whitespace :
int32_t newEnd=iii;
for( int32_t jjj=iii-1; jjj>_pos; jjj--) {
if( _data[jjj] == ' '
|| _data[jjj] == '\n'
|| _data[jjj] == '\r'
|| _data[jjj] == '\t') {
newEnd = jjj;
} else {
break;
}
}
// find end of value:
m_value = _data.Extract(_pos, newEnd);
EXML_DEBUG(" find text '" << m_value << "'");
_pos = iii-1;
return true;
}
}
_pos = _data.Size();
EXML_ERROR("Text got end of file without finding end node");
return false;
}
bool exml::EXmlTextCDATA::Parse(const etk::UString& _data, int32_t& _pos, bool _caseSensitive, ivec2& _filePos)
{
EXML_DEBUG("start parse : 'text::CDATA'");
// search end of the comment :
for (int32_t iii=_pos; iii+2<_data.Size(); iii++) {
_filePos += ivec2(1,0);
DrawElementParsed(_data[iii], _filePos);
if (_data[iii] == '\n') {
_filePos.setValue(1, _filePos.y()+1);
continue;
}
if( _data[iii] == ']'
&& _data[iii+1] == ']'
&& _data[iii+2] == '>') {
// find end of value:
m_value = _data.Extract(_pos, iii-1);
EXML_DEBUG(" find text CDATA '" << m_value << "'");
_pos = iii+2;
return true;
}
}
_pos = _data.Size();
EXML_ERROR("text CDATA got end of file without finding end node");
return false;
}

View File

@ -20,6 +20,17 @@ namespace exml
EXmlText(void) { }; EXmlText(void) { };
virtual ~EXmlText(void) { }; virtual ~EXmlText(void) { };
virtual nodeType_te GetType(void) { return typeText; }; virtual nodeType_te GetType(void) { return typeText; };
virtual bool Parse(const etk::UString& _data, int32_t& _pos, bool _caseSensitive, ivec2& _filePos);
virtual bool Generate(etk::UString& _data, int32_t _indent);
int32_t CountLines(void);
};
class EXmlTextCDATA : public EXmlText
{
public:
EXmlTextCDATA(void) { };
virtual ~EXmlTextCDATA(void) { };
virtual nodeType_te GetType(void) { return typeText; };
virtual bool Parse(const etk::UString& _data, int32_t& _pos, bool _caseSensitive, ivec2& _filePos);
}; };
}; };