2
* VirtualBox XML helper APIs.
6
* Copyright (C) 2007-2008 Sun Microsystems, Inc.
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.
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.
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.
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.
30
#ifndef ___VBox_vboxxml_h
31
#define ___VBox_vboxxml_h
34
# error "There are no XML APIs available in Ring-0 Context!"
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.
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.
44
#ifdef DOXYGEN_RUNNING
45
# define IN_VBOXXML_R3
48
/** @def VBOXXML_CLASS
49
* Class export/import wrapper. */
51
# define VBOXXML_CLASS DECLEXPORT_CLASS
53
# define VBOXXML_CLASS DECLIMPORT_CLASS
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.
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
66
* template class VBOXXML_CLASS std::auto_ptr <Data>;
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.
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.
77
#pragma warning (disable:4251)
78
#pragma warning (disable:4275)
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;
92
// Little string class for XML only
93
//////////////////////////////////////////////////////////////////////////////
103
ministring(const ministring &s)
109
ministring(const char *pcsz)
120
void operator=(const char *pcsz)
126
void operator=(const ministring &s)
132
const char* c_str() const
147
void copyFrom(const char *pcsz)
150
m_psz = RTStrDup(pcsz);
158
//////////////////////////////////////////////////////////////////////////////
161
* Base exception class.
163
class VBOXXML_CLASS Error : public std::exception
167
Error(const char *pcszMessage)
170
copyFrom(pcszMessage);
173
Error(const Error &s)
179
virtual ~Error() throw()
184
void operator=(const Error &s)
190
void setWhat(const char *pcszMessage)
193
copyFrom(pcszMessage);
196
virtual const char* what() const throw()
202
Error() {}; // hide the default constructor to make sure the extended one above is always used
213
void copyFrom(const char *pcszMessage)
216
m_pcsz = RTStrDup(pcszMessage);
222
class VBOXXML_CLASS LogicError : public Error
226
LogicError(const char *aMsg = NULL)
230
LogicError(RT_SRC_POS_DECL);
233
class VBOXXML_CLASS RuntimeError : public Error
237
RuntimeError(const char *aMsg = NULL)
242
class VBOXXML_CLASS XmlError : public RuntimeError
245
XmlError(xmlErrorPtr aErr);
247
static char *Format(xmlErrorPtr aErr);
251
//////////////////////////////////////////////////////////////////////////////
253
class VBOXXML_CLASS ENotImplemented : public LogicError
256
ENotImplemented(const char *aMsg = NULL) : LogicError(aMsg) {}
257
ENotImplemented(RT_SRC_POS_DECL) : LogicError(RT_SRC_POS_ARGS) {}
260
class VBOXXML_CLASS EInvalidArg : public LogicError
263
EInvalidArg(const char *aMsg = NULL) : LogicError(aMsg) {}
264
EInvalidArg(RT_SRC_POS_DECL) : LogicError(RT_SRC_POS_ARGS) {}
267
class VBOXXML_CLASS EDocumentNotEmpty : public LogicError
270
EDocumentNotEmpty(const char *aMsg = NULL) : LogicError(aMsg) {}
271
EDocumentNotEmpty(RT_SRC_POS_DECL) : LogicError(RT_SRC_POS_ARGS) {}
274
class VBOXXML_CLASS ENodeIsNotElement : public LogicError
277
ENodeIsNotElement(const char *aMsg = NULL) : LogicError(aMsg) {}
278
ENodeIsNotElement(RT_SRC_POS_DECL) : LogicError(RT_SRC_POS_ARGS) {}
282
//////////////////////////////////////////////////////////////////////////////
284
class VBOXXML_CLASS ENoMemory : public RuntimeError, public std::bad_alloc
287
ENoMemory(const char *aMsg = NULL) : RuntimeError (aMsg) {}
288
virtual ~ENoMemory() throw() {}
291
class VBOXXML_CLASS EIPRTFailure : public RuntimeError
295
EIPRTFailure (int aRC);
297
int rc() const { return mRC; }
305
* The Stream class is a base class for I/O streams.
307
class VBOXXML_CLASS Stream
313
virtual const char *uri() const = 0;
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.
319
* Throws ENotImplemented if this operation is not implemented for the
322
virtual uint64_t pos() const = 0;
325
* Sets the current read/write position in the stream.
327
* @param aPos Zero-based byte offset from the beginning of the stream.
329
* Throws ENotImplemented if this operation is not implemented for the
332
virtual void setPos (uint64_t aPos) = 0;
336
* The Input class represents an input stream.
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.
342
class VBOXXML_CLASS Input : virtual public Stream
347
* Reads from the stream to the supplied buffer.
349
* @param aBuf Buffer to store read data to.
350
* @param aLen Buffer length.
352
* @return Number of bytes read.
354
virtual int read (char *aBuf, int aLen) = 0;
360
class VBOXXML_CLASS Output : virtual public Stream
365
* Writes to the stream from the supplied buffer.
367
* @param aBuf Buffer to write data from.
368
* @param aLen Buffer length.
370
* @return Number of bytes written.
372
virtual int write (const char *aBuf, int aLen) = 0;
375
* Truncates the stream from the current position and upto the end.
376
* The new file size will become exactly #pos() bytes.
378
* Throws ENotImplemented if this operation is not implemented for the
381
virtual void truncate() = 0;
385
//////////////////////////////////////////////////////////////////////////////
388
* The File class is a stream implementation that reads from and writes to
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.
397
class VBOXXML_CLASS File : public Input, public Output
402
* Possible file access modes.
404
enum Mode { Mode_Read, Mode_WriteCreate, Mode_Overwrite, Mode_ReadWrite };
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.
411
* @param aMode File mode.
412
* @param aFileName File name.
414
File (Mode aMode, const char *aFileName);
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).
420
* The read/write position of the given handle will be reset to the
421
* beginning of the file on success.
423
* Note that the given file handle will not be automatically closed upon
424
* this object destruction.
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.
431
* @param aHandle Open file handle.
432
* @param aFileName File name (for reference).
434
File (RTFILE aHandle, const char *aFileName = NULL);
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.
443
const char *uri() const;
445
uint64_t pos() const;
446
void setPos (uint64_t aPos);
449
* See Input::read(). If this method is called in wrong file mode,
450
* LogicError will be thrown.
452
int read (char *aBuf, int aLen);
455
* See Output::write(). If this method is called in wrong file mode,
456
* LogicError will be thrown.
458
int write (const char *aBuf, int aLen);
461
* See Output::truncate(). If this method is called in wrong file mode,
462
* LogicError will be thrown.
468
/* Obscure class data */
470
std::auto_ptr <Data> m;
472
/* auto_ptr data doesn't have proper copy semantics */
473
DECLARE_CLS_COPY_CTOR_ASSIGN_NOOP (File)
477
* The MemoryBuf class represents a stream implementation that reads from the
480
class VBOXXML_CLASS MemoryBuf : public Input
484
MemoryBuf (const char *aBuf, size_t aLen, const char *aURI = NULL);
486
virtual ~MemoryBuf();
488
const char *uri() const;
490
int read (char *aBuf, int aLen);
491
uint64_t pos() const;
492
void setPos (uint64_t aPos);
495
/* Obscure class data */
497
std::auto_ptr <Data> m;
499
/* auto_ptr data doesn't have proper copy semantics */
500
DECLARE_CLS_COPY_CTOR_ASSIGN_NOOP (MemoryBuf)
510
typedef xmlParserInput* FNEXTERNALENTITYLOADER(const char *aURI,
512
xmlParserCtxt *aCtxt);
513
typedef FNEXTERNALENTITYLOADER *PFNEXTERNALENTITYLOADER;
515
class VBOXXML_CLASS GlobalLock
521
void setExternalEntityLoader(PFNEXTERNALENTITYLOADER pFunc);
523
static xmlParserInput* callDefaultLoader(const char *aURI,
525
xmlParserCtxt *aCtxt);
528
/* Obscure class data. */
535
* an XML node, which represents either an element or text content
538
* For elements, getName() returns the element name, and getValue()
539
* returns the text contents, if any.
541
* For attributes, getName() returns the attribute name, and getValue()
542
* returns the attribute value, if any.
544
* Since the default constructor is private, one can create new nodes
545
* only through factory methods provided by the XML classes. These are:
547
* -- xml::Document::createRootElement()
548
* -- xml::Node::createChild()
549
* -- xml::Node::addContent()
550
* -- xml::Node::setAttribute()
554
typedef std::list<const ElementNode*> ElementNodesList;
560
class VBOXXML_CLASS Node
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;
572
int getLineNumber() const;
576
return mType == IsElement;
580
typedef enum {IsElement, IsAttribute, IsContent} EnumType;
583
// hide the default constructor so people use only our factory methods
585
Node(const Node &x); // no copying
587
void buildChildren();
589
/* Obscure class data */
594
class VBOXXML_CLASS ElementNode : public Node
597
int getChildElements(ElementNodesList &children,
598
const char *pcszMatch = NULL) const;
600
const ElementNode* findChildElement(const char *pcszMatch) const;
601
const ElementNode* findChildElementFromId(const char *pcszId) const;
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;
608
ElementNode* createChild(const char *pcszElementName);
609
ContentNode* addContent(const char *pcszContent);
610
AttributeNode* setAttribute(const char *pcszName, const char *pcszValue);
613
// hide the default constructor so people use only our factory methods
615
ElementNode(const ElementNode &x); // no copying
618
friend class Document;
619
friend class XmlFileParser;
622
class VBOXXML_CLASS ContentNode : public Node
627
// hide the default constructor so people use only our factory methods
629
ContentNode(const ContentNode &x); // no copying
632
friend class ElementNode;
635
class VBOXXML_CLASS AttributeNode : public Node
640
// hide the default constructor so people use only our factory methods
642
AttributeNode(const AttributeNode &x); // no copying
645
friend class ElementNode;
653
class VBOXXML_CLASS NodesLoop
656
NodesLoop(const ElementNode &node, const char *pcszMatch = NULL);
658
const ElementNode* forAllNodes() const;
661
/* Obscure class data */
671
class VBOXXML_CLASS Document
677
Document(const Document &x);
678
Document& operator=(const Document &x);
680
const ElementNode* getRootElement() const;
682
ElementNode* createRootElement(const char *pcszRootElementName);
685
friend class XmlFileParser;
686
friend class XmlFileWriter;
688
void refreshInternals();
690
/* Obscure class data */
700
class VBOXXML_CLASS XmlParserBase
706
xmlParserCtxtPtr m_ctxt;
714
class VBOXXML_CLASS XmlFileParser : public XmlParserBase
720
void read(const char *pcszFilename, Document &doc);
723
/* Obscure class data */
727
static int ReadCallback(void *aCtxt, char *aBuf, int aLen);
728
static int CloseCallback (void *aCtxt);
736
class VBOXXML_CLASS XmlFileWriter
739
XmlFileWriter(Document &doc);
742
void write(const char *pcszFilename);
744
static int WriteCallback(void *aCtxt, const char *aBuf, int aLen);
745
static int CloseCallback (void *aCtxt);
748
/* Obscure class data */
753
#if defined(_MSC_VER)
754
#pragma warning (default:4251)
757
#endif /* IN_RING3 */
761
} // end namespace xml
763
#endif /* ___VBox_vboxxml_h */