21 for (
const auto* child = firstChild; child; child = child->nextSibling) {
22 if (child->name == childName) {
37 for (
const auto* current = hint; current; current = current->nextSibling) {
38 if (current->name == childName) {
39 hint = current->nextSibling;
43 for (
const auto* current = firstChild; current != hint; current = current->nextSibling) {
44 if (current->name == childName) {
45 hint = current->nextSibling;
55 if (
const auto* elem =
findChild(childName)) {
69 std::string_view childName, std::string_view defaultValue)
const
72 return child ? child->getData() : defaultValue;
84 if (!child)
return defaultValue;
85 auto r = StringOp::stringTo<int>(child->getData());
86 return r ? *r : defaultValue;
97 for (
const auto* attr = firstAttribute; attr; attr = attr->nextAttribute) {
98 if (attr->getName() == attrName) {
109 if (result)
return *result;
120 std::string_view defaultValue)
const
123 return attr ? attr->getValue() : defaultValue;
128 bool defaultValue)
const
135 int defaultValue)
const
138 if (!attr)
return defaultValue;
139 auto r = StringOp::stringTo<int>(attr->getValue());
140 return r ? *r : defaultValue;
147 for (
auto** attr = &firstAttribute; *attr; attr = &(*attr)->nextAttribute) {
148 if ((*attr)->getName() == attrName) {
158 auto* attr = *attrPtr;
159 *attrPtr = attr->nextAttribute;
172 auto** elem = &parent.firstChild;
176 n->setData(childData);
180 if ((*elem)->getName() == childName) {
183 elem = &(*elem)->nextSibling;
191 auto** elem = &parent.firstChild;
196 (*elem)->setData(childData);
199 if ((*elem)->getName() == childName) {
200 (*elem)->setData(childData);
203 elem = &(*elem)->nextSibling;
211 auto** attr = &elem.firstAttribute;
218 if ((*attr)->getName() == attrName) {
219 (*attr)->setValue(attrValue);
222 attr = &(*attr)->nextAttribute;
233 , nextElement(&doc.root) {}
235 [[nodiscard]] std::string_view
getSystemID()
const {
return systemID; }
238 stack.push_back(currentElement);
243 assert(*nextElement ==
nullptr);
245 nextElement = &n->firstChild;
247 nextAttribute = &n->firstAttribute;
251 nextElement = ¤tElement->nextSibling;
252 nextAttribute =
nullptr;
253 currentElement = stack.back();
258 currentElement->data =
text.data();
261 void attribute(std::string_view name, std::string_view value) {
264 assert(nextAttribute);
265 assert(*nextAttribute ==
nullptr);
267 nextAttribute = &a->nextAttribute;
271 auto pos1 = txt.find(
" SYSTEM ");
272 if (pos1 == std::string_view::npos)
return;
273 if ((pos1 + 8) >= txt.size())
return;
274 char q = txt[pos1 + 8];
275 if (q !=
one_of(
'"',
'\''))
return;
276 auto t = txt.substr(pos1 + 9);
277 auto pos2 =
t.find(q);
278 if (pos2 == std::string_view::npos)
return;
280 systemID =
t.substr(0, pos2);
286 std::string_view systemID;
287 std::vector<XMLElement*> stack;
313 auto* p =
static_cast<char*
>(allocator.
allocate(str.size() + 1,
alignof(
char)));
330 throw XMLException(filename,
": failed to read: ",
e.getMessage());
335 rapidsax::parse<rapidsax::zeroTerminateStrings>(handler, buf.
data());
337 throw XMLException(filename,
": Document parsing failed: ",
e.what());
341 ": Document doesn't contain mandatory root Element");
345 "You're probably using an old incompatible file format.");
348 throw XMLException(filename,
": systemID doesn't match "
349 "(expected ", systemID,
", got ", handler.
getSystemID(),
")\n"
350 "You're probably using an old incompatible file format.");
357 if (name.empty())
return nullptr;
360 unsigned numAttrs; ar.
load(numAttrs);
361 auto** attrPtr = &elem->firstAttribute;
367 attrPtr = &attr->nextAttribute;
370 unsigned numElems; ar.
load(numElems);
372 auto** elemPtr = &elem->firstChild;
374 auto* n = loadElement(ar);
376 elemPtr = &n->nextSibling;
390 root = loadElement(ar);
399 ar.
save(attr.getName());
400 ar.
save(attr.getValue());
407 saveElement(ar, child);
417 saveElement(ar, *root);
419 std::string_view empty;
428 auto** attrPtr = &outElem->firstAttribute;
434 attrPtr = &outAttr->nextAttribute;
437 if (
auto data = inElem.
getData() ; !data.empty()) {
441 auto** childPtr = &outElem->firstChild;
443 auto* outChild = clone(inChild);
444 *childPtr = outChild;
445 childPtr = &outChild->nextSibling;
455 assert(elem->nextSibling ==
nullptr);
464 stream.
attribute(attr.getName(), attr.getValue());
468 saveElement(stream, child);
480 saveElement(stream, *root);
488 auto** attrPtr = &outElem->firstAttribute;
489 for (
const auto& [inName, inValue] : inElem.
attributes) {
494 attrPtr = &outAttr->nextAttribute;
497 if (!inElem.
data.empty()) {
501 auto** childPtr = &outElem->firstChild;
502 for (
const auto& inChild : inElem.
children) {
503 auto* outChild = clone(inChild);
504 *childPtr = outChild;
505 childPtr = &outChild->nextSibling;
517static std::unique_ptr<FileContext> lastSerializedFileContext;
520 return std::move(lastSerializedFileContext);
534template<
typename Archive>
537 assert(Archive::IS_LOADER);
538 ar.serialize(
"name",
name,
543 if (ar.versionBelow(version, 2)) {
544 std::unique_ptr<FileContext>
context;
545 ar.serialize(
"context",
context);
547 lastSerializedFileContext = std::move(
context);
'XMLOutputStream' is a helper to write an XML file in a streaming way.
void attribute(std::string_view name, std::string_view value)
void begin(std::string_view tag)
void end(std::string_view tag)
void data(std::string_view value)
void * allocate(size_t bytes, size_t alignment)
void read(std::span< uint8_t > buffer)
Read from file.
size_t getSize()
Returns the size of this file.
void resize(size_t size)
Grow or shrink the memory block.
const T * data() const
Returns pointer to the start of the memory buffer.
std::string_view getValue() const
void attribute(std::string_view name, std::string_view value)
void doctype(std::string_view txt)
void start(std::string_view name)
XMLDocumentHandler(XMLDocument &doc_)
std::string_view getSystemID() const
void text(std::string_view text)
XMLElement * setChildData(XMLElement &parent, const char *childName, const char *childData)
void serialize(MemInputArchive &ar, unsigned version)
XMLElement * getOrCreateChild(XMLElement &parent, const char *childName, const char *childData)
void setAttribute(XMLElement &elem, const char *attrName, const char *attrValue)
const char * allocateString(std::string_view str)
XMLElement * allocateElement(const char *name)
XMLAttribute * allocateAttribute(const char *name, const char *value)
void load(const std::string &filename, std::string_view systemID)
std::string_view getName() const
size_t numChildren() const
XMLAttribute ** findAttributePointer(std::string_view attrName)
int getChildDataAsInt(std::string_view childName, int defaultValue) const
AttributeRange getAttributes() const
const XMLAttribute * findAttribute(std::string_view attrName) const
const XMLElement * findChild(std::string_view childName) const
static void removeAttribute(XMLAttribute **attrPtr)
std::string_view getAttributeValue(std::string_view attrName) const
size_t numAttributes() const
int getAttributeValueAsInt(std::string_view attrName, int defaultValue) const
const XMLAttribute & getAttribute(std::string_view attrName) const
const XMLElement & getChild(std::string_view childName) const
std::string_view getChildData(std::string_view childName) const
std::string_view getData() const
bool getChildDataAsBool(std::string_view childName, bool defaultValue) const
bool getAttributeValueAsBool(std::string_view attrName, bool defaultValue) const
ChildRange getChildren() const
const XMLElement * getFirstChild() const
auto & getXMLOutputStream()
bool stringToBool(string_view str)
std::optional< Context > context
This file implemented 3 utility functions:
auto copy(InputRange &&range, OutputIter out)
constexpr size_t EXTRA_BUFFER_SPACE
size_t size(std::string_view utf8)
auto distance(octet_iterator first, octet_iterator last)
#define INSTANTIATE_SERIALIZE_METHODS(CLASS)
void serialize(Archive &ar, unsigned version)
std::vector< OldXMLElement > children
std::vector< std::pair< std::string, std::string > > attributes
static std::unique_ptr< FileContext > getLastSerializedFileContext()
constexpr void repeat(T n, Op op)
Repeat the given operation 'op' 'n' times.
constexpr auto begin(const zstring_view &x)
constexpr auto end(const zstring_view &x)