void SimpleXML::Tag::appendAttribString(string& tmp) { for(auto& i: attribs) { tmp.append(i.first); tmp.append("=\"", 2); if(needsEscape(i.second, true)) { string tmp2(i.second); escape(tmp2, true); tmp.append(tmp2); } else { tmp.append(i.second); } tmp.append("\" ", 2); } tmp.erase(tmp.size()-1); }
void SimpleXML::Tag::appendAttribString(string& tmp) { for(StringPairIter i = attribs.begin(); i!= attribs.end(); ++i) { tmp.append(i->first); tmp.append("=\"", 2); if(needsEscape(i->second, true)) { string tmp2(i->second); escape(tmp2, true); tmp.append(tmp2); } else { tmp.append(i->second); } tmp.append("\" ", 2); } tmp.erase(tmp.size()-1); }
/** * The same as the version above, but writes to a file instead...yes, this could be made * with streams and only one code set but streams are slow...the file f should be a buffered * file, otherwise things will be very slow (I assume write is not expensive and call it a lot */ void SimpleXML::Tag::toXML(int indent, OutputStream* f) { if(children.empty() && data.empty()) { string tmp; tmp.reserve(indent + name.length() + 30); tmp.append(indent, '\t'); tmp.append(1, '<'); tmp.append(name); tmp.append(1, ' '); appendAttribString(tmp); tmp.append("/>\r\n", 4); f->write(tmp); } else { string tmp; tmp.append(indent, '\t'); tmp.append(1, '<'); tmp.append(name); tmp.append(1, ' '); appendAttribString(tmp); if(children.empty()) { tmp.append(1, '>'); if(needsEscape(data, false)) { string tmp2(data); escape(tmp2, false); tmp.append(tmp2); } else { tmp.append(data); } } else { tmp.append(">\r\n", 3); f->write(tmp); tmp.clear(); for(Iter i = children.begin(); i!=children.end(); ++i) { (*i)->toXML(indent + 1, f); } tmp.append(indent, '\t'); } tmp.append("</", 2); tmp.append(name); tmp.append(">\r\n", 3); f->write(tmp); } }
/** * The same as the version above, but writes to a file instead...yes, this could be made * with streams and only one code set but streams are slow...the file f should be a buffered * file, otherwise things will be very slow (I assume write is not expensive and call it a lot */ void SimpleXML::Tag::toXML(int indent, OutputStream* f, bool /*noIndent*/ /*false*/) { if(children.empty() && data.empty() && !forceEndTag) { string tmp; tmp.reserve(indent + name.length() + 30); tmp.append(indent, '\t'); tmp.append(1, '<'); tmp.append(name); tmp.append(1, ' '); appendAttribString(tmp); tmp.append("/>\r\n", 4); f->write(tmp); } else { string tmp; tmp.append(indent, '\t'); tmp.append(1, '<'); tmp.append(name); tmp.append(1, ' '); appendAttribString(tmp); if(children.empty()) { tmp.append(1, '>'); if(needsEscape(data, false)) { string tmp2(data); escape(tmp2, false); tmp.append(tmp2); } else { tmp.append(data); } } else { tmp.append(">\r\n", 3); f->write(tmp); tmp.clear(); for(auto& i: children) { i->toXML(indent + 1, f); } tmp.append(indent, '\t'); } tmp.append("</", 2); tmp.append(name); tmp.append(">\r\n", 3); f->write(tmp); } }
void copyAndEscape(char** dest, const char* src, size_t length) { char* destp = *dest; const char* end = src + length; if (length != 0 && !needsEscape(src, length)) { for (const char* ptr = src; ptr < end; ptr++) { *(destp++) = *ptr; } } else { *(destp++) = '"'; for (const char* ptr = src;; ptr++) { unsigned numBackslashes = 0; while (ptr < end && *ptr == '\\') { ptr++; numBackslashes++; } if (ptr == end) { appendN(&destp, '\\', 2 * numBackslashes); break; } else if (*ptr == '"') { appendN(&destp, '\\', 2 * numBackslashes + 1); *(destp++) = *ptr; } else { appendN(&destp, '\\', numBackslashes); *(destp++) = *ptr; } } *(destp++) = '"'; } *dest = destp; }