23 size_t pos = _string.find(
"&");
24 if (pos == std::string::npos)
return _string;
26 ret.reserve(_string.size());
28 while (pos != std::string::npos)
30 ret += _string.substr(old, pos - old);
32 size_t end = _string.find(
";", pos + 1);
33 if (end == std::string::npos)
40 std::string tag = _string.substr(pos, end - pos + 1);
41 if (tag ==
"&") ret +=
'&';
42 else if (tag ==
"<") ret +=
'<';
43 else if (tag ==
">") ret +=
'>';
44 else if (tag ==
"'") ret +=
'\'';
45 else if (tag ==
""") ret +=
'\"';
54 pos = _string.find(
"&", old);
56 ret += _string.substr(old, std::string::npos);
65 size_t pos = _string.find_first_of(
"&<>'\"");
66 if (pos == std::string::npos)
return _string;
68 ret.reserve(_string.size() * 2);
70 while (pos != std::string::npos)
72 ret += _string.substr(old, pos - old);
74 if (_string[pos] ==
'&') ret +=
"&";
75 else if (_string[pos] ==
'<') ret +=
"<";
76 else if (_string[pos] ==
'>') ret +=
">";
77 else if (_string[pos] ==
'\'') ret +=
"'";
78 else if (_string[pos] ==
'\"') ret +=
""";
81 pos = _string.find_first_of(
"&<>'\"", old);
83 ret += _string.substr(old, std::string::npos);
93 ElementEnumerator::ElementEnumerator(VectorElement::iterator _begin, VectorElement::iterator _end) :
102 if (m_current == m_end)
110 if (m_current == m_end)
119 if ((*m_current)->getName() == _name)
127 assert(m_current != m_end);
133 assert(m_current != m_end);
140 Element::Element(
const std::string& _name,
ElementPtr _parent,
ElementType _type,
const std::string& _content) :
150 for (VectorElement::iterator iter = mChilds.begin(); iter != mChilds.end(); ++iter)
157 void Element::save(std::ostream& _stream,
size_t _level)
160 for (
size_t tab = 0; tab < _level; ++tab)
173 for (VectorAttributes::iterator iter = mAttributes.begin(); iter != mAttributes.end(); ++iter)
178 bool empty = mChilds.empty();
180 if (empty && mContent.empty())
195 if (!mContent.empty())
199 for (
size_t tab = 0; tab <= _level; ++tab) _stream <<
" ";
207 for (
size_t child = 0; child < mChilds.size(); child++)
209 mChilds[child]->save(_stream, _level + 1);
214 for (
size_t tab = 0; tab < _level; ++tab)
217 _stream <<
"</" << mName <<
">\n";
224 mChilds.push_back(node);
230 VectorElement::iterator item = std::find(mChilds.begin(), mChilds.end(), _child);
231 if (item != mChilds.end())
240 for (VectorElement::iterator iter = mChilds.begin(); iter != mChilds.end(); ++iter)
delete *iter;
248 for (VectorAttributes::iterator iter = mAttributes.begin(); iter != mAttributes.end(); ++iter)
250 if ( (*iter).first == _name)
252 _value = (*iter).second;
261 for (VectorAttributes::iterator iter = mAttributes.begin(); iter != mAttributes.end(); ++iter)
263 if ((*iter).first == _name)
264 return (*iter).second;
276 for (
size_t index = 0; index < mAttributes.size(); ++index)
278 if (mAttributes[index].first == _key)
280 mAttributes.erase(mAttributes.begin() + index);
289 elem->mAttributes = mAttributes;
291 for (VectorElement::iterator iter = mChilds.begin(); iter != mChilds.end(); ++iter)
294 child->mParent = elem;
295 elem->mChilds.push_back(child);
303 for (
size_t index = 0; index < mAttributes.size(); ++index)
305 if (mAttributes[index].first == _key)
307 mAttributes[index].second = _value;
316 if (mContent.empty())
323 mContent += _content;
362#if MYGUI_COMPILER == MYGUI_COMPILER_MSVC && !defined(STLPORT)
363 inline void open_stream(std::ofstream& _stream,
const std::wstring& _wide)
365 _stream.open(_wide.c_str());
367 inline void open_stream(std::ifstream& _stream,
const std::wstring& _wide)
369 _stream.open(_wide.c_str());
372 inline void open_stream(std::ofstream& _stream,
const std::wstring& _wide)
374 _stream.open(
UString(_wide).asUTF8_c_str());
376 inline void open_stream(std::ifstream& _stream,
const std::wstring& _wide)
378 _stream.open(UString(_wide).asUTF8_c_str());
387 mDeclaration(nullptr),
402 std::ifstream stream;
403 stream.open(_filename.c_str());
405 if (!stream.is_open())
408 setLastFileError(_filename);
412 bool result =
open(stream);
421 std::ifstream stream;
424 if (!stream.is_open())
427 setLastFileError(_filename);
431 bool result =
open(stream);
441 bool result =
open(data);
450 std::ofstream stream;
451 stream.open(_filename.c_str());
453 if (!stream.is_open())
456 setLastFileError(_filename);
460 bool result =
save(stream);
464 setLastFileError(_filename);
474 std::ofstream stream;
477 if (!stream.is_open())
480 setLastFileError(_filename);
484 bool result =
save(stream);
488 setLastFileError(_filename);
507 while (!_stream->
eof())
513 if (read[read.size() - 1] ==
'\r')
514 read.erase(read.size() - 1, 1);
524 if (!parseLine(line, currentNode))
549 _stream << (char)0xEFu;
550 _stream << (char)0xBBu;
551 _stream << (char)0xBFu;
553 mDeclaration->save(_stream, 0);
555 mRoot->save(_stream, 0);
568 bool Document::parseTag(
ElementPtr& _currentNode, std::string _content)
573 if (_content.empty())
582 _currentNode =
new Element(
"",
nullptr);
585 mRoot = _currentNode;
590 char symbol = _content[0];
591 bool tagDeclaration =
false;
596 if (_currentNode !=
nullptr)
603 else if (symbol ==
'?')
605 tagDeclaration =
true;
606 _content.erase(0, 1);
614 if (_currentNode ==
nullptr)
620 start = _content.find_first_not_of(
" \t", 1);
621 if (start == _content.npos)
628 end = _content.find_last_not_of(
" \t");
629 _content = _content.substr(start, end - start + 1);
632 if (_currentNode->
getName() != _content)
638 _currentNode = _currentNode->
getParent();
643 std::string cut = _content;
644 start = _content.find_first_of(
" \t/?", 1);
645 if (start != _content.npos)
647 cut = _content.substr(0, start);
648 _content = _content.substr(start);
670 mDeclaration = _currentNode;
681 mRoot = _currentNode;
686 start = _content.find_last_not_of(
" \t");
687 if (start == _content.npos)
692 if ((_content[start] ==
'/') || (_content[start] ==
'?'))
696 _content[start] =
' ';
698 start = _content.find_last_not_of(
" \t");
699 if (start == _content.npos)
702 _currentNode = _currentNode->
getParent();
711 start = _content.find(
'=');
712 if (start == _content.npos)
718 end = _content.find_first_of(
"\"\'", start + 1);
719 if (end == _content.npos)
724 end = _content.find_first_of(
"\"\'", end + 1);
725 if (end == _content.npos)
731 std::string key = _content.substr(0, start);
732 std::string value = _content.substr(start + 1, end - start);
735 if (! checkPair(key, value))
745 _content = _content.substr(end + 1);
748 start = _content.find_first_not_of(
" \t");
749 if (start == _content.npos)
759 _currentNode = _currentNode->
getParent();
766 bool Document::checkPair(std::string& _key, std::string& _value)
772 size_t start = _key.find_first_of(
" \t\"\'&");
773 if (start != _key.npos)
778 if (_value.size() < 2)
780 if (((_value[0] !=
'"') || (_value[_value.length() - 1] !=
'"')) &&
781 ((_value[0] !=
'\'') || (_value[_value.length() - 1] !=
'\'')))
789 size_t Document::find(
const std::string& _text,
char _char,
size_t _start)
795 char buff[16] =
"\"_\0";
802 pos = _text.find_first_of(buff, pos);
805 if (pos == _text.npos)
810 else if (_text[pos] ==
'"')
830 void Document::clearDeclaration()
835 mDeclaration =
nullptr;
839 void Document::clearRoot()
864 bool Document::parseLine(std::string& _line,
ElementPtr& _element)
870 size_t start = find(_line,
'<');
871 if (start == _line.npos)
876 if ((start + 3 < _line.size()) && (_line[start + 1] ==
'!') && (_line[start + 2] ==
'-') && (_line[start + 3] ==
'-'))
878 end = _line.find(
"-->", start + 4);
879 if (end == _line.npos)
885 end = find(_line,
'>', start + 1);
886 if (end == _line.npos)
890 size_t body = _line.find_first_not_of(
" \t<");
893 std::string body_str = _line.substr(0, start);
897 if (_element !=
nullptr)
909 if (!parseTag(_element, _line.substr(start + 1, end - start - 1)))
914 _line = _line.substr(end + 1);
921 const std::string& error = mLastError.
print();
924 return MyGUI::utility::toString(
"'", error,
"' , file='", mLastErrorFile,
"' , line=", mLine,
" , col=", mCol);
947 void Document::setLastFileError(
const std::string& _filename)
949 mLastErrorFile = _filename;
952 void Document::setLastFileError(
const std::wstring& _filename)
virtual void readline(std::string &_source, Char _delim='\n')=0
A UTF-16 string with implicit conversion to/from std::string and std::wstring.
const std::wstring & asWStr() const
returns the current string in the native form of std::wstring
const std::string & asUTF8() const
returns the current string in UTF-8 form within a std::string
bool save(const std::string &_filename)
ElementPtr createRoot(const std::string &_name)
std::string getLastError() const
ElementPtr getRoot() const
bool open(const std::string &_filename)
ElementPtr createDeclaration(const std::string &_version="1.0", const std::string &_encoding="UTF-8")
ElementPtr operator->() const
void setAttribute(const std::string &_key, const std::string &_value)
const std::string & getContent() const
void addContent(const T &_content)
ElementPtr createChild(const std::string &_name, const std::string &_content="", ElementType _type=ElementType::Normal)
ElementEnumerator getElementEnumerator()
void removeAttribute(const std::string &_key)
ElementType getType() const
void removeChild(ElementPtr _child)
ElementPtr getParent() const
const std::string & getName() const
void addAttribute(const std::string &_key, const T &_value)
bool findAttribute(const std::string &_name, std::string &_value)
const VectorAttributes & getAttributes() const
void setContent(const T &_content)
std::string toString(T p)
void trim(std::string &_str, bool _left=true, bool _right=true)
static std::string convert_to_xml(const std::string &_string)
static std::string convert_from_xml(const std::string &_string, bool &_ok)
std::pair< std::string, std::string > PairAttribute
std::vector< PairAttribute > VectorAttributes
void open_stream(std::ofstream &_stream, const std::wstring &_wide)
@ MoreThanOneXMLDeclaration
@ InconsistentOpenCloseElements
std::string print() const