xml.cpp revision da0cd3ee12f6b9c0e86f2aea3213cba6869b6647
35473cad6d5d5b57348c66f0cfdd7d51d6071ee7vboxsync * IPRT - XML Manipulation API.
f001425d2b0a661d4cd1f7ea07b4e7454538c829vboxsync * Copyright (C) 2007-2012 Oracle Corporation
fcae7923a3c756b333f1e33eba002edf4448fb54vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
fcae7923a3c756b333f1e33eba002edf4448fb54vboxsync * available from http://www.virtualbox.org. This file is free software;
fcae7923a3c756b333f1e33eba002edf4448fb54vboxsync * you can redistribute it and/or modify it under the terms of the GNU
fcae7923a3c756b333f1e33eba002edf4448fb54vboxsync * General Public License (GPL) as published by the Free Software
fcae7923a3c756b333f1e33eba002edf4448fb54vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
fcae7923a3c756b333f1e33eba002edf4448fb54vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
fcae7923a3c756b333f1e33eba002edf4448fb54vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
f001425d2b0a661d4cd1f7ea07b4e7454538c829vboxsync * The contents of this file may alternatively be used under the terms
f001425d2b0a661d4cd1f7ea07b4e7454538c829vboxsync * of the Common Development and Distribution License Version 1.0
f001425d2b0a661d4cd1f7ea07b4e7454538c829vboxsync * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
f001425d2b0a661d4cd1f7ea07b4e7454538c829vboxsync * VirtualBox OSE distribution, in which case the provisions of the
f001425d2b0a661d4cd1f7ea07b4e7454538c829vboxsync * CDDL are applicable instead of those of the GPL.
f001425d2b0a661d4cd1f7ea07b4e7454538c829vboxsync * You may elect to license modified versions of this file under the
f001425d2b0a661d4cd1f7ea07b4e7454538c829vboxsync * terms and conditions of either the GPL or the CDDL or both.
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync////////////////////////////////////////////////////////////////////////////////
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync////////////////////////////////////////////////////////////////////////////////
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * Global module initialization structure. This is to wrap non-reentrant bits
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * of libxml, among other things.
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * The constructor and destructor of this structure are used to perform global
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * module initialization and cleanup. There must be only one global variable of
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * this structure.
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync /* Check the parser version. The docs say it will kill the app if
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * there is a serious version mismatch, but I couldn't find it in the
561b8d2b46fb10887829b7e4d7d29447817adbddvboxsync * source code (it only prints the error/warning message to the console) so
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * let's leave it as is for informational purposes. */
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync /* Init libxml */
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync /* Save the default entity resolver before someone has replaced it */
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync sxml.defaultEntityLoader = xmlGetExternalEntityLoader();
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync /* Shutdown libxml */
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync /** Used to provide some thread safety missing in libxml2 (see e.g.
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * XmlTreeBackend::read()) */
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync sxml; /* XXX naming this xml will break with gcc-3.3 */
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync////////////////////////////////////////////////////////////////////////////////
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync// Exceptions
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync////////////////////////////////////////////////////////////////////////////////
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * Composes a single message for the given error. The caller must free the
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * returned string using RTStrFree() when no more necessary.
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync const char *msg = aErr->message ? aErr->message : "<none>";
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync /* strip spaces, trailing EOLs and dot-like char */
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync while (msgLen && strchr(" \n.?!", msg [msgLen - 1]))
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync RTStrAPrintf(&finalMsg, "%.*s.\nLocation: '%s', line %d (%d), column %d",
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync msgLen, msg, aErr->file, aErr->line, aErr->int1, aErr->int2);
1403063c7e0c0a072d59e323b66068b06278fb9avboxsyncEIPRTFailure::EIPRTFailure(int aRC, const char *pcszContext, ...)
f48c3167a0f99da174686b66dc4e666f38ecae46vboxsync RTStrAPrintf(&newMsg, "%s: %d (%s)", pszContext2, aRC, RTErrGetShort(aRC));
f48c3167a0f99da174686b66dc4e666f38ecae46vboxsync////////////////////////////////////////////////////////////////////////////////
f48c3167a0f99da174686b66dc4e666f38ecae46vboxsync// File Class
f48c3167a0f99da174686b66dc4e666f38ecae46vboxsync//////////////////////////////////////////////////////////////////////////////
1403063c7e0c0a072d59e323b66068b06278fb9avboxsyncFile::File(Mode aMode, const char *aFileName, bool aFlushIt /* = false */)
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync /** @todo change to RTFILE_O_DENY_WRITE where appropriate. */
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync flags = RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_NONE;
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync flags = RTFILE_O_WRITE | RTFILE_O_CREATE | RTFILE_O_DENY_NONE;
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync flags = RTFILE_O_WRITE | RTFILE_O_CREATE_REPLACE | RTFILE_O_DENY_NONE;
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync flags = RTFILE_O_READWRITE | RTFILE_O_OPEN | RTFILE_O_DENY_NONE;;
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync int vrc = RTFileOpen(&m->handle, aFileName, flags);
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync throw EIPRTFailure(vrc, "Runtime error opening '%s' for reading", aFileName);
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync m->flushOnClose = aFlushIt && (flags & RTFILE_O_ACCESS_MASK) != RTFILE_O_READ;
1403063c7e0c0a072d59e323b66068b06278fb9avboxsyncFile::File(RTFILE aHandle, const char *aFileName /* = NULL */, bool aFlushIt /* = false */)
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync int vrc = RTFileSeek(m->handle, 0, RTFILE_SEEK_CURRENT, &p);
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync throw EIPRTFailure(vrc, "Runtime error seeking in file '%s'", m->strFileName.c_str());
6479169ec893c18a646cec595e4e214492d180f0vboxsync /* check if we overflow int64_t and move to INT64_MAX first */
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync vrc = RTFileSeek(m->handle, INT64_MAX, method, &p);
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync /* seek the rest */
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync vrc = RTFileSeek(m->handle, (int64_t) aPos, method, &p);
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync throw EIPRTFailure(vrc, "Runtime error seeking in file '%s'", m->strFileName.c_str());
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync return (int)len;
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync throw EIPRTFailure(vrc, "Runtime error reading from file '%s'", m->strFileName.c_str());
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync int vrc = RTFileWrite (m->handle, aBuf, len, &len);
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync return (int)len;
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync throw EIPRTFailure(vrc, "Runtime error writing to file '%s'", m->strFileName.c_str());
f48c3167a0f99da174686b66dc4e666f38ecae46vboxsync throw EIPRTFailure(vrc, "Runtime error truncating file '%s'", m->strFileName.c_str());
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync////////////////////////////////////////////////////////////////////////////////
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync// MemoryBuf Class
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync//////////////////////////////////////////////////////////////////////////////
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync const char *buf;
1403063c7e0c0a072d59e323b66068b06278fb9avboxsyncMemoryBuf::MemoryBuf (const char *aBuf, size_t aLen, const char *aURI /* = NULL */)
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync : m (new Data())
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync return 0 /* nothing to read */;
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync size_t len = m->pos + aLen < m->len ? aLen : m->len - m->pos;
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync return (int)len;
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync////////////////////////////////////////////////////////////////////////////////
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync// GlobalLock class
f48c3167a0f99da174686b66dc4e666f38ecae46vboxsync////////////////////////////////////////////////////////////////////////////////
6479169ec893c18a646cec595e4e214492d180f0vboxsyncvoid GlobalLock::setExternalEntityLoader(PFNEXTERNALENTITYLOADER pLoader)
6479169ec893c18a646cec595e4e214492d180f0vboxsyncxmlParserInput* GlobalLock::callDefaultLoader(const char *aURI,
6479169ec893c18a646cec595e4e214492d180f0vboxsync const char *aID,
6479169ec893c18a646cec595e4e214492d180f0vboxsync return gGlobal.sxml.defaultEntityLoader(aURI, aID, aCtxt);
6479169ec893c18a646cec595e4e214492d180f0vboxsync////////////////////////////////////////////////////////////////////////////////
6479169ec893c18a646cec595e4e214492d180f0vboxsync// Node class
6479169ec893c18a646cec595e4e214492d180f0vboxsync////////////////////////////////////////////////////////////////////////////////
6479169ec893c18a646cec595e4e214492d180f0vboxsync bool operator()(const char* s1, const char* s2) const
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync // attributes, if this is an element; can be empty
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync typedef std::map<const char*, boost::shared_ptr<AttributeNode>, compare_const_char > AttributesMap;
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync // child elements, if this is an element; can be empty
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync typedef std::list< boost::shared_ptr<Node> > InternalNodesList;
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * Private implementation.
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * @param elmRoot
1403063c7e0c0a072d59e323b66068b06278fb9avboxsyncvoid Node::buildChildren(const ElementNode &elmRoot) // private
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync // go thru this element's attributes
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync const char *pcszKey;
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync boost::shared_ptr<AttributeNode> pNew(new AttributeNode(elmRoot, this, plibAttr, &pcszKey));
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync // go thru this element's child elements
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync pNew = boost::shared_ptr<Node>(new ElementNode(&elmRoot, this, plibNode));
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync pNew = boost::shared_ptr<Node>(new ContentNode(this, plibNode));
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync // recurse for this child element to get its own children
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * Returns the name of the node, which is either the element name or
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * the attribute name. For other node types it probably returns NULL.
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * Returns the name of the node, which is either the element name or
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * the attribute name. For other node types it probably returns NULL.
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * Returns the XML namespace URI, which is the attribute name. For other node types it probably
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * returns NULL.
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * Variant of nameEquals that checks the namespace as well.
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * @param pcszNamespace
6479169ec893c18a646cec595e4e214492d180f0vboxsync * @param pcsz
6479169ec893c18a646cec595e4e214492d180f0vboxsyncbool Node::nameEquals(const char *pcszNamespace, const char *pcsz) const
1519f0483877fddc0a03ab7e3382124f889bb36avboxsync return true;
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync return false;
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync return false;
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync return false;
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync // name matches: then check namespaces as well
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync return true;
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync // caller wants namespace:
1519f0483877fddc0a03ab7e3382124f889bb36avboxsync // but node has no namespace:
1519f0483877fddc0a03ab7e3382124f889bb36avboxsync return false;
1519f0483877fddc0a03ab7e3382124f889bb36avboxsync return !strcmp(m_pcszNamespacePrefix, pcszNamespace);
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * Returns the value of a node. If this node is an attribute, returns
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * the attribute value; if this node is an element, then this returns
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * the element text content.
2084a447d1acb619df7c393fac41b79d517e4b3dvboxsync // libxml hides attribute values in another node created as a
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync // single child of the attribute node, and it's in the content field
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * Copies the value of a node into the given integer variable.
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * Returns TRUE only if a value was found and was actually an
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * integer of the given type.
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync const char *pcsz;
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync && (VINF_SUCCESS == RTStrToInt32Ex(pcsz, NULL, 10, &i))
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync return true;
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync return false;
6479169ec893c18a646cec595e4e214492d180f0vboxsync * Copies the value of a node into the given integer variable.
6479169ec893c18a646cec595e4e214492d180f0vboxsync * Returns TRUE only if a value was found and was actually an
6479169ec893c18a646cec595e4e214492d180f0vboxsync * integer of the given type.
6479169ec893c18a646cec595e4e214492d180f0vboxsync const char *pcsz;
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync && (VINF_SUCCESS == RTStrToUInt32Ex(pcsz, NULL, 10, &i))
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync return true;
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync return false;
1519f0483877fddc0a03ab7e3382124f889bb36avboxsync * Copies the value of a node into the given integer variable.
1519f0483877fddc0a03ab7e3382124f889bb36avboxsync * Returns TRUE only if a value was found and was actually an
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * integer of the given type.
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync const char *pcsz;
6479169ec893c18a646cec595e4e214492d180f0vboxsync && (VINF_SUCCESS == RTStrToInt64Ex(pcsz, NULL, 10, &i))
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync return true;
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync return false;
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * Copies the value of a node into the given integer variable.
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * Returns TRUE only if a value was found and was actually an
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * integer of the given type.
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync const char *pcsz;
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync && (VINF_SUCCESS == RTStrToUInt64Ex(pcsz, NULL, 10, &i))
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync return true;
6479169ec893c18a646cec595e4e214492d180f0vboxsync return false;
6479169ec893c18a646cec595e4e214492d180f0vboxsync * Returns the line number of the current node in the source XML file.
6479169ec893c18a646cec595e4e214492d180f0vboxsync * Useful for error messages.
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * Private element constructor.
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * @param pelmRoot
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * @param pParent
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * @param plibNode
1403063c7e0c0a072d59e323b66068b06278fb9avboxsyncElementNode::ElementNode(const ElementNode *pelmRoot,
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync // NULL passed, then this is the root element
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync m_pcszNamespacePrefix = (const char*)m_plibNode->ns->prefix;
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync m_pcszNamespaceHref = (const char*)m_plibNode->ns->href;
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * Builds a list of direct child elements of the current element that
f48c3167a0f99da174686b66dc4e666f38ecae46vboxsync * match the given string; if pcszMatch is NULL, all direct child
6479169ec893c18a646cec595e4e214492d180f0vboxsync * elements are returned.
6479169ec893c18a646cec595e4e214492d180f0vboxsync * @param children out: list of nodes to which children will be appended.
f48c3167a0f99da174686b66dc4e666f38ecae46vboxsync * @param pcszMatch in: match string, or NULL to return all children.
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * @return Number of items appended to the list (0 if none).
1403063c7e0c0a072d59e323b66068b06278fb9avboxsyncint ElementNode::getChildElements(ElementNodesList &children,
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync for (Data::InternalNodesList::iterator it = m->children.begin();
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync // export this child node if ...
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync || (!strcmp(pcszMatch, p->getName())) // the element name matches
f48c3167a0f99da174686b66dc4e666f38ecae46vboxsync * Returns the first child element whose name matches pcszMatch.
f48c3167a0f99da174686b66dc4e666f38ecae46vboxsync * @param pcszNamespace Namespace prefix (e.g. "vbox") or NULL to match any namespace.
f48c3167a0f99da174686b66dc4e666f38ecae46vboxsync * @param pcszMatch Element name to match.
1403063c7e0c0a072d59e323b66068b06278fb9avboxsyncconst ElementNode* ElementNode::findChildElement(const char *pcszNamespace,
f48c3167a0f99da174686b66dc4e666f38ecae46vboxsync ElementNode *pelm = static_cast<ElementNode*>((*it).get());
f48c3167a0f99da174686b66dc4e666f38ecae46vboxsync * Returns the first child element whose "id" attribute matches pcszId.
f48c3167a0f99da174686b66dc4e666f38ecae46vboxsync * @param pcszId identifier to look for.
f48c3167a0f99da174686b66dc4e666f38ecae46vboxsync * @return child element or NULL if not found.
1403063c7e0c0a072d59e323b66068b06278fb9avboxsyncconst ElementNode* ElementNode::findChildElementFromId(const char *pcszId) const
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync ElementNode *pelm = static_cast<ElementNode*>((*it).get());
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * Looks up the given attribute node in this element's attribute map.
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * With respect to namespaces, the internal attributes map stores namespace
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * prefixes with attribute names only if the attribute uses a non-default
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * namespace. As a result, the following rules apply:
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * -- To find attributes from a non-default namespace, pcszMatch must not
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * be prefixed with a namespace.
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * -- To find attributes from the default namespace (or if the document does
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * not use namespaces), pcszMatch must be prefixed with the namespace
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * prefix and a colon.
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * For example, if the document uses the "vbox:" namespace by default, you
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * must omit "vbox:" from pcszMatch to find such attributes, whether they
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * are specifed in the xml or not.
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * @param pcszMatch
1403063c7e0c0a072d59e323b66068b06278fb9avboxsyncconst AttributeNode* ElementNode::findAttribute(const char *pcszMatch) const
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * Convenience method which attempts to find the attribute with the given
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * name and returns its value as a string.
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * @param pcszMatch name of attribute to find (see findAttribute() for namespace remarks)
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * @param ppcsz out: attribute value
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * @return TRUE if attribute was found and str was thus updated.
1403063c7e0c0a072d59e323b66068b06278fb9avboxsyncbool ElementNode::getAttributeValue(const char *pcszMatch, const char *&ppcsz) const
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync return true;
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync return false;
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * Convenience method which attempts to find the attribute with the given
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * name and returns its value as a string.
6479169ec893c18a646cec595e4e214492d180f0vboxsync * @param pcszMatch name of attribute to find (see findAttribute() for namespace remarks)
6479169ec893c18a646cec595e4e214492d180f0vboxsync * @param str out: attribute value; overwritten only if attribute was found
6479169ec893c18a646cec595e4e214492d180f0vboxsync * @return TRUE if attribute was found and str was thus updated.
6479169ec893c18a646cec595e4e214492d180f0vboxsyncbool ElementNode::getAttributeValue(const char *pcszMatch, RTCString &str) const
6479169ec893c18a646cec595e4e214492d180f0vboxsync return true;
35473cad6d5d5b57348c66f0cfdd7d51d6071ee7vboxsync return false;
35473cad6d5d5b57348c66f0cfdd7d51d6071ee7vboxsync * Like getAttributeValue (ministring variant), but makes sure that all backslashes
35473cad6d5d5b57348c66f0cfdd7d51d6071ee7vboxsync * are converted to forward slashes.
35473cad6d5d5b57348c66f0cfdd7d51d6071ee7vboxsync * @param pcszMatch
35473cad6d5d5b57348c66f0cfdd7d51d6071ee7vboxsync * @param str
35473cad6d5d5b57348c66f0cfdd7d51d6071ee7vboxsyncbool ElementNode::getAttributeValuePath(const char *pcszMatch, RTCString &str) const
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync return true;
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync return false;
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * Convenience method which attempts to find the attribute with the given
f65dabff4474710524235022d328b737f174fc1dvboxsync * name and returns its value as a signed integer. This calls
f65dabff4474710524235022d328b737f174fc1dvboxsync * RTStrToInt32Ex internally and will only output the integer if that
f65dabff4474710524235022d328b737f174fc1dvboxsync * function returns no error.
f65dabff4474710524235022d328b737f174fc1dvboxsync * @param pcszMatch name of attribute to find (see findAttribute() for namespace remarks)
f65dabff4474710524235022d328b737f174fc1dvboxsync * @param i out: attribute value; overwritten only if attribute was found
f65dabff4474710524235022d328b737f174fc1dvboxsync * @return TRUE if attribute was found and str was thus updated.
f65dabff4474710524235022d328b737f174fc1dvboxsyncbool ElementNode::getAttributeValue(const char *pcszMatch, int32_t &i) const
f65dabff4474710524235022d328b737f174fc1dvboxsync const char *pcsz;
f65dabff4474710524235022d328b737f174fc1dvboxsync && (VINF_SUCCESS == RTStrToInt32Ex(pcsz, NULL, 0, &i))
f65dabff4474710524235022d328b737f174fc1dvboxsync return true;
f65dabff4474710524235022d328b737f174fc1dvboxsync return false;
f65dabff4474710524235022d328b737f174fc1dvboxsync * Convenience method which attempts to find the attribute with the given
f65dabff4474710524235022d328b737f174fc1dvboxsync * name and returns its value as an unsigned integer.This calls
f65dabff4474710524235022d328b737f174fc1dvboxsync * RTStrToUInt32Ex internally and will only output the integer if that
f65dabff4474710524235022d328b737f174fc1dvboxsync * function returns no error.
f65dabff4474710524235022d328b737f174fc1dvboxsync * @param pcszMatch name of attribute to find (see findAttribute() for namespace remarks)
f65dabff4474710524235022d328b737f174fc1dvboxsync * @param i out: attribute value; overwritten only if attribute was found
f65dabff4474710524235022d328b737f174fc1dvboxsync * @return TRUE if attribute was found and str was thus updated.
f65dabff4474710524235022d328b737f174fc1dvboxsyncbool ElementNode::getAttributeValue(const char *pcszMatch, uint32_t &i) const
f65dabff4474710524235022d328b737f174fc1dvboxsync const char *pcsz;
f65dabff4474710524235022d328b737f174fc1dvboxsync && (VINF_SUCCESS == RTStrToUInt32Ex(pcsz, NULL, 0, &i))
f65dabff4474710524235022d328b737f174fc1dvboxsync return true;
f65dabff4474710524235022d328b737f174fc1dvboxsync return false;
f65dabff4474710524235022d328b737f174fc1dvboxsync * Convenience method which attempts to find the attribute with the given
f65dabff4474710524235022d328b737f174fc1dvboxsync * name and returns its value as a signed long integer. This calls
f65dabff4474710524235022d328b737f174fc1dvboxsync * RTStrToInt64Ex internally and will only output the integer if that
f65dabff4474710524235022d328b737f174fc1dvboxsync * function returns no error.
f65dabff4474710524235022d328b737f174fc1dvboxsync * @param pcszMatch name of attribute to find (see findAttribute() for namespace remarks)
f65dabff4474710524235022d328b737f174fc1dvboxsync * @param i out: attribute value
f65dabff4474710524235022d328b737f174fc1dvboxsync * @return TRUE if attribute was found and str was thus updated.
f65dabff4474710524235022d328b737f174fc1dvboxsyncbool ElementNode::getAttributeValue(const char *pcszMatch, int64_t &i) const
f65dabff4474710524235022d328b737f174fc1dvboxsync const char *pcsz;
f65dabff4474710524235022d328b737f174fc1dvboxsync && (VINF_SUCCESS == RTStrToInt64Ex(pcsz, NULL, 0, &i))
f65dabff4474710524235022d328b737f174fc1dvboxsync return true;
f65dabff4474710524235022d328b737f174fc1dvboxsync return false;
f65dabff4474710524235022d328b737f174fc1dvboxsync * Convenience method which attempts to find the attribute with the given
f65dabff4474710524235022d328b737f174fc1dvboxsync * name and returns its value as an unsigned long integer.This calls
f65dabff4474710524235022d328b737f174fc1dvboxsync * RTStrToUInt64Ex internally and will only output the integer if that
f65dabff4474710524235022d328b737f174fc1dvboxsync * function returns no error.
f65dabff4474710524235022d328b737f174fc1dvboxsync * @param pcszMatch name of attribute to find (see findAttribute() for namespace remarks)
f65dabff4474710524235022d328b737f174fc1dvboxsync * @param i out: attribute value; overwritten only if attribute was found
f65dabff4474710524235022d328b737f174fc1dvboxsync * @return TRUE if attribute was found and str was thus updated.
1403063c7e0c0a072d59e323b66068b06278fb9avboxsyncbool ElementNode::getAttributeValue(const char *pcszMatch, uint64_t &i) const
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync const char *pcsz;
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync && (VINF_SUCCESS == RTStrToUInt64Ex(pcsz, NULL, 0, &i))
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync return true;
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync return false;
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * Convenience method which attempts to find the attribute with the given
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * name and returns its value as a boolean. This accepts "true", "false",
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * "yes", "no", "1" or "0" as valid values.
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * @param pcszMatch name of attribute to find (see findAttribute() for namespace remarks)
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * @param f out: attribute value; overwritten only if attribute was found
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * @return TRUE if attribute was found and str was thus updated.
14a3a4c9d0c43ff4b0e32ee6e45e5c842527dc6dvboxsyncbool ElementNode::getAttributeValue(const char *pcszMatch, bool &f) const
14a3a4c9d0c43ff4b0e32ee6e45e5c842527dc6dvboxsync const char *pcsz;
35473cad6d5d5b57348c66f0cfdd7d51d6071ee7vboxsync return true;
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync return true;
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync return false;
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * Creates a new child element node and appends it to the list
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * of children in "this".
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * @param pcszElementName
1403063c7e0c0a072d59e323b66068b06278fb9avboxsyncElementNode* ElementNode::createChild(const char *pcszElementName)
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync // we must be an element, not an attribute
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync // libxml side: create new node
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync // now wrap this in C++
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync ElementNode *p = new ElementNode(m_pelmRoot, this, plibNode);
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * Creates a content node and appends it to the list of children
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * in "this".
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * @param pcszContent
1403063c7e0c0a072d59e323b66068b06278fb9avboxsyncContentNode* ElementNode::addContent(const char *pcszContent)
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync // libxml side: create new node
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync if (!(plibNode = xmlNewText((const xmlChar*)pcszContent)))
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync // now wrap this in C++
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * Sets the given attribute; overloaded version for const char *.
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * If an attribute with the given name exists, it is overwritten,
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * otherwise a new attribute is created. Returns the attribute node
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * that was either created or changed.
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * @param pcszName
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * @param pcszValue
1403063c7e0c0a072d59e323b66068b06278fb9avboxsyncAttributeNode* ElementNode::setAttribute(const char *pcszName, const char *pcszValue)
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync // libxml side: xmlNewProp creates an attribute
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync xmlAttr *plibAttr = xmlNewProp(m_plibNode, (xmlChar*)pcszName, (xmlChar*)pcszValue);
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync // C++ side: create an attribute node around it
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync const char *pcszKey;
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync boost::shared_ptr<AttributeNode> pNew(new AttributeNode(*m_pelmRoot, this, plibAttr, &pcszKey));
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync // overwrite existing libxml attribute node
35473cad6d5d5b57348c66f0cfdd7d51d6071ee7vboxsync xmlAttrPtr plibAttr = xmlSetProp(m_plibNode, (xmlChar*)pcszName, (xmlChar*)pcszValue);
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync // and fix our existing C++ side around it
35473cad6d5d5b57348c66f0cfdd7d51d6071ee7vboxsync boost::shared_ptr<AttributeNode> pattr = it->second;
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync pattr->m_plibAttr = plibAttr; // in case the xmlAttrPtr is different, I'm not sure
35473cad6d5d5b57348c66f0cfdd7d51d6071ee7vboxsync * Like setAttribute (ministring variant), but replaces all backslashes with forward slashes
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * before calling that one.
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * @param pcszName
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * @param strValue
1403063c7e0c0a072d59e323b66068b06278fb9avboxsyncAttributeNode* ElementNode::setAttributePath(const char *pcszName, const RTCString &strValue)
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * Sets the given attribute; overloaded version for int32_t.
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * If an attribute with the given name exists, it is overwritten,
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * otherwise a new attribute is created. Returns the attribute node
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * that was either created or changed.
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * @param pcszName
1403063c7e0c0a072d59e323b66068b06278fb9avboxsyncAttributeNode* ElementNode::setAttribute(const char *pcszName, int32_t i)
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync char szValue[12]; // negative sign + 10 digits + \0
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync AttributeNode *p = setAttribute(pcszName, szValue);
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * Sets the given attribute; overloaded version for uint32_t.
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * If an attribute with the given name exists, it is overwritten,
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * otherwise a new attribute is created. Returns the attribute node
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * that was either created or changed.
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * @param pcszName
1403063c7e0c0a072d59e323b66068b06278fb9avboxsyncAttributeNode* ElementNode::setAttribute(const char *pcszName, uint32_t u)
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync AttributeNode *p = setAttribute(pcszName, szValue);
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * Sets the given attribute; overloaded version for int64_t.
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * If an attribute with the given name exists, it is overwritten,
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * otherwise a new attribute is created. Returns the attribute node
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * that was either created or changed.
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * @param pcszName
1403063c7e0c0a072d59e323b66068b06278fb9avboxsyncAttributeNode* ElementNode::setAttribute(const char *pcszName, int64_t i)
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync char szValue[21]; // negative sign + 19 digits + \0
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync AttributeNode *p = setAttribute(pcszName, szValue);
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * Sets the given attribute; overloaded version for uint64_t.
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * If an attribute with the given name exists, it is overwritten,
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * otherwise a new attribute is created. Returns the attribute node
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * that was either created or changed.
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * @param pcszName
1403063c7e0c0a072d59e323b66068b06278fb9avboxsyncAttributeNode* ElementNode::setAttribute(const char *pcszName, uint64_t u)
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync AttributeNode *p = setAttribute(pcszName, szValue);
1519f0483877fddc0a03ab7e3382124f889bb36avboxsync * Sets the given attribute to the given uint32_t, outputs a hexadecimal string.
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * If an attribute with the given name exists, it is overwritten,
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * otherwise a new attribute is created. Returns the attribute node
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * that was either created or changed.
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * @param pcszName
1403063c7e0c0a072d59e323b66068b06278fb9avboxsyncAttributeNode* ElementNode::setAttributeHex(const char *pcszName, uint32_t u)
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync RTStrPrintf(szValue, sizeof(szValue), "0x%RX32", u);
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync AttributeNode *p = setAttribute(pcszName, szValue);
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * Sets the given attribute; overloaded version for bool.
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * If an attribute with the given name exists, it is overwritten,
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * otherwise a new attribute is created. Returns the attribute node
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * that was either created or changed.
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * @param pcszName
1403063c7e0c0a072d59e323b66068b06278fb9avboxsyncAttributeNode* ElementNode::setAttribute(const char *pcszName, bool f)
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync return setAttribute(pcszName, (f) ? "true" : "false");
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * Private constructor for a new attribute node. This one is special:
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * in ppcszKey, it returns a pointer to a string buffer that should be
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * used to index the attribute correctly with namespaces.
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * @param pParent
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * @param elmRoot
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * @param plibAttr
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * @param ppcszKey
1403063c7e0c0a072d59e323b66068b06278fb9avboxsyncAttributeNode::AttributeNode(const ElementNode &elmRoot,
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync const char **ppcszKey)
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync m_pcszNamespacePrefix = (const char*)plibAttr->ns->prefix;
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync m_pcszNamespaceHref = (const char*)plibAttr->ns->href;
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync || (strcmp(m_pcszNamespaceHref, elmRoot.m_pcszNamespaceHref))
6479169ec893c18a646cec595e4e214492d180f0vboxsync // not default namespace:
1403063c7e0c0a072d59e323b66068b06278fb9avboxsyncContentNode::ContentNode(Node *pParent, xmlNode *plibNode)
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * NodesLoop
1403063c7e0c0a072d59e323b66068b06278fb9avboxsyncNodesLoop::NodesLoop(const ElementNode &node, const char *pcszMatch /* = NULL */)
6e89506dd9d878449c4850f0ef4ade3424e2f1c1vboxsync * Handy convenience helper for looping over all child elements. Create an
6e89506dd9d878449c4850f0ef4ade3424e2f1c1vboxsync * instance of NodesLoop on the stack and call this method until it returns
6e89506dd9d878449c4850f0ef4ade3424e2f1c1vboxsync * NULL, like this:
6e89506dd9d878449c4850f0ef4ade3424e2f1c1vboxsync * xml::ElementNode node; // should point to an element
91ec4b43ffbf2a38ec79abe529bf141f7f7d4e93vboxsync * xml::NodesLoop loop(node, "child"); // find all "child" elements under node
f48c3167a0f99da174686b66dc4e666f38ecae46vboxsync * const xml::ElementNode *pChild = NULL;
f48c3167a0f99da174686b66dc4e666f38ecae46vboxsync * while (pChild = loop.forAllNodes())
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync////////////////////////////////////////////////////////////////////////////////
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync// Document class
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync////////////////////////////////////////////////////////////////////////////////
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync return *this;
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * private method to refresh all internal structures after the internal pDocument
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * has changed. Called from XmlFileParser::read(). m->reset() must have been
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * called before to make sure all members except the internal pDocument are clean.
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync m->pRootElement = new ElementNode(NULL, NULL, xmlDocGetRootElement(m->plibDocument));
09ca25a8a278cde483cba79172249b42179d796fvboxsync * Returns the root element of the document, or NULL if the document is empty.
09ca25a8a278cde483cba79172249b42179d796fvboxsync * Const variant.
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * Returns the root element of the document, or NULL if the document is empty.
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * Non-const variant.
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * Creates a new element node and sets it as the root element. This will
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * only work if the document is empty; otherwise EDocumentNotEmpty is thrown.
1403063c7e0c0a072d59e323b66068b06278fb9avboxsyncElementNode* Document::createRootElement(const char *pcszRootElementName,
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync // libxml side: create document, create root node
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync m->plibDocument = xmlNewDoc((const xmlChar*)"1.0");
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync xmlDocSetRootElement(m->plibDocument, plibRootNode);
6479169ec893c18a646cec595e4e214492d180f0vboxsync // now wrap this in C++
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync m->pRootElement = new ElementNode(NULL, NULL, plibRootNode);
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync // add document global comment if specified
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync // now wrap this in C++
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync m->pComment = new ElementNode(NULL, NULL, pComment);
fb4eaa62a6bbeb82a89703d833d39339783feb4avboxsync////////////////////////////////////////////////////////////////////////////////
fb4eaa62a6bbeb82a89703d833d39339783feb4avboxsync// XmlParserBase class
fb4eaa62a6bbeb82a89703d833d39339783feb4avboxsync////////////////////////////////////////////////////////////////////////////////
fb4eaa62a6bbeb82a89703d833d39339783feb4avboxsync////////////////////////////////////////////////////////////////////////////////
fb4eaa62a6bbeb82a89703d833d39339783feb4avboxsync// XmlMemParser class
fb4eaa62a6bbeb82a89703d833d39339783feb4avboxsync////////////////////////////////////////////////////////////////////////////////
fb4eaa62a6bbeb82a89703d833d39339783feb4avboxsync * Parse the given buffer and fills the given Document object with its contents.
fb4eaa62a6bbeb82a89703d833d39339783feb4avboxsync * Throws XmlError on parsing errors.
fb4eaa62a6bbeb82a89703d833d39339783feb4avboxsync * The document that is passed in will be reset before being filled if not empty.
fb4eaa62a6bbeb82a89703d833d39339783feb4avboxsync * @param pvBuf in: memory buffer to parse.
fb4eaa62a6bbeb82a89703d833d39339783feb4avboxsync * @param cbSize in: size of the memory buffer.
fb4eaa62a6bbeb82a89703d833d39339783feb4avboxsync * @param strFilename in: name fo file to parse.
fb4eaa62a6bbeb82a89703d833d39339783feb4avboxsync * @param doc out: document to be reset and filled with data according to file contents.
fb4eaa62a6bbeb82a89703d833d39339783feb4avboxsyncvoid XmlMemParser::read(const void* pvBuf, size_t cbSize,
fb4eaa62a6bbeb82a89703d833d39339783feb4avboxsync// global.setExternalEntityLoader(ExternalEntityLoader);
dbd602ecc07512999944bedae1e2d09c88f2298bvboxsync if (!(doc.m->plibDocument = xmlCtxtReadMemory(m_ctxt,
fb4eaa62a6bbeb82a89703d833d39339783feb4avboxsync (const char*)pvBuf,
fb4eaa62a6bbeb82a89703d833d39339783feb4avboxsync////////////////////////////////////////////////////////////////////////////////
fb4eaa62a6bbeb82a89703d833d39339783feb4avboxsync// XmlMemWriter class
fb4eaa62a6bbeb82a89703d833d39339783feb4avboxsync////////////////////////////////////////////////////////////////////////////////
fb4eaa62a6bbeb82a89703d833d39339783feb4avboxsyncvoid XmlMemWriter::write(const Document &doc, void **ppvBuf, size_t *pcbSize)
fb4eaa62a6bbeb82a89703d833d39339783feb4avboxsync xmlDocDumpFormatMemory(doc.m->plibDocument, (xmlChar**)&m_pBuf, &size, 1);
fb4eaa62a6bbeb82a89703d833d39339783feb4avboxsync////////////////////////////////////////////////////////////////////////////////
dbd602ecc07512999944bedae1e2d09c88f2298bvboxsync// XmlFileParser class
fb4eaa62a6bbeb82a89703d833d39339783feb4avboxsync////////////////////////////////////////////////////////////////////////////////
fb4eaa62a6bbeb82a89703d833d39339783feb4avboxsync IOContext(const char *pcszFilename, File::Mode mode, bool fFlush = false)
fb4eaa62a6bbeb82a89703d833d39339783feb4avboxsync WriteContext(const char *pcszFilename, bool fFlush)
fb4eaa62a6bbeb82a89703d833d39339783feb4avboxsync : IOContext(pcszFilename, File::Mode_Overwrite, fFlush)
fb4eaa62a6bbeb82a89703d833d39339783feb4avboxsync * Reads the given file and fills the given Document object with its contents.
fb4eaa62a6bbeb82a89703d833d39339783feb4avboxsync * Throws XmlError on parsing errors.
fb4eaa62a6bbeb82a89703d833d39339783feb4avboxsync * The document that is passed in will be reset before being filled if not empty.
dbd602ecc07512999944bedae1e2d09c88f2298bvboxsync * @param strFilename in: name fo file to parse.
fb4eaa62a6bbeb82a89703d833d39339783feb4avboxsync * @param doc out: document to be reset and filled with data according to file contents.
fb4eaa62a6bbeb82a89703d833d39339783feb4avboxsyncvoid XmlFileParser::read(const RTCString &strFilename,
fb4eaa62a6bbeb82a89703d833d39339783feb4avboxsync// global.setExternalEntityLoader(ExternalEntityLoader);
fb4eaa62a6bbeb82a89703d833d39339783feb4avboxsyncint XmlFileParser::ReadCallback(void *aCtxt, char *aBuf, int aLen)
fb4eaa62a6bbeb82a89703d833d39339783feb4avboxsync ReadContext *pContext = static_cast<ReadContext*>(aCtxt);
fb4eaa62a6bbeb82a89703d833d39339783feb4avboxsync /* To prevent throwing exceptions while inside libxml2 code, we catch
561b8d2b46fb10887829b7e4d7d29447817adbddvboxsync * them and forward to our level using a couple of variables. */
561b8d2b46fb10887829b7e4d7d29447817adbddvboxsync catch (const xml::EIPRTFailure &err) { pContext->setError(err); }
561b8d2b46fb10887829b7e4d7d29447817adbddvboxsync catch (const RTCError &err) { pContext->setError(err); }
561b8d2b46fb10887829b7e4d7d29447817adbddvboxsync catch (const std::exception &err) { pContext->setError(err); }
561b8d2b46fb10887829b7e4d7d29447817adbddvboxsync catch (...) { pContext->setError(xml::LogicError(RT_SRC_POS)); }
fb4eaa62a6bbeb82a89703d833d39339783feb4avboxsync /// @todo to be written
561b8d2b46fb10887829b7e4d7d29447817adbddvboxsync////////////////////////////////////////////////////////////////////////////////
561b8d2b46fb10887829b7e4d7d29447817adbddvboxsync// XmlFileWriter class
561b8d2b46fb10887829b7e4d7d29447817adbddvboxsync////////////////////////////////////////////////////////////////////////////////
fb4eaa62a6bbeb82a89703d833d39339783feb4avboxsyncvoid XmlFileWriter::writeInternal(const char *pcszFilename, bool fSafe)
561b8d2b46fb10887829b7e4d7d29447817adbddvboxsync /* serialize to the stream */
fb4eaa62a6bbeb82a89703d833d39339783feb4avboxsync long rc = xmlSaveDoc(saveCtxt, m->pDoc->m->plibDocument);
561b8d2b46fb10887829b7e4d7d29447817adbddvboxsync /* look if there was a forwarded exception from the lower level */
0360c14b2b3750bd2c90d935775ccdb05da307c9vboxsync// if (m->trappedErr.get() != NULL)
0360c14b2b3750bd2c90d935775ccdb05da307c9vboxsync// m->trappedErr->rethrow();
0360c14b2b3750bd2c90d935775ccdb05da307c9vboxsync /* there must be an exception from the Output implementation,
0360c14b2b3750bd2c90d935775ccdb05da307c9vboxsync * otherwise the save operation must always succeed. */
0360c14b2b3750bd2c90d935775ccdb05da307c9vboxsyncvoid XmlFileWriter::write(const char *pcszFilename, bool fSafe)
0360c14b2b3750bd2c90d935775ccdb05da307c9vboxsync /* Empty string and directory spec must be avoid. */
0360c14b2b3750bd2c90d935775ccdb05da307c9vboxsync /* Construct both filenames first to ease error handling. */
0360c14b2b3750bd2c90d935775ccdb05da307c9vboxsync int rc = RTStrCopy(szTmpFilename, sizeof(szTmpFilename) - strlen(s_pszTmpSuff), pcszFilename);
0360c14b2b3750bd2c90d935775ccdb05da307c9vboxsync rc = RTStrCopy(szPrevFilename, sizeof(szPrevFilename) - strlen(s_pszPrevSuff), pcszFilename);
0360c14b2b3750bd2c90d935775ccdb05da307c9vboxsync /* Write the XML document to the temporary file. */
561b8d2b46fb10887829b7e4d7d29447817adbddvboxsync /* Make a backup of any existing file (ignore failure). */
561b8d2b46fb10887829b7e4d7d29447817adbddvboxsync RTFileRename(pcszFilename, szPrevFilename, RTPATHRENAME_FLAGS_REPLACE);
561b8d2b46fb10887829b7e4d7d29447817adbddvboxsync /* Commit the temporary file. Just leave the tmp file behind on failure. */
561b8d2b46fb10887829b7e4d7d29447817adbddvboxsync rc = RTFileRename(szTmpFilename, pcszFilename, RTPATHRENAME_FLAGS_REPLACE);
561b8d2b46fb10887829b7e4d7d29447817adbddvboxsync throw EIPRTFailure(rc, "Failed to replace '%s' with '%s'", pcszFilename, szTmpFilename);
561b8d2b46fb10887829b7e4d7d29447817adbddvboxsync /* Flush the directory changes (required on linux at least). */
561b8d2b46fb10887829b7e4d7d29447817adbddvboxsync AssertMsg(RT_SUCCESS(rc) || rc == VERR_NOT_SUPPORTED || rc == VERR_NOT_IMPLEMENTED, ("%Rrc\n", rc));
561b8d2b46fb10887829b7e4d7d29447817adbddvboxsyncint XmlFileWriter::WriteCallback(void *aCtxt, const char *aBuf, int aLen)
561b8d2b46fb10887829b7e4d7d29447817adbddvboxsync WriteContext *pContext = static_cast<WriteContext*>(aCtxt);
561b8d2b46fb10887829b7e4d7d29447817adbddvboxsync /* To prevent throwing exceptions while inside libxml2 code, we catch
561b8d2b46fb10887829b7e4d7d29447817adbddvboxsync * them and forward to our level using a couple of variables. */
561b8d2b46fb10887829b7e4d7d29447817adbddvboxsync catch (const xml::EIPRTFailure &err) { pContext->setError(err); }
561b8d2b46fb10887829b7e4d7d29447817adbddvboxsync catch (const RTCError &err) { pContext->setError(err); }
561b8d2b46fb10887829b7e4d7d29447817adbddvboxsync catch (const std::exception &err) { pContext->setError(err); }
561b8d2b46fb10887829b7e4d7d29447817adbddvboxsync catch (...) { pContext->setError(xml::LogicError(RT_SRC_POS)); }
561b8d2b46fb10887829b7e4d7d29447817adbddvboxsync /// @todo to be written
561b8d2b46fb10887829b7e4d7d29447817adbddvboxsync/*static*/ const char * const XmlFileWriter::s_pszTmpSuff = "-tmp";
561b8d2b46fb10887829b7e4d7d29447817adbddvboxsync/*static*/ const char * const XmlFileWriter::s_pszPrevSuff = "-prev";
561b8d2b46fb10887829b7e4d7d29447817adbddvboxsync} // end namespace xml