VirtualBox

Changeset 67675 in vbox


Ignore:
Timestamp:
Jun 28, 2017 10:28:30 PM (8 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
116490
Message:

iprt/xml: Added a RTCString writer class.

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/iprt/cpp/xml.h

    r64993 r67675  
    955955    friend class XmlFileParser;
    956956    friend class XmlMemWriter;
     957    friend class XmlStringWriter;
    957958    friend class XmlFileWriter;
    958959
     
    10141015};
    10151016
    1016 /*
    1017  * XmlMemParser
    1018  *
    1019  */
    1020 
     1017/**
     1018 * XmlMemWriter
     1019 */
    10211020class RT_DECL_CLASS XmlMemWriter
    10221021{
     
    10311030};
    10321031
    1033 /*
     1032
     1033/**
     1034 * XmlStringWriter - writes the XML to an RTCString instance.
     1035 */
     1036class RT_DECL_CLASS XmlStringWriter
     1037{
     1038public:
     1039    XmlStringWriter();
     1040
     1041    int write(const Document &rDoc, RTCString *pStrDst);
     1042
     1043private:
     1044    static int WriteCallbackForSize(void *pvUser, const char *pachBuf, int cbToWrite);
     1045    static int WriteCallbackForReal(void *pvUser, const char *pachBuf, int cbToWrite);
     1046    static int CloseCallback(void *pvUser);
     1047
     1048    /** Pointer to the destination string while we're in the write() call.   */
     1049    RTCString  *m_pStrDst;
     1050    /** Set by WriteCallback if we cannot grow the destination string. */
     1051    bool        m_fOutOfMemory;
     1052};
     1053
     1054
     1055/**
    10341056 * XmlFileWriter
    1035  *
    1036  */
    1037 
     1057 */
    10381058class RT_DECL_CLASS XmlFileWriter
    10391059{
  • trunk/src/VBox/Runtime/r3/xml.cpp

    r65597 r67675  
    18471847}
    18481848
     1849
     1850////////////////////////////////////////////////////////////////////////////////
     1851//
     1852// XmlStringWriter class
     1853//
     1854////////////////////////////////////////////////////////////////////////////////
     1855
     1856XmlStringWriter::XmlStringWriter()
     1857  : m_pStrDst(NULL), m_fOutOfMemory(false)
     1858{
     1859}
     1860
     1861int XmlStringWriter::write(const Document &rDoc, RTCString *pStrDst)
     1862{
     1863    /*
     1864     * Clear the output string and take the global libxml2 lock so we can
     1865     * safely configure the output formatting.
     1866     */
     1867    pStrDst->setNull();
     1868
     1869    GlobalLock lock;
     1870
     1871    xmlIndentTreeOutput = 1;
     1872    xmlTreeIndentString = "  ";
     1873    xmlSaveNoEmptyTags  = 0;
     1874
     1875    /*
     1876     * Do a pass to calculate the size.
     1877     */
     1878    size_t cbOutput = 1; /* zero term */
     1879
     1880    xmlSaveCtxtPtr pSaveCtx= xmlSaveToIO(WriteCallbackForSize, CloseCallback, &cbOutput, NULL /*pszEncoding*/, XML_SAVE_FORMAT);
     1881    if (!pSaveCtx)
     1882        return VERR_NO_MEMORY;
     1883
     1884    long rcXml = xmlSaveDoc(pSaveCtx, rDoc.m->plibDocument);
     1885    xmlSaveClose(pSaveCtx);
     1886    if (rcXml == -1)
     1887        return VERR_GENERAL_FAILURE;
     1888
     1889    /*
     1890     * Try resize the string.
     1891     */
     1892    int rc = pStrDst->reserveNoThrow(cbOutput);
     1893    if (RT_SUCCESS(rc))
     1894    {
     1895        /*
     1896         * Do the real run where we feed output to the string.
     1897         */
     1898        m_pStrDst      = pStrDst;
     1899        m_fOutOfMemory = false;
     1900        pSaveCtx = xmlSaveToIO(WriteCallbackForReal, CloseCallback, this, NULL /*pszEncoding*/, XML_SAVE_FORMAT);
     1901        if (pSaveCtx)
     1902        {
     1903            rcXml = xmlSaveDoc(pSaveCtx, rDoc.m->plibDocument);
     1904            xmlSaveClose(pSaveCtx);
     1905            m_pStrDst = NULL;
     1906            if (rcXml != -1)
     1907            {
     1908                if (!m_fOutOfMemory)
     1909                    return VINF_SUCCESS;
     1910
     1911                rc = VERR_NO_STR_MEMORY;
     1912            }
     1913            else
     1914                rc = VERR_GENERAL_FAILURE;
     1915        }
     1916        else
     1917            rc = VERR_NO_MEMORY;
     1918        pStrDst->setNull();
     1919        m_pStrDst = NULL;
     1920    }
     1921    return rc;
     1922}
     1923
     1924/*static*/ int XmlStringWriter::WriteCallbackForSize(void *pvUser, const char *pachBuf, int cbToWrite)
     1925{
     1926    if (cbToWrite > 0)
     1927        *(size_t *)pvUser += (unsigned)cbToWrite;
     1928    RT_NOREF(pachBuf);
     1929    return cbToWrite;
     1930}
     1931
     1932/*static*/ int XmlStringWriter::WriteCallbackForReal(void *pvUser, const char *pachBuf, int cbToWrite)
     1933{
     1934    XmlStringWriter *pThis = static_cast<XmlStringWriter*>(pvUser);
     1935    if (!pThis->m_fOutOfMemory)
     1936    {
     1937        if (cbToWrite > 0)
     1938        {
     1939            try
     1940            {
     1941                pThis->m_pStrDst->append(pachBuf, (size_t)cbToWrite);
     1942            }
     1943            catch (std::bad_alloc)
     1944            {
     1945                pThis->m_fOutOfMemory = true;
     1946                return -1;
     1947            }
     1948        }
     1949        return cbToWrite;
     1950    }
     1951    return -1; /* failure */
     1952}
     1953
     1954int XmlStringWriter::CloseCallback(void *pvUser)
     1955{
     1956    /* Nothing to do here. */
     1957    RT_NOREF(pvUser);
     1958    return 0;
     1959}
     1960
     1961
     1962
    18491963////////////////////////////////////////////////////////////////////////////////
    18501964//
Note: See TracChangeset for help on using the changeset viewer.

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