VirtualBox

Changeset 21073 in vbox for trunk/include


Ignore:
Timestamp:
Jun 30, 2009 3:01:09 PM (15 years ago)
Author:
vboxsync
Message:

Main: move libxml2 to IPRT unconditionally (remove VBOX_WITH_LIBXML2_IN_VBOXRT); move xml classes to IPRT; introduce IPRT ministring class as base for both Utf8Str and xml.cpp, with better performance (remembers string lengths and can thus use memcpy instead of strdup); introduce some Utf8Str helpers to avoid string buffer hacks in Main code

Location:
trunk/include/VBox
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/com/string.h

    r18589 r21073  
    4949#include "VBox/com/assert.h"
    5050
    51 #include <iprt/string.h>
    5251#include <iprt/cpputils.h>
    5352#include <iprt/alloc.h>
     53#include <iprt/ministring_cpp.h>
    5454
    5555namespace com
     
    153153    }
    154154
    155     bool operator == (const Bstr &that) const { return !compare (that.bstr); }
    156     bool operator != (const Bstr &that) const { return !!compare (that.bstr); }
    157     bool operator == (CBSTR that) const { return !compare (that); }
    158     bool operator == (BSTR that) const { return !compare (that); }
     155    bool operator==(const Bstr &that) const { return !compare (that.bstr); }
     156    bool operator!=(const Bstr &that) const { return !!compare (that.bstr); }
     157    bool operator==(CBSTR that) const { return !compare (that); }
     158    bool operator==(BSTR that) const { return !compare (that); }
    159159
    160160#if defined (VBOX_WITH_XPCOM)
    161     bool operator != (const wchar_t *that) const
     161    bool operator!=(const wchar_t *that) const
    162162    {
    163163        AssertCompile (sizeof (wchar_t) == sizeof (OLECHAR));
    164164        return !!compare ((CBSTR) that);
    165165    }
    166     bool operator == (const wchar_t *that) const
     166    bool operator==(const wchar_t *that) const
    167167    {
    168168        AssertCompile (sizeof (wchar_t) == sizeof (OLECHAR));
     
    171171#endif
    172172
    173     bool operator != (CBSTR that) const { return !!compare (that); }
    174     bool operator != (BSTR that) const { return !!compare (that); }
    175     bool operator < (const Bstr &that) const { return compare (that.bstr) < 0; }
    176     bool operator < (CBSTR that) const { return compare (that) < 0; }
    177     bool operator < (BSTR that) const { return compare (that) < 0; }
     173    bool operator!=(CBSTR that) const { return !!compare (that); }
     174    bool operator!=(BSTR that) const { return !!compare (that); }
     175    bool operator<(const Bstr &that) const { return compare (that.bstr) < 0; }
     176    bool operator<(CBSTR that) const { return compare (that) < 0; }
     177    bool operator<(BSTR that) const { return compare (that) < 0; }
    178178#if defined (VBOX_WITH_XPCOM)
    179     bool operator < (const wchar_t *that) const
     179    bool operator<(const wchar_t *that) const
    180180    {
    181181        AssertCompile (sizeof (wchar_t) == sizeof (OLECHAR));
     
    303303
    304304/* symmetric compare operators */
    305 inline bool operator== (CBSTR l, const Bstr &r) { return r.operator== (l); }
    306 inline bool operator!= (CBSTR l, const Bstr &r) { return r.operator!= (l); }
    307 inline bool operator== (BSTR l, const Bstr &r) { return r.operator== (l); }
    308 inline bool operator!= (BSTR l, const Bstr &r) { return r.operator!= (l); }
     305inline bool operator==(CBSTR l, const Bstr &r) { return r.operator== (l); }
     306inline bool operator!=(CBSTR l, const Bstr &r) { return r.operator!= (l); }
     307inline bool operator==(BSTR l, const Bstr &r) { return r.operator== (l); }
     308inline bool operator!=(BSTR l, const Bstr &r) { return r.operator!= (l); }
    309309
    310310////////////////////////////////////////////////////////////////////////////////
     
    324324 *    afterwards.
    325325 */
    326 class Utf8Str
     326class Utf8Str : public ministring
    327327{
    328328public:
    329329
    330     enum CaseSensitivity
    331     {
    332         CaseSensitive,
    333         CaseInsensitive
    334     };
    335 
    336     typedef char *String;
    337     typedef const char *ConstString;
    338 
    339     Utf8Str () : str (NULL) {}
    340 
    341     Utf8Str (const Utf8Str &that) : str (NULL) { raw_copy (str, that.str); }
    342     Utf8Str (const char *that) : str (NULL) { raw_copy (str, that); }
    343 
    344     Utf8Str (const Bstr &that) : str (NULL) { raw_copy (str, that); }
    345     Utf8Str (CBSTR that) : str (NULL) { raw_copy (str, that); }
    346 
    347     /** Shortcut that calls #alloc(aSize) right after object creation. */
    348     Utf8Str (size_t aSize) : str (NULL) { alloc(aSize); }
    349 
    350     virtual ~Utf8Str () { setNull(); }
    351 
    352     Utf8Str &operator = (const Utf8Str &that) { safe_assign (that.str); return *this; }
    353     Utf8Str &operator = (const char *that) { safe_assign (that); return *this; }
    354 
    355     Utf8Str &operator = (const Bstr &that)
    356     {
    357         setNull();
    358         raw_copy (str, that);
    359         return *this;
    360     }
    361     Utf8Str &operator = (CBSTR that)
    362     {
    363         setNull();
    364         raw_copy (str, that);
    365         return *this;
    366     }
    367 
    368     Utf8Str &setNull()
    369     {
    370         if (str)
    371         {
    372 #if !defined (VBOX_WITH_XPCOM)
    373             ::RTStrFree (str);
    374 #else
    375             nsMemory::Free (str);
    376 #endif
    377             str = NULL;
    378         }
    379         return *this;
    380     }
    381 
    382     Utf8Str &setNullIfEmpty()
    383     {
    384         if (str && *str == 0)
    385         {
    386 #if !defined (VBOX_WITH_XPCOM)
    387             ::RTStrFree (str);
    388 #else
    389             nsMemory::Free (str);
    390 #endif
    391             str = NULL;
    392         }
    393         return *this;
    394     }
    395 
    396     /**
    397      *  Allocates memory for a string capable to store \a aSize - 1 bytes (not characters!);
    398      *  in other words, aSize includes the terminating zero character. If \a aSize
    399      *  is zero, or if a memory allocation error occurs, this object will become null.
    400      */
    401     Utf8Str &alloc (size_t aSize)
    402     {
    403         setNull();
    404         if (aSize)
    405         {
    406 #if !defined (VBOX_WITH_XPCOM)
    407             str = (char *) ::RTMemTmpAlloc (aSize);
    408 #else
    409             str = (char *) nsMemory::Alloc (aSize);
    410 #endif
    411             if (str)
    412                 str [0] = 0;
    413         }
    414         return *this;
    415     }
    416 
    417     void append(const Utf8Str &that)
    418     {
    419         size_t cbThis = length();
    420         size_t cbThat = that.length();
    421 
    422         if (cbThat)
    423         {
    424             size_t cbBoth = cbThis + cbThat + 1;
    425 
    426             // @todo optimize with realloc() once the memory management is fixed
    427             char *pszTemp;
    428 #if !defined (VBOX_WITH_XPCOM)
    429             pszTemp = (char*)::RTMemTmpAlloc(cbBoth);
    430 #else
    431             pszTemp = (char*)nsMemory::Alloc(cbBoth);
    432 #endif
    433             if (str)
    434             {
    435                 memcpy(pszTemp, str, cbThis);
    436                 setNull();
    437             }
    438             if (that.str)
    439                 memcpy(pszTemp + cbThis, that.str, cbThat);
    440             pszTemp[cbThis + cbThat] = '\0';
    441 
    442             str = pszTemp;
    443         }
    444     }
    445 
    446     int compare (const char *pcsz, CaseSensitivity cs = CaseSensitive) const
    447     {
    448         if (str == pcsz)
    449             return 0;
    450         if (str == NULL)
    451             return -1;
    452         if (pcsz == NULL)
    453             return 1;
    454 
    455         if (cs == CaseSensitive)
    456             return ::RTStrCmp(str, pcsz);
    457         else
    458             return ::RTStrICmp(str, pcsz);
    459     }
    460 
    461     int compare (const Utf8Str &that, CaseSensitivity cs = CaseSensitive) const
    462     {
    463         return compare (that.str, cs);
    464     }
    465 
    466     bool operator == (const Utf8Str &that) const { return !compare (that); }
    467     bool operator != (const Utf8Str &that) const { return !!compare (that); }
    468     bool operator == (const char *that) const { return !compare (that); }
    469     bool operator != (const char *that) const { return !!compare (that); }
    470     bool operator < (const Utf8Str &that) const { return compare (that) < 0; }
    471     bool operator < (const char *that) const { return compare (that) < 0; }
    472 
    473     bool endsWith (const Utf8Str &that, CaseSensitivity cs = CaseSensitive) const
    474     {
    475         if (isNull() || that.isNull())
    476             return false;
    477 
    478         size_t l1 = length();
    479         size_t l2 = that.length();
    480         if (l1 < l2)
    481             return false;
    482 
    483         size_t l = l1 - l2;
    484         if (cs == CaseSensitive)
    485             return ::RTStrCmp(&str[l], that.str) == 0;
    486         else
    487             return ::RTStrICmp(&str[l], that.str) == 0;
    488     }
    489 
    490     bool startsWith (const Utf8Str &that, CaseSensitivity cs = CaseSensitive) const
    491     {
    492         if (isNull() || that.isNull())
    493             return false;
    494 
    495         size_t l1 = length();
    496         size_t l2 = that.length();
    497         if (l1 < l2)
    498             return false;
    499 
    500         if (cs == CaseSensitive)
    501             return ::RTStrNCmp(str, that.str, l2) == 0;
    502         else
    503             return ::RTStrNICmp(str, that.str, l2) == 0;
    504     }
    505 
    506     bool contains (const Utf8Str &that, CaseSensitivity cs = CaseSensitive) const
    507     {
    508         if (cs == CaseSensitive)
    509             return ::RTStrStr (str, that.str) != NULL;
    510         else
    511             return ::RTStrIStr (str, that.str) != NULL;
    512     }
    513 
    514     Utf8Str& toLower()
    515     {
    516         if (isEmpty())
    517             return *this;
    518 
    519         ::RTStrToLower(str);
    520 
    521         return *this;
    522     }
    523 
    524     Utf8Str& toUpper()
    525     {
    526         if (isEmpty())
    527             return *this;
    528 
    529         ::RTStrToUpper(str);
    530 
    531         return *this;
    532     }
    533 
    534     bool isNull() const { return str == NULL; }
    535     operator bool() const { return !isNull(); }
    536 
    537     bool isEmpty() const { return isNull() || *str == 0; }
    538 
    539     size_t length() const { return isNull() ? 0 : ::strlen (str); }
    540 
    541     /** Intended to to pass instances as input (|char *|) parameters to methods. */
    542     operator const char *() const { return str; }
    543 
    544     /** The same as operator const char *(), but for situations where the compiler
    545         cannot typecast implicitly (for example, in printf() argument list). */
    546     const char *raw() const { return str; }
    547 
    548     /** The same as operator const char *(), but for situations where the compiler
    549         cannot typecast implicitly (for example, in printf() argument list). */
    550     const char *c_str() const { return str; }
    551 
    552     /**
    553      *  Returns a non-const raw pointer that allows to modify the string directly.
    554      *  @warning
    555      *      Be sure not to modify data beyond the allocated memory! The
    556      *      guaranteed size of the allocated memory is at least #length()
    557      *      bytes after creation and after every assignment operation.
    558      */
    559     char *mutableRaw() { return str; }
     330    Utf8Str() {}
     331
     332    Utf8Str(const Utf8Str &that)
     333        : ministring(that)
     334    {}
     335
     336    Utf8Str(const char *that)
     337        : ministring(that)
     338    {}
     339
     340    Utf8Str(const Bstr &that)
     341    {
     342        copyFrom(that);
     343    }
     344
     345    Utf8Str(CBSTR that)
     346    {
     347        copyFrom(that);
     348    }
     349
     350    Utf8Str& operator=(const Utf8Str &that)
     351    {
     352        ministring::operator=(that);
     353        return *this;
     354    }
     355
     356    Utf8Str& operator=(const char *that)
     357    {
     358        ministring::operator=(that);
     359        return *this;
     360    }
     361
     362    Utf8Str& operator=(const Bstr &that)
     363    {
     364        cleanup();
     365        copyFrom(that);
     366        return *this;
     367    }
     368
     369    Utf8Str& operator=(CBSTR that)
     370    {
     371        cleanup();
     372        copyFrom(that);
     373        return *this;
     374    }
    560375
    561376    /**
     
    564379     *  caller.
    565380     */
    566     const Utf8Str &cloneTo (char **pstr) const
     381    const Utf8Str& cloneTo(char **pstr) const
    567382    {
    568383        if (pstr)
    569         {
    570             *pstr = NULL;
    571             raw_copy (*pstr, str);
    572         }
     384            *pstr = RTStrDup(m_psz);
    573385        return *this;
    574386    }
     
    582394     *  string.
    583395     */
    584     Utf8Str &detachTo (char **pstr)
    585     {
    586         *pstr = str;
    587         str = NULL;
     396    Utf8Str& detachTo(char **pstr)
     397    {
     398        *pstr = m_psz;
     399        m_psz = NULL;
     400        m_cbAllocated = 0;
     401        m_cbLength = 0;
    588402        return *this;
    589403    }
     
    594408     *  caller.
    595409     */
    596     const Utf8Str &cloneTo (BSTR *pstr) const
     410    const Utf8Str& cloneTo(BSTR *pstr) const
    597411    {
    598412        if (pstr)
    599413        {
    600414            *pstr = NULL;
    601             Bstr::raw_copy (*pstr, str);
     415            Bstr::raw_copy(*pstr, m_psz);
    602416        }
    603417        return *this;
     
    623437
    624438    /**
    625      * Attempts to convert the member string into an 32-bit integer.
     439     * Returns true if "this" ends with "that".
     440     * @param that
     441     * @param cs
     442     * @return
     443     */
     444    bool endsWith(const Utf8Str &that, CaseSensitivity cs = CaseSensitive) const;
     445
     446    /**
     447     * Returns true if "this" begins with "that".
     448     * @return
     449     */
     450    bool startsWith(const Utf8Str &that, CaseSensitivity cs = CaseSensitive) const;
     451
     452    /**
     453     * Returns true if "this" contains "that" (strstr).
     454     * @param that
     455     * @param cs
     456     * @return
     457     */
     458    bool contains(const Utf8Str &that, CaseSensitivity cs = CaseSensitive) const;
     459
     460    /**
     461     * Converts "this" to lower case by calling RTStrToLower().
     462     * @return
     463     */
     464    Utf8Str& toLower();
     465
     466    /**
     467     * Converts "this" to upper case by calling RTStrToUpper().
     468     * @return
     469     */
     470    Utf8Str& toUpper();
     471
     472    /**
     473     * Removes a trailing slash from the member string, if present.
     474     * Calls RTPathStripTrailingSlash() without having to mess with mutableRaw().
     475     */
     476    void stripTrailingSlash();
     477
     478    /**
     479     * Removes a trailing filename from the member string, if present.
     480     * Calls RTPathStripFilename() without having to mess with mutableRaw().
     481     */
     482    void stripFilename();
     483
     484    /**
     485     * Removes a trailing file name extension from the member string, if present.
     486     * Calls RTPathStripExt() without having to mess with mutableRaw().
     487     */
     488    void stripExt();
     489
     490    /**
     491     * Attempts to convert the member string into a 32-bit integer.
    626492     *
    627493     * @returns 32-bit unsigned number on success.
     
    630496    int toInt32() const
    631497    {
    632         return RTStrToInt32(str);
     498        return RTStrToInt32(m_psz);
    633499    }
    634500
     
    641507    int toUInt32() const
    642508    {
    643         return RTStrToUInt32(str);
     509        return RTStrToUInt32(m_psz);
    644510    }
    645511
     
    652518    int64_t toInt64() const
    653519    {
    654         return RTStrToInt64(str);
     520        return RTStrToInt64(m_psz);
    655521    }
    656522
     
    663529    uint64_t toUInt64() const
    664530    {
    665         return RTStrToUInt64(str);
     531        return RTStrToUInt64(m_psz);
    666532    }
    667533
     
    684550     *  Takes the ownership of the returned data.
    685551     */
    686     char **asOutParam() { setNull(); return &str; }
     552    char **asOutParam()
     553    {
     554        cleanup();
     555        return &m_psz;
     556    }
    687557
    688558    /**
     
    693563protected:
    694564
    695     void safe_assign (const char *s)
    696     {
    697         if (str != s)
    698         {
    699             setNull();
    700             raw_copy (str, s);
    701         }
    702     }
    703 
    704     inline static void raw_copy (char *&ls, const char *rs)
    705     {
    706         if (rs)
    707 #if !defined (VBOX_WITH_XPCOM)
    708             ::RTStrDupEx (&ls, rs);
    709 #else
    710             ls = (char *) nsMemory::Clone (rs, strlen (rs) + 1);
    711 #endif
    712     }
    713 
    714     inline static void raw_copy (char *&ls, CBSTR rs)
    715     {
    716         if (rs)
    717         {
    718 #if !defined (VBOX_WITH_XPCOM)
    719             ::RTUtf16ToUtf8 ((PRTUTF16) rs, &ls);
    720 #else
    721             char *s = NULL;
    722             ::RTUtf16ToUtf8 ((PRTUTF16) rs, &s);
    723             raw_copy (ls, s);
    724             ::RTStrFree (s);
    725 #endif
    726         }
    727     }
    728 
    729     char *str;
     565    /**
     566     * As with the ministring::copyFrom() variants, this unconditionally
     567     * sets the members to a copy of the given other strings and makes
     568     * no assumptions about previous contents. This can therefore be used
     569     * both in copy constructors, when member variables have no defined
     570     * value, and in assignments after having called cleanup().
     571     *
     572     * This variant converts from a UTF-16 string, most probably from
     573     * a Bstr assignment.
     574     *
     575     * @param rs
     576     */
     577    void copyFrom(CBSTR s)
     578    {
     579        if (s)
     580        {
     581            RTUtf16ToUtf8((PRTUTF16)s, &m_psz);
     582            m_cbLength = strlen(m_psz);             // TODO optimize by using a different RTUtf* function
     583            m_cbAllocated = m_cbLength + 1;
     584        }
     585        else
     586        {
     587            m_cbLength = 0;
     588            m_cbAllocated = 0;
     589            m_psz = NULL;
     590        }
     591    }
    730592
    731593    friend class Bstr; /* to access our raw_copy() */
    732594};
    733 
    734 // symmetric compare operators
    735 inline bool operator== (const char *l, const Utf8Str &r) { return r.operator== (l); }
    736 inline bool operator!= (const char *l, const Utf8Str &r) { return r.operator!= (l); }
    737595
    738596// work around error C2593 of the stupid MSVC 7.x ambiguity resolver
     
    760618}
    761619
    762 inline const Bstr &Bstr::cloneTo (char **pstr) const
    763 {
    764     if (pstr) {
    765         *pstr = NULL;
    766         Utf8Str::raw_copy (*pstr, bstr);
     620inline const Bstr& Bstr::cloneTo(char **pstr) const
     621{
     622    if (pstr)
     623    {
     624        Utf8Str ustr(*this);
     625        ustr.detachTo(pstr);
    767626    }
    768627    return *this;
  • trunk/include/VBox/settings.h

    r16560 r21073  
    3131#define ___VBox_settings_h
    3232
     33#include <limits>
     34
    3335#include <iprt/cdefs.h>
    3436#include <iprt/cpputils.h>
    35 #include <iprt/string.h>
    36 
    37 #include <list>
    38 #include <memory>
    39 #include <limits>
    40 
    4137#include <iprt/time.h>
     38#include <iprt/xml_cpp.h>
    4239
    4340#include <VBox/com/Guid.h>
    44 
    45 #include <VBox/xml.h>
    46 
    47 // #include <stdarg.h>
    4841
    4942/* these conflict with numeric_digits<>::min and max */
  • trunk/include/VBox/xml.h

    r19530 r21073  
    1 /** @file
    2  * VirtualBox XML helper APIs.
    3  */
    4 
    5 /*
    6  * Copyright (C) 2007-2008 Sun Microsystems, Inc.
    7  *
    8  * This file is part of VirtualBox Open Source Edition (OSE), as
    9  * available from http://www.virtualbox.org. This file is free software;
    10  * you can redistribute it and/or modify it under the terms of the GNU
    11  * General Public License (GPL) as published by the Free Software
    12  * Foundation, in version 2 as it comes in the "COPYING" file of the
    13  * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
    14  * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
    15  *
    16  * The contents of this file may alternatively be used under the terms
    17  * of the Common Development and Distribution License Version 1.0
    18  * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
    19  * VirtualBox OSE distribution, in which case the provisions of the
    20  * CDDL are applicable instead of those of the GPL.
    21  *
    22  * You may elect to license modified versions of this file under the
    23  * terms and conditions of either the GPL or the CDDL or both.
    24  *
    25  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
    26  * Clara, CA 95054 USA or visit http://www.sun.com if you need
    27  * additional information or have any questions.
    28  */
    29 
    30 #ifndef ___VBox_vboxxml_h
    31 #define ___VBox_vboxxml_h
    32 
    33 #ifndef IN_RING3
    34 # error "There are no XML APIs available in Ring-0 Context!"
    35 #else /* IN_RING3 */
    36 
    37 /** @def IN_VBOXXML_R3
    38  * Used to indicate whether we're inside the same link module as the
    39  * XML Settings File Manipulation API.
    40  *
    41  * @todo should go to a separate common include together with VBOXXML2_CLASS
    42  * once there becomes more than one header in the VBoxXML2 library.
    43  */
    44 #ifdef DOXYGEN_RUNNING
    45 # define IN_VBOXXML_R3
    46 #endif
    47 
    48 /** @def VBOXXML_CLASS
    49  * Class export/import wrapper. */
    50 #ifdef IN_VBOXXML_R3
    51 # define VBOXXML_CLASS DECLEXPORT_CLASS
    52 #else
    53 # define VBOXXML_CLASS DECLIMPORT_CLASS
    54 #endif
    55 
    56 /*
    57  * Shut up MSVC complaining that auto_ptr[_ref] template instantiations (as a
    58  * result of private data member declarations of some classes below) need to
    59  * be exported too to in order to be accessible by clients.
    60  *
    61  * The alternative is to instantiate a template before the data member
    62  * declaration with the VBOXXML_CLASS prefix, but the standard disables
    63  * explicit instantiations in a foreign namespace. In other words, a declaration
    64  * like:
    65  *
    66  *   template class VBOXXML_CLASS std::auto_ptr <Data>;
    67  *
    68  * right before the member declaration makes MSVC happy too, but this is not a
    69  * valid C++ construct (and G++ spits it out). So, for now we just disable the
    70  * warning and will come back to this problem one day later.
    71  *
    72  * We also disable another warning (4275) saying that a DLL-exported class
    73  * inherits form a non-DLL-exported one (e.g. settings::ENoMemory ->
    74  * std::bad_alloc). I can't get how it can harm yet.
    75  */
    76 #if defined(_MSC_VER)
    77 #pragma warning (disable:4251)
    78 #pragma warning (disable:4275)
    79 #endif
    80 
    81 /* Forwards */
    82 typedef struct _xmlParserInput xmlParserInput;
    83 typedef xmlParserInput *xmlParserInputPtr;
    84 typedef struct _xmlParserCtxt xmlParserCtxt;
    85 typedef xmlParserCtxt *xmlParserCtxtPtr;
    86 typedef struct _xmlError xmlError;
    87 typedef xmlError *xmlErrorPtr;
    88 
    89 namespace xml
    90 {
    91 
    92 // Little string class for XML only
    93 //////////////////////////////////////////////////////////////////////////////
    94 
    95 class ministring
    96 {
    97 public:
    98     ministring()
    99         : m_psz(NULL)
    100     {
    101     }
    102 
    103     ministring(const ministring &s)
    104         : m_psz(NULL)
    105     {
    106         copyFrom(s.c_str());
    107     }
    108 
    109     ministring(const char *pcsz)
    110         : m_psz(NULL)
    111     {
    112         copyFrom(pcsz);
    113     }
    114 
    115     ~ministring()
    116     {
    117         cleanup();
    118     }
    119 
    120     void operator=(const char *pcsz)
    121     {
    122         cleanup();
    123         copyFrom(pcsz);
    124     }
    125 
    126     void operator=(const ministring &s)
    127     {
    128         cleanup();
    129         copyFrom(s.c_str());
    130     }
    131 
    132     const char* c_str() const
    133     {
    134         return m_psz;
    135     }
    136 
    137 private:
    138     void cleanup()
    139     {
    140         if (m_psz)
    141         {
    142             RTStrFree(m_psz);
    143             m_psz = NULL;
    144         }
    145     }
    146 
    147     void copyFrom(const char *pcsz)
    148     {
    149         if (pcsz)
    150             m_psz = RTStrDup(pcsz);
    151     }
    152 
    153 
    154     char *m_psz;
    155 };
    156 
    157 // Exceptions
    158 //////////////////////////////////////////////////////////////////////////////
    159 
    160 /**
    161  * Base exception class.
    162  */
    163 class VBOXXML_CLASS Error : public std::exception
    164 {
    165 public:
    166 
    167     Error(const char *pcszMessage)
    168         : m_pcsz(NULL)
    169     {
    170         copyFrom(pcszMessage);
    171     }
    172 
    173     Error(const Error &s)
    174         : std::exception(s)
    175     {
    176         copyFrom(s.what());
    177     }
    178 
    179     virtual ~Error() throw()
    180     {
    181         cleanup();
    182     }
    183 
    184     void operator=(const Error &s)
    185     {
    186         cleanup();
    187         copyFrom(s.what());
    188     }
    189 
    190     void setWhat(const char *pcszMessage)
    191     {
    192         cleanup();
    193         copyFrom(pcszMessage);
    194     }
    195 
    196     virtual const char* what() const throw()
    197     {
    198         return m_pcsz;
    199     }
    200 
    201 private:
    202     Error() {};     // hide the default constructor to make sure the extended one above is always used
    203 
    204     void cleanup()
    205     {
    206         if (m_pcsz)
    207         {
    208             RTStrFree(m_pcsz);
    209             m_pcsz = NULL;
    210         }
    211     }
    212 
    213     void copyFrom(const char *pcszMessage)
    214     {
    215         if (pcszMessage)
    216             m_pcsz = RTStrDup(pcszMessage);
    217     }
    218 
    219     char *m_pcsz;
    220 };
    221 
    222 class VBOXXML_CLASS LogicError : public Error
    223 {
    224 public:
    225 
    226     LogicError(const char *aMsg = NULL)
    227         : xml::Error(aMsg)
    228     {}
    229 
    230     LogicError(RT_SRC_POS_DECL);
    231 };
    232 
    233 class VBOXXML_CLASS RuntimeError : public Error
    234 {
    235 public:
    236 
    237     RuntimeError(const char *aMsg = NULL)
    238         : xml::Error(aMsg)
    239     {}
    240 };
    241 
    242 class VBOXXML_CLASS XmlError : public RuntimeError
    243 {
    244 public:
    245     XmlError(xmlErrorPtr aErr);
    246 
    247     static char *Format(xmlErrorPtr aErr);
    248 };
    249 
    250 // Logical errors
    251 //////////////////////////////////////////////////////////////////////////////
    252 
    253 class VBOXXML_CLASS ENotImplemented : public LogicError
    254 {
    255 public:
    256     ENotImplemented(const char *aMsg = NULL) : LogicError(aMsg) {}
    257     ENotImplemented(RT_SRC_POS_DECL) : LogicError(RT_SRC_POS_ARGS) {}
    258 };
    259 
    260 class VBOXXML_CLASS EInvalidArg : public LogicError
    261 {
    262 public:
    263     EInvalidArg(const char *aMsg = NULL) : LogicError(aMsg) {}
    264     EInvalidArg(RT_SRC_POS_DECL) : LogicError(RT_SRC_POS_ARGS) {}
    265 };
    266 
    267 class VBOXXML_CLASS EDocumentNotEmpty : public LogicError
    268 {
    269 public:
    270     EDocumentNotEmpty(const char *aMsg = NULL) : LogicError(aMsg) {}
    271     EDocumentNotEmpty(RT_SRC_POS_DECL) : LogicError(RT_SRC_POS_ARGS) {}
    272 };
    273 
    274 class VBOXXML_CLASS ENodeIsNotElement : public LogicError
    275 {
    276 public:
    277     ENodeIsNotElement(const char *aMsg = NULL) : LogicError(aMsg) {}
    278     ENodeIsNotElement(RT_SRC_POS_DECL) : LogicError(RT_SRC_POS_ARGS) {}
    279 };
    280 
    281 // Runtime errors
    282 //////////////////////////////////////////////////////////////////////////////
    283 
    284 class VBOXXML_CLASS ENoMemory : public RuntimeError, public std::bad_alloc
    285 {
    286 public:
    287     ENoMemory(const char *aMsg = NULL) : RuntimeError (aMsg) {}
    288     virtual ~ENoMemory() throw() {}
    289 };
    290 
    291 class VBOXXML_CLASS EIPRTFailure : public RuntimeError
    292 {
    293 public:
    294 
    295     EIPRTFailure (int aRC);
    296 
    297     int rc() const { return mRC; }
    298 
    299 private:
    300     int mRC;
    301 };
    302 
    303 
    304 /**
    305  * The Stream class is a base class for I/O streams.
    306  */
    307 class VBOXXML_CLASS Stream
    308 {
    309 public:
    310 
    311     virtual ~Stream() {}
    312 
    313     virtual const char *uri() const = 0;
    314 
    315     /**
    316      * Returns the current read/write position in the stream. The returned
    317      * position is a zero-based byte offset from the beginning of the file.
    318      *
    319      * Throws ENotImplemented if this operation is not implemented for the
    320      * given stream.
    321      */
    322     virtual uint64_t pos() const = 0;
    323 
    324     /**
    325      * Sets the current read/write position in the stream.
    326      *
    327      * @param aPos Zero-based byte offset from the beginning of the stream.
    328      *
    329      * Throws ENotImplemented if this operation is not implemented for the
    330      * given stream.
    331      */
    332     virtual void setPos (uint64_t aPos) = 0;
    333 };
    334 
    335 /**
    336  * The Input class represents an input stream.
    337  *
    338  * This input stream is used to read the settings tree from.
    339  * This is an abstract class that must be subclassed in order to fill it with
    340  * useful functionality.
    341  */
    342 class VBOXXML_CLASS Input : virtual public Stream
    343 {
    344 public:
    345 
    346     /**
    347      * Reads from the stream to the supplied buffer.
    348      *
    349      * @param aBuf Buffer to store read data to.
    350      * @param aLen Buffer length.
    351      *
    352      * @return Number of bytes read.
    353      */
    354     virtual int read (char *aBuf, int aLen) = 0;
    355 };
    356 
    357 /**
    358  *
    359  */
    360 class VBOXXML_CLASS Output : virtual public Stream
    361 {
    362 public:
    363 
    364     /**
    365      * Writes to the stream from the supplied buffer.
    366      *
    367      * @param aBuf Buffer to write data from.
    368      * @param aLen Buffer length.
    369      *
    370      * @return Number of bytes written.
    371      */
    372     virtual int write (const char *aBuf, int aLen) = 0;
    373 
    374     /**
    375      * Truncates the stream from the current position and upto the end.
    376      * The new file size will become exactly #pos() bytes.
    377      *
    378      * Throws ENotImplemented if this operation is not implemented for the
    379      * given stream.
    380      */
    381     virtual void truncate() = 0;
    382 };
    383 
    384 
    385 //////////////////////////////////////////////////////////////////////////////
    386 
    387 /**
    388  * The File class is a stream implementation that reads from and writes to
    389  * regular files.
    390  *
    391  * The File class uses IPRT File API for file operations. Note that IPRT File
    392  * API is not thread-safe. This means that if you pass the same RTFILE handle to
    393  * different File instances that may be simultaneously used on different
    394  * threads, you should care about serialization; otherwise you will get garbage
    395  * when reading from or writing to such File instances.
    396  */
    397 class VBOXXML_CLASS File : public Input, public Output
    398 {
    399 public:
    400 
    401     /**
    402      * Possible file access modes.
    403      */
    404     enum Mode { Mode_Read, Mode_WriteCreate, Mode_Overwrite, Mode_ReadWrite };
    405 
    406     /**
    407      * Opens a file with the given name in the given mode. If @a aMode is Read
    408      * or ReadWrite, the file must exist. If @a aMode is Write, the file must
    409      * not exist. Otherwise, an EIPRTFailure excetion will be thrown.
    410      *
    411      * @param aMode     File mode.
    412      * @param aFileName File name.
    413      */
    414     File (Mode aMode, const char *aFileName);
    415 
    416     /**
    417      * Uses the given file handle to perform file operations. This file
    418      * handle must be already open in necessary mode (read, or write, or mixed).
    419      *
    420      * The read/write position of the given handle will be reset to the
    421      * beginning of the file on success.
    422      *
    423      * Note that the given file handle will not be automatically closed upon
    424      * this object destruction.
    425      *
    426      * @note It you pass the same RTFILE handle to more than one File instance,
    427      *       please make sure you have provided serialization in case if these
    428      *       instasnces are to be simultaneously used by different threads.
    429      *       Otherwise you may get garbage when reading or writing.
    430      *
    431      * @param aHandle   Open file handle.
    432      * @param aFileName File name (for reference).
    433      */
    434     File (RTFILE aHandle, const char *aFileName = NULL);
    435 
    436     /**
    437      * Destroys the File object. If the object was created from a file name
    438      * the corresponding file will be automatically closed. If the object was
    439      * created from a file handle, it will remain open.
    440      */
    441     virtual ~File();
    442 
    443     const char *uri() const;
    444 
    445     uint64_t pos() const;
    446     void setPos (uint64_t aPos);
    447 
    448     /**
    449      * See Input::read(). If this method is called in wrong file mode,
    450      * LogicError will be thrown.
    451      */
    452     int read (char *aBuf, int aLen);
    453 
    454     /**
    455      * See Output::write(). If this method is called in wrong file mode,
    456      * LogicError will be thrown.
    457      */
    458     int write (const char *aBuf, int aLen);
    459 
    460     /**
    461      * See Output::truncate(). If this method is called in wrong file mode,
    462      * LogicError will be thrown.
    463      */
    464     void truncate();
    465 
    466 private:
    467 
    468     /* Obscure class data */
    469     struct Data;
    470     std::auto_ptr <Data> m;
    471 
    472     /* auto_ptr data doesn't have proper copy semantics */
    473     DECLARE_CLS_COPY_CTOR_ASSIGN_NOOP (File)
    474 };
    475 
    476 /**
    477  * The MemoryBuf class represents a stream implementation that reads from the
    478  * memory buffer.
    479  */
    480 class VBOXXML_CLASS MemoryBuf : public Input
    481 {
    482 public:
    483 
    484     MemoryBuf (const char *aBuf, size_t aLen, const char *aURI = NULL);
    485 
    486     virtual ~MemoryBuf();
    487 
    488     const char *uri() const;
    489 
    490     int read (char *aBuf, int aLen);
    491     uint64_t pos() const;
    492     void setPos (uint64_t aPos);
    493 
    494 private:
    495     /* Obscure class data */
    496     struct Data;
    497     std::auto_ptr <Data> m;
    498 
    499     /* auto_ptr data doesn't have proper copy semantics */
    500     DECLARE_CLS_COPY_CTOR_ASSIGN_NOOP (MemoryBuf)
    501 };
    502 
    503 
    504 /*
    505  * GlobalLock
    506  *
    507  *
    508  */
    509 
    510 typedef xmlParserInput* FNEXTERNALENTITYLOADER(const char *aURI,
    511                                                const char *aID,
    512                                                xmlParserCtxt *aCtxt);
    513 typedef FNEXTERNALENTITYLOADER *PFNEXTERNALENTITYLOADER;
    514 
    515 class VBOXXML_CLASS GlobalLock
    516 {
    517 public:
    518     GlobalLock();
    519     ~GlobalLock();
    520 
    521     void setExternalEntityLoader(PFNEXTERNALENTITYLOADER pFunc);
    522 
    523     static xmlParserInput* callDefaultLoader(const char *aURI,
    524                                              const char *aID,
    525                                              xmlParserCtxt *aCtxt);
    526 
    527 private:
    528     /* Obscure class data. */
    529     struct Data;
    530     struct Data *m;
    531 };
    532 
    533 /**
    534  * Node:
    535  *  an XML node, which represents either an element or text content
    536  *  or an attribute.
    537  *
    538  *  For elements, getName() returns the element name, and getValue()
    539  *  returns the text contents, if any.
    540  *
    541  *  For attributes, getName() returns the attribute name, and getValue()
    542  *  returns the attribute value, if any.
    543  *
    544  *  Since the default constructor is private, one can create new nodes
    545  *  only through factory methods provided by the XML classes. These are:
    546  *
    547  *  --  xml::Document::createRootElement()
    548  *  --  xml::Node::createChild()
    549  *  --  xml::Node::addContent()
    550  *  --  xml::Node::setAttribute()
    551  */
    552 
    553 class ElementNode;
    554 typedef std::list<const ElementNode*> ElementNodesList;
    555 
    556 class AttributeNode;
    557 
    558 class ContentNode;
    559 
    560 class VBOXXML_CLASS Node
    561 {
    562 public:
    563     ~Node();
    564 
    565     const char* getName() const;
    566     const char* getValue() const;
    567     bool copyValue(int32_t &i) const;
    568     bool copyValue(uint32_t &i) const;
    569     bool copyValue(int64_t &i) const;
    570     bool copyValue(uint64_t &i) const;
    571 
    572     int getLineNumber() const;
    573 
    574     int isElement()
    575     {
    576         return mType == IsElement;
    577     }
    578 
    579 protected:
    580     typedef enum {IsElement, IsAttribute, IsContent} EnumType;
    581     EnumType mType;
    582 
    583     // hide the default constructor so people use only our factory methods
    584     Node(EnumType type);
    585     Node(const Node &x);      // no copying
    586 
    587     void buildChildren();
    588 
    589     /* Obscure class data */
    590     struct Data;
    591     Data *m;
    592 };
    593 
    594 class VBOXXML_CLASS ElementNode : public Node
    595 {
    596 public:
    597     int getChildElements(ElementNodesList &children,
    598                          const char *pcszMatch = NULL) const;
    599 
    600     const ElementNode* findChildElement(const char *pcszMatch) const;
    601     const ElementNode* findChildElementFromId(const char *pcszId) const;
    602 
    603     const AttributeNode* findAttribute(const char *pcszMatch) const;
    604     bool getAttributeValue(const char *pcszMatch, const char *&ppcsz) const;
    605     bool getAttributeValue(const char *pcszMatch, int64_t &i) const;
    606     bool getAttributeValue(const char *pcszMatch, uint64_t &i) const;
    607 
    608     ElementNode* createChild(const char *pcszElementName);
    609     ContentNode* addContent(const char *pcszContent);
    610     AttributeNode* setAttribute(const char *pcszName, const char *pcszValue);
    611 
    612 protected:
    613     // hide the default constructor so people use only our factory methods
    614     ElementNode();
    615     ElementNode(const ElementNode &x);      // no copying
    616 
    617     friend class Node;
    618     friend class Document;
    619     friend class XmlFileParser;
    620 };
    621 
    622 class VBOXXML_CLASS ContentNode : public Node
    623 {
    624 public:
    625 
    626 protected:
    627     // hide the default constructor so people use only our factory methods
    628     ContentNode();
    629     ContentNode(const ContentNode &x);      // no copying
    630 
    631     friend class Node;
    632     friend class ElementNode;
    633 };
    634 
    635 class VBOXXML_CLASS AttributeNode : public Node
    636 {
    637 public:
    638 
    639 protected:
    640     // hide the default constructor so people use only our factory methods
    641     AttributeNode();
    642     AttributeNode(const AttributeNode &x);      // no copying
    643 
    644     friend class Node;
    645     friend class ElementNode;
    646 };
    647 
    648 /*
    649  * NodesLoop
    650  *
    651  */
    652 
    653 class VBOXXML_CLASS NodesLoop
    654 {
    655 public:
    656     NodesLoop(const ElementNode &node, const char *pcszMatch = NULL);
    657     ~NodesLoop();
    658     const ElementNode* forAllNodes() const;
    659 
    660 private:
    661     /* Obscure class data */
    662     struct Data;
    663     Data *m;
    664 };
    665 
    666 /*
    667  * Document
    668  *
    669  */
    670 
    671 class VBOXXML_CLASS Document
    672 {
    673 public:
    674     Document();
    675     ~Document();
    676 
    677     Document(const Document &x);
    678     Document& operator=(const Document &x);
    679 
    680     const ElementNode* getRootElement() const;
    681 
    682     ElementNode* createRootElement(const char *pcszRootElementName);
    683 
    684 private:
    685     friend class XmlFileParser;
    686     friend class XmlFileWriter;
    687 
    688     void refreshInternals();
    689 
    690     /* Obscure class data */
    691     struct Data;
    692     Data *m;
    693 };
    694 
    695 /*
    696  * XmlParserBase
    697  *
    698  */
    699 
    700 class VBOXXML_CLASS XmlParserBase
    701 {
    702 protected:
    703     XmlParserBase();
    704     ~XmlParserBase();
    705 
    706     xmlParserCtxtPtr m_ctxt;
    707 };
    708 
    709 /*
    710  * XmlFileParser
    711  *
    712  */
    713 
    714 class VBOXXML_CLASS XmlFileParser : public XmlParserBase
    715 {
    716 public:
    717     XmlFileParser();
    718     ~XmlFileParser();
    719 
    720     void read(const char *pcszFilename, Document &doc);
    721 
    722 private:
    723     /* Obscure class data */
    724     struct Data;
    725     struct Data *m;
    726 
    727     static int ReadCallback(void *aCtxt, char *aBuf, int aLen);
    728     static int CloseCallback (void *aCtxt);
    729 };
    730 
    731 /*
    732  * XmlFileWriter
    733  *
    734  */
    735 
    736 class VBOXXML_CLASS XmlFileWriter
    737 {
    738 public:
    739     XmlFileWriter(Document &doc);
    740     ~XmlFileWriter();
    741 
    742     void write(const char *pcszFilename);
    743 
    744     static int WriteCallback(void *aCtxt, const char *aBuf, int aLen);
    745     static int CloseCallback (void *aCtxt);
    746 
    747 private:
    748     /* Obscure class data */
    749     struct Data;
    750     Data *m;
    751 };
    752 
    753 #if defined(_MSC_VER)
    754 #pragma warning (default:4251)
    755 #endif
    756 
    757 #endif /* IN_RING3 */
    758 
    759 /** @} */
    760 
    761 } // end namespace xml
    762 
    763 #endif /* ___VBox_vboxxml_h */
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