VirtualBox

Changeset 17362 in vbox for trunk/src/VBox/Main/xml


Ignore:
Timestamp:
Mar 4, 2009 6:10:58 PM (16 years ago)
Author:
vboxsync
Message:

OVF: partial implementation of write support in XML classes.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/xml/xml.cpp

    r16538 r17362  
    44
    55/*
    6  * Copyright (C) 2007-2008 Sun Microsystems, Inc.
     6 * Copyright (C) 2007-2009 Sun Microsystems, Inc.
    77 *
    88 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    4242#include "VBox/xml.h"
    4343
     44////////////////////////////////////////////////////////////////////////////////
     45//
     46// globals
     47//
     48////////////////////////////////////////////////////////////////////////////////
    4449
    4550/**
     
    9499{
    95100
    96 //////////////////////////////////////////////////////////////////////////////
     101////////////////////////////////////////////////////////////////////////////////
     102//
    97103// Exceptions
    98 //////////////////////////////////////////////////////////////////////////////
     104//
     105////////////////////////////////////////////////////////////////////////////////
    99106
    100107LogicError::LogicError(RT_SRC_POS_DECL)
     
    111118{
    112119    if (!aErr)
    113         throw EInvalidArg (RT_SRC_POS);
     120        throw EInvalidArg(RT_SRC_POS);
    114121
    115122    char *msg = Format(aErr);
     
    148155}
    149156
    150 //////////////////////////////////////////////////////////////////////////////
     157////////////////////////////////////////////////////////////////////////////////
     158//
    151159// File Class
     160//
    152161//////////////////////////////////////////////////////////////////////////////
    153162
     
    283292}
    284293
    285 //////////////////////////////////////////////////////////////////////////////
     294////////////////////////////////////////////////////////////////////////////////
     295//
    286296// MemoryBuf Class
     297//
    287298//////////////////////////////////////////////////////////////////////////////
    288299
     
    349360}
    350361
    351 /*
    352  * GlobalLock
    353  *
    354  *
    355  */
     362////////////////////////////////////////////////////////////////////////////////
     363//
     364// GlobalLock class
     365//
     366////////////////////////////////////////////////////////////////////////////////
    356367
    357368struct GlobalLock::Data
     
    392403}
    393404
    394 /*
    395  * Node
    396  *
    397  *
    398  */
     405////////////////////////////////////////////////////////////////////////////////
     406//
     407// Node class
     408//
     409////////////////////////////////////////////////////////////////////////////////
    399410
    400411struct Node::Data
    401412{
    402413    xmlNode     *plibNode;          // != NULL if this is an element
    403     xmlAttr     *plibAttr;          // != NULL if this is an element
    404 
    405     Node     *pParent;       // NULL only for the root element
     414    xmlAttr     *plibAttr;          // != NULL if this is an attribute
     415
     416    Node        *pParent;           // NULL only for the root element
    406417    const char  *pcszName;          // points either into plibNode or plibAttr
    407418
     
    790801}
    791802
    792 /*
    793  * Document
    794  *
    795  *
    796  */
     803////////////////////////////////////////////////////////////////////////////////
     804//
     805// Document class
     806//
     807////////////////////////////////////////////////////////////////////////////////
    797808
    798809struct Document::Data
    799810{
    800     xmlDocPtr   pDocument;
    801     Node     *pRootElement;
     811    xmlDocPtr   plibDocument;
     812    Node        *pRootElement;
    802813
    803814    Data()
    804815    {
    805         pDocument = NULL;
     816        plibDocument = NULL;
    806817        pRootElement = NULL;
    807818    }
     
    814825    void reset()
    815826    {
    816         if (pDocument)
     827        if (plibDocument)
    817828        {
    818             xmlFreeDoc(pDocument);
    819             pDocument = NULL;
     829            xmlFreeDoc(plibDocument);
     830            plibDocument = NULL;
    820831        }
    821832        if (pRootElement)
     
    828839    void copyFrom(const Document::Data *p)
    829840    {
    830         if (p->pDocument)
     841        if (p->plibDocument)
    831842        {
    832             pDocument = xmlCopyDoc(p->pDocument,
    833                                    1);      // recursive == copy all
     843            plibDocument = xmlCopyDoc(p->plibDocument,
     844                                      1);      // recursive == copy all
    834845        }
    835846    }
     
    867878{
    868879    m->pRootElement = new Node();
    869     m->pRootElement->m->plibNode = xmlDocGetRootElement(m->pDocument);
     880    m->pRootElement->m->plibNode = xmlDocGetRootElement(m->plibDocument);
    870881    m->pRootElement->m->pcszName = (const char*)m->pRootElement->m->plibNode->name;
    871882
     
    873884}
    874885
     886/**
     887 * Returns the root element of the document, or NULL if the document is empty.
     888 * @return
     889 */
    875890const Node* Document::getRootElement() const
    876891{
     
    878893}
    879894
    880 /*
    881  * XmlParserBase
    882  *
    883  *
    884  */
     895/**
     896 * Creates a new element node and sets it as the root element. This will
     897 * only work if the document is empty; otherwise EDocumentNotEmpty is thrown.
     898 */
     899Node* Document::createRootElement(const char *pcszRootElementName)
     900{
     901    if (m->pRootElement)
     902        throw EDocumentNotEmpty(RT_SRC_POS);
     903
     904    m->plibDocument = xmlNewDoc((const xmlChar*)"1.0");
     905    if (!(m->pRootElement = new Node()))
     906        throw ENoMemory();
     907    Node::Data *pNodeData = m->pRootElement->m;
     908    if (!(pNodeData->plibNode = xmlNewNode(NULL,        // namespace
     909                                           (const xmlChar*)pcszRootElementName)))
     910        throw ENoMemory();
     911    pNodeData->pcszName = (const char*)pNodeData->plibNode->name;
     912
     913    return m->pRootElement;
     914}
     915
     916////////////////////////////////////////////////////////////////////////////////
     917//
     918// XmlParserBase class
     919//
     920////////////////////////////////////////////////////////////////////////////////
    885921
    886922XmlParserBase::XmlParserBase()
     
    897933}
    898934
    899 /*
    900  * XmlFileParser
    901  *
    902  *
    903  */
     935////////////////////////////////////////////////////////////////////////////////
     936//
     937// XmlFileParser class
     938//
     939////////////////////////////////////////////////////////////////////////////////
    904940
    905941struct XmlFileParser::Data
     
    931967}
    932968
    933 struct ReadContext
     969struct ReadWriteContext
    934970{
    935971    File file;
    936972    com::Utf8Str error;
    937973
    938     ReadContext(const char *pcszFilename)
    939         : file(File::Mode_Read, pcszFilename)
     974    ReadWriteContext(const char *pcszFilename)
     975        : file(File::Mode_Read, pcszFilename)     // @todo must be write for writer
    940976    {
    941977    }
     
    9691005    m->strXmlFilename = pcszFilename;
    9701006
    971     ReadContext context(pcszFilename);
     1007    ReadWriteContext context(pcszFilename);
    9721008    doc.m->reset();
    973     if (!(doc.m->pDocument = xmlCtxtReadIO(m->ctxt,
    974                                            ReadCallback,
    975                                            CloseCallback,
    976                                            &context,
    977                                            pcszFilename,
    978                                            NULL,       // encoding = auto
    979                                            XML_PARSE_NOBLANKS)))
     1009    if (!(doc.m->plibDocument = xmlCtxtReadIO(m->ctxt,
     1010                                              ReadCallback,
     1011                                              CloseCallback,
     1012                                              &context,
     1013                                              pcszFilename,
     1014                                              NULL,       // encoding = auto
     1015                                              XML_PARSE_NOBLANKS)))
    9801016        throw XmlError(xmlCtxtGetLastError(m->ctxt));
    9811017
     
    9861022int XmlFileParser::ReadCallback(void *aCtxt, char *aBuf, int aLen)
    9871023{
    988     ReadContext *pContext = static_cast<ReadContext*>(aCtxt);
     1024    ReadWriteContext *pContext = static_cast<ReadWriteContext*>(aCtxt);
    9891025
    9901026    /* To prevent throwing exceptions while inside libxml2 code, we catch
     
    10101046}
    10111047
     1048////////////////////////////////////////////////////////////////////////////////
     1049//
     1050// XmlFileWriter class
     1051//
     1052////////////////////////////////////////////////////////////////////////////////
     1053
     1054struct XmlFileWriter::Data
     1055{
     1056    Document *pDoc;
     1057};
     1058
     1059XmlFileWriter::XmlFileWriter(Document &doc)
     1060{
     1061    m = new Data();
     1062    m->pDoc = &doc;
     1063}
     1064
     1065XmlFileWriter::~XmlFileWriter()
     1066{
     1067    delete m;
     1068}
     1069
     1070int XmlFileWriter::WriteCallback(void *aCtxt, const char *aBuf, int aLen)
     1071{
     1072    ReadWriteContext *pContext = static_cast<ReadWriteContext*>(aCtxt);
     1073
     1074    /* To prevent throwing exceptions while inside libxml2 code, we catch
     1075     * them and forward to our level using a couple of variables. */
     1076    try
     1077    {
     1078        return pContext->file.write(aBuf, aLen);
     1079    }
     1080    catch (const xml::EIPRTFailure &err) { pContext->setError(err); }
     1081    catch (const xml::Error &err) { pContext->setError(err); }
     1082    catch (const std::exception &err) { pContext->setError(err); }
     1083    catch (...) { pContext->setError(xml::LogicError(RT_SRC_POS)); }
     1084
     1085    return -1 /* failure */;
     1086}
     1087
     1088int XmlFileWriter::CloseCallback(void *aCtxt)
     1089{
     1090    /// @todo to be written
     1091
     1092    return -1;
     1093}
     1094
     1095void XmlFileWriter::write(const char *pcszFilename)
     1096{
     1097    ReadWriteContext context(pcszFilename);
     1098
     1099    GlobalLock lock();
     1100
     1101    /* serialize to the stream */
     1102    xmlIndentTreeOutput = 1;
     1103    xmlTreeIndentString = "  ";
     1104    xmlSaveNoEmptyTags = 0;
     1105
     1106    xmlSaveCtxtPtr saveCtxt;
     1107    if (!(saveCtxt = xmlSaveToIO(WriteCallback,
     1108                                 CloseCallback,
     1109                                 &context,
     1110                                 NULL,
     1111                                 XML_SAVE_FORMAT)))
     1112        throw xml::LogicError(RT_SRC_POS);
     1113
     1114    long rc = xmlSaveDoc(saveCtxt, m->pDoc->m->plibDocument);
     1115    if (rc == -1)
     1116    {
     1117        /* look if there was a forwared exception from the lower level */
     1118//         if (m->trappedErr.get() != NULL)
     1119//             m->trappedErr->rethrow();
     1120
     1121        /* there must be an exception from the Output implementation,
     1122         * otherwise the save operation must always succeed. */
     1123        throw xml::LogicError(RT_SRC_POS);
     1124    }
     1125
     1126    xmlSaveClose(saveCtxt);
     1127}
     1128
    10121129
    10131130} // end namespace xml
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette