127 lines
4.0 KiB
C++
127 lines
4.0 KiB
C++
/** @file
|
|
* @author Edouard DUPIN
|
|
* @copyright 2011, Edouard DUPIN, all right reserved
|
|
* @license MPL v2.0 (see license file)
|
|
*/
|
|
|
|
#include <exml/internal/Attribute.hpp>
|
|
#include <exml/debug.hpp>
|
|
#include <exml/internal/Document.hpp>
|
|
|
|
ememory::SharedPtr<exml::internal::Attribute> exml::internal::Attribute::create(const std::string& _name, const std::string& _value) {
|
|
return ememory::SharedPtr<exml::internal::Attribute>(new exml::internal::Attribute(_name, _value));
|
|
}
|
|
|
|
exml::internal::Attribute::Attribute(const std::string& _name, const std::string& _value) :
|
|
exml::internal::Node(_value),
|
|
m_name(_name) {
|
|
|
|
}
|
|
|
|
bool exml::internal::Attribute::iParse(const std::string& _data, int32_t& _pos, bool _caseSensitive, exml::FilePos& _filePos, exml::internal::Document& _doc) {
|
|
EXML_VERBOSE("start parse : 'attribute'");
|
|
m_pos = _filePos;
|
|
// search end of the comment :
|
|
size_t lastElementName = _pos;
|
|
for (size_t iii=_pos; iii<_data.size(); iii++) {
|
|
_filePos.check(_data[iii]);
|
|
#ifdef ENABLE_DISPLAY_PARSED_ELEMENT
|
|
drawElementParsed(_data[iii], _filePos);
|
|
#endif
|
|
if (checkAvaillable(_data[iii], false) == true) {
|
|
lastElementName = iii;
|
|
} else {
|
|
break;
|
|
}
|
|
}
|
|
m_name = std::string(_data, _pos, lastElementName+1-(_pos));
|
|
if (_caseSensitive == true) {
|
|
m_name = etk::tolower(m_name);
|
|
}
|
|
// count white space :
|
|
exml::FilePos tmpPos;
|
|
int32_t white = countWhiteChar(_data, lastElementName+1, tmpPos);
|
|
_filePos += tmpPos;
|
|
if (lastElementName+white+1 >= _data.size()) {
|
|
CREATE_ERROR(_doc, _data, lastElementName+white+1, _filePos, " parse an xml end with an attribute parsing...");
|
|
return false;
|
|
}
|
|
if (_data[lastElementName+white+1] != '=') {
|
|
CREATE_ERROR(_doc, _data, lastElementName+white+1, _filePos, " error attribute parsing == > missing '=' ...");
|
|
return false;
|
|
}
|
|
white += countWhiteChar(_data, lastElementName+white+2, tmpPos);
|
|
_filePos += tmpPos;
|
|
|
|
if (lastElementName+white+2>=_data.size()) {
|
|
CREATE_ERROR(_doc, _data, lastElementName+white+2, _filePos, " parse an xml end with an attribute parsing...");
|
|
return false;
|
|
}
|
|
bool simpleQuoteCase = false;
|
|
if (_data[lastElementName+white+2] == '\'') { // '
|
|
simpleQuoteCase = true;
|
|
}
|
|
if ( _data[lastElementName+white+2] != '"'
|
|
&& _data[lastElementName+white+2] != '\'') { // '
|
|
// parse with no element " == > direct value separate with space ...
|
|
++_filePos;
|
|
size_t lastAttributePos = lastElementName+white+2;
|
|
for (size_t iii=lastElementName+white+2; iii<_data.size(); iii++) {
|
|
#ifdef ENABLE_DISPLAY_PARSED_ELEMENT
|
|
drawElementParsed(_data[iii], _filePos);
|
|
#endif
|
|
if (_filePos.check(_data[iii]) == true) {
|
|
CREATE_ERROR(_doc, _data, iii, _filePos, "unexpected '\\n' in an attribute parsing");
|
|
return false;
|
|
}
|
|
if( _data[iii] != ' '
|
|
&& _data[iii] != '/'
|
|
&& _data[iii] != '?'
|
|
&& _data[iii] != '>') {
|
|
lastAttributePos = iii+1;
|
|
} else {
|
|
break;
|
|
}
|
|
}
|
|
m_value = std::string(_data, lastElementName+white+2, lastAttributePos-(lastElementName+white+2));
|
|
|
|
EXML_PARSE_ATTRIBUTE(m_pos << " attribute : " << m_name << "=\"" << m_value << "\"");
|
|
|
|
_pos = lastAttributePos-1;
|
|
return true;
|
|
}
|
|
size_t lastAttributePos = lastElementName+white+3;
|
|
for (size_t iii=lastElementName+white+3; iii<_data.size(); iii++) {
|
|
#ifdef ENABLE_DISPLAY_PARSED_ELEMENT
|
|
drawElementParsed(_data[iii], _filePos);
|
|
#endif
|
|
_filePos.check(_data[iii]);
|
|
if ( (_data[iii] != '"' && simpleQuoteCase == false)
|
|
|| (_data[iii] != '\'' && simpleQuoteCase == true) ) { // '
|
|
lastAttributePos = iii+1;
|
|
} else {
|
|
break;
|
|
}
|
|
}
|
|
m_value = std::string(_data, lastElementName+white+3, lastAttributePos-(lastElementName+white+3));
|
|
|
|
EXML_PARSE_ATTRIBUTE(m_pos << " attribute : " << m_name << "=\"" << m_value << "\"");
|
|
|
|
_pos = lastAttributePos;
|
|
return true;
|
|
}
|
|
|
|
bool exml::internal::Attribute::iGenerate(std::string& _data, int32_t _indent) const {
|
|
_data += " ";
|
|
_data += m_name;
|
|
_data += "=\"";
|
|
_data += m_value;
|
|
_data += "\"";
|
|
return true;
|
|
}
|
|
|
|
void exml::internal::Attribute::clear() {
|
|
m_name = "";
|
|
}
|
|
|