39 size_t pos = _string.find(
"&");
40 if (pos == std::string::npos)
return _string;
42 ret.reserve(_string.size());
44 while (pos != std::string::npos)
46 ret += _string.substr(old, pos - old);
48 size_t end = _string.find(
";", pos + 1);
49 if (end == std::string::npos)
56 std::string tag = _string.substr(pos, end - pos + 1);
57 if (tag ==
"&") ret +=
'&';
58 else if (tag ==
"<") ret +=
'<';
59 else if (tag ==
">") ret +=
'>';
60 else if (tag ==
"'") ret +=
'\'';
61 else if (tag ==
""") ret +=
'\"';
70 pos = _string.find(
"&", old);
72 ret += _string.substr(old, std::string::npos);
81 size_t pos = _string.find_first_of(
"&<>'\"");
82 if (pos == std::string::npos)
return _string;
84 ret.reserve(_string.size() * 2);
86 while (pos != std::string::npos)
88 ret += _string.substr(old, pos - old);
90 if (_string[pos] ==
'&') ret +=
"&";
91 else if (_string[pos] ==
'<') ret +=
"<";
92 else if (_string[pos] ==
'>') ret +=
">";
93 else if (_string[pos] ==
'\'') ret +=
"'";
94 else if (_string[pos] ==
'\"') ret +=
""";
97 pos = _string.find_first_of(
"&<>'\"", old);
99 ret += _string.substr(old, std::string::npos);
109 ElementEnumerator::ElementEnumerator(VectorElement::iterator _begin, VectorElement::iterator _end) :
118 if (m_current == m_end)
return false;
125 if (m_current == m_end)
return false;
133 if ((*m_current)->getName() == _name)
return true;
141 Element::Element(
const std::string &_name,
ElementPtr _parent,
ElementType _type,
const std::string& _content) :
151 for (VectorElement::iterator iter=mChilds.begin(); iter!=mChilds.end(); ++iter)
158 void Element::save(std::ostream& _stream,
size_t _level)
161 for (
size_t tab=0; tab<_level; ++tab) _stream <<
" ";
168 for (VectorAttributes::iterator iter = mAttributes.begin(); iter != mAttributes.end(); ++iter)
173 bool empty = mChilds.empty();
175 if (empty && mContent.empty())
178 else _stream <<
"/>\n";
183 if (!empty) _stream <<
"\n";
185 if (!mContent.empty())
189 for (
size_t tab=0; tab<=_level; ++tab) _stream <<
" ";
193 if (!empty) _stream <<
"\n";
196 for (
size_t child=0; child<mChilds.size(); child++)
198 mChilds[child]->save(_stream, _level + 1);
203 for (
size_t tab=0; tab<_level; ++tab)
206 _stream <<
"</" << mName <<
">\n";
214 mChilds.push_back(node);
220 for (VectorElement::iterator iter = mChilds.begin(); iter != mChilds.end(); ++iter)
delete *iter;
228 for (VectorAttributes::iterator iter=mAttributes.begin(); iter!=mAttributes.end(); ++iter)
230 if ( (*iter).first == _name)
232 _value = (*iter).second;
241 for (VectorAttributes::iterator iter=mAttributes.begin(); iter!=mAttributes.end(); ++iter)
243 if ( (*iter).first == _name)
return (*iter).second;
255 for (
size_t index=0; index<mAttributes.size(); ++index)
257 if (mAttributes[index].first == _key)
259 mAttributes.erase(mAttributes.begin() + index);
268 elem->mAttributes = mAttributes;
270 for (VectorElement::iterator iter=mChilds.begin(); iter!=mChilds.end(); ++iter)
273 child->mParent = elem;
274 elem->mChilds.push_back(child);
282 for (
size_t index=0; index<mAttributes.size(); ++index)
284 if (mAttributes[index].first == _key)
286 mAttributes[index].second = _value;
295 if (mContent.empty()) mContent = _content;
299 mContent += _content;
303 #if MYGUI_COMPILER == MYGUI_COMPILER_MSVC && !defined(STLPORT)
304 inline void open_stream(std::ofstream& _stream,
const std::wstring& _wide) { _stream.open(_wide.c_str()); }
305 inline void open_stream(std::ifstream& _stream,
const std::wstring& _wide) { _stream.open(_wide.c_str()); }
307 inline void open_stream(std::ofstream& _stream,
const std::wstring& _wide) { _stream.open(
UString(_wide).asUTF8_c_str()); }
308 inline void open_stream(std::ifstream& _stream,
const std::wstring& _wide) { _stream.open(UString(_wide).asUTF8_c_str()); }
331 std::ifstream stream;
332 stream.open(_filename.c_str());
334 if (!stream.is_open())
337 setLastFileError(_filename);
341 bool result =
open(stream);
350 std::ifstream stream;
353 if (!stream.is_open())
356 setLastFileError(_filename);
360 bool result =
open(stream);
370 bool result =
open(data);
379 std::ofstream stream;
380 stream.open(_filename.c_str());
382 if (!stream.is_open())
385 setLastFileError(_filename);
389 bool result =
save(stream);
393 setLastFileError(_filename);
403 std::ofstream stream;
406 if (!stream.is_open())
409 setLastFileError(_filename);
413 bool result =
save(stream);
417 setLastFileError(_filename);
436 while (!_stream->
eof())
440 if (read.empty())
continue;
441 if (read[read.size()-1] ==
'\r') read.erase(read.size()-1, 1);
442 if (read.empty())
continue;
446 if (read.empty())
continue;
450 if (!parseLine(line, currentNode))
475 _stream << (char)0xEFu;
476 _stream << (char)0xBBu;
477 _stream << (char)0xBFu;
479 mDeclaration->save(_stream, 0);
480 if (mRoot) mRoot->save(_stream, 0);
493 bool Document::parseTag(
ElementPtr &_currentNode, std::string _content)
499 if (_content.empty())
502 if (_currentNode) _currentNode = _currentNode->
createChild(
"");
505 _currentNode =
new Element(
"", 0);
507 if (!mRoot) mRoot = _currentNode;
512 char simbol = _content[0];
513 bool tag_info =
false;
515 if (simbol ==
'!')
return true;
521 _content.erase(0, 1);
528 if (_currentNode == 0)
538 start = _content.find_first_not_of(
" \t", 1);
539 if (start == _content.npos)
546 end = _content.find_last_not_of(
" \t");
547 _content = _content.substr(start, end - start+1);
550 if (_currentNode->
getName() != _content)
556 _currentNode = _currentNode->
getParent();
561 std::string cut = _content;
562 start = _content.find_first_of(
" \t/?", 1);
563 if (start != _content.npos)
565 cut = _content.substr(0, start);
566 _content = _content.substr(start);
573 if (_currentNode) _currentNode = _currentNode->
createChild(cut);
585 mDeclaration = _currentNode;
596 mRoot = _currentNode;
601 start = _content.find_last_not_of(
" \t");
602 if (start == _content.npos)
return true;
606 if ((_content[start] ==
'/') || (_content[start] ==
'?'))
610 _content[start] =
' ';
612 start = _content.find_last_not_of(
" \t");
613 if (start == _content.npos)
616 _currentNode = _currentNode->
getParent();
625 start = _content.find(
'=');
626 if (start == _content.npos)
632 end = _content.find_first_of(
"\"\'", start+1);
633 if (end == _content.npos)
638 end = _content.find_first_of(
"\"\'", end+1);
639 if (end == _content.npos)
645 std::string key = _content.substr(0, start);
646 std::string value = _content.substr(start+1, end-start);
649 if (! checkPair(key, value))
659 _content = _content.substr(end+1);
662 start = _content.find_first_not_of(
" \t");
663 if (start == _content.npos)
break;
672 _currentNode = _currentNode->
getParent();
679 bool Document::checkPair(std::string &_key, std::string &_value)
683 if (_key.empty())
return false;
684 size_t start = _key.find_first_of(
" \t\"\'&");
685 if (start != _key.npos)
return false;
689 if (_value.size() < 2)
return false;
690 if (((_value[0] !=
'"') || (_value[_value.length()-1] !=
'"')) &&
691 ((_value[0] !=
'\'') || (_value[_value.length()-1] !=
'\'')))
return false;
698 size_t Document::find(
const std::string& _text,
char _char,
size_t _start)
704 char buff[16] =
"\"_\0";
711 pos = _text.find_first_of(buff, pos);
714 if (pos == _text.npos)
break;
717 else if (_text[pos] ==
'"')
723 else if (kov) pos ++;
733 void Document::clearDeclaration()
742 void Document::clearRoot()
767 bool Document::parseLine(std::string& _line,
ElementPtr& _element)
773 size_t start = find(_line,
'<');
774 if (start == _line.npos)
break;
775 size_t end = _line.npos;
778 if ((start + 3 < _line.size()) && (_line[start + 1] ==
'!') && (_line[start + 2] ==
'-') && (_line[start + 3] ==
'-'))
780 end = _line.find(
"-->", start + 4);
781 if (end == _line.npos)
break;
786 end = find(_line,
'>', start+1);
787 if (end == _line.npos)
break;
790 size_t body = _line.find_first_not_of(
" \t<");
793 std::string body_str = _line.substr(0, start);
809 if (!parseTag(_element, _line.substr(start+1, end-start-1)))
814 _line = _line.substr(end+1);
821 const std::string& error = mLastError.
print();
822 if (error.empty())
return error;
823 return MyGUI::utility::toString(
"'", error,
"' , file='", mLastErrorFile,
"' , line=", mLine,
" , col=", mCol);