VirtualBox

source: vbox/trunk/include/iprt/xml_cpp.h@ 21165

Last change on this file since 21165 was 21085, checked in by vboxsync, 16 years ago

Main: fix class import/export linkage by using RT_DECL_CLASS (r49346)

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 15.0 KB
Line 
1/** @file
2 * VirtualBox XML helper APIs.
3 */
4
5/*
6 * Copyright (C) 2007-2009 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#include <list>
38#include <memory>
39
40#include <iprt/ministring_cpp.h>
41
42/* Forwards */
43typedef struct _xmlParserInput xmlParserInput;
44typedef xmlParserInput *xmlParserInputPtr;
45typedef struct _xmlParserCtxt xmlParserCtxt;
46typedef xmlParserCtxt *xmlParserCtxtPtr;
47typedef struct _xmlError xmlError;
48typedef xmlError *xmlErrorPtr;
49
50namespace xml
51{
52
53// Exceptions
54//////////////////////////////////////////////////////////////////////////////
55
56/**
57 * Base exception class.
58 */
59class RT_DECL_CLASS Error : public std::exception
60{
61public:
62
63 Error(const char *pcszMessage)
64 : m_s(pcszMessage)
65 {
66 }
67
68 Error(const Error &s)
69 : std::exception(s),
70 m_s(s.what())
71 {
72 }
73
74 virtual ~Error() throw()
75 {
76 }
77
78 void operator=(const Error &s)
79 {
80 m_s = s.what();
81 }
82
83 void setWhat(const char *pcszMessage)
84 {
85 m_s = pcszMessage;
86 }
87
88 virtual const char* what() const throw()
89 {
90 return m_s.c_str();
91 }
92
93private:
94 Error() {}; // hide the default constructor to make sure the extended one above is always used
95
96 ministring m_s;
97};
98
99class RT_DECL_CLASS LogicError : public Error
100{
101public:
102
103 LogicError(const char *aMsg = NULL)
104 : xml::Error(aMsg)
105 {}
106
107 LogicError(RT_SRC_POS_DECL);
108};
109
110class RT_DECL_CLASS RuntimeError : public Error
111{
112public:
113
114 RuntimeError(const char *aMsg = NULL)
115 : xml::Error(aMsg)
116 {}
117};
118
119class RT_DECL_CLASS XmlError : public RuntimeError
120{
121public:
122 XmlError(xmlErrorPtr aErr);
123
124 static char *Format(xmlErrorPtr aErr);
125};
126
127// Logical errors
128//////////////////////////////////////////////////////////////////////////////
129
130class RT_DECL_CLASS ENotImplemented : public LogicError
131{
132public:
133 ENotImplemented(const char *aMsg = NULL) : LogicError(aMsg) {}
134 ENotImplemented(RT_SRC_POS_DECL) : LogicError(RT_SRC_POS_ARGS) {}
135};
136
137class RT_DECL_CLASS EInvalidArg : public LogicError
138{
139public:
140 EInvalidArg(const char *aMsg = NULL) : LogicError(aMsg) {}
141 EInvalidArg(RT_SRC_POS_DECL) : LogicError(RT_SRC_POS_ARGS) {}
142};
143
144class RT_DECL_CLASS EDocumentNotEmpty : public LogicError
145{
146public:
147 EDocumentNotEmpty(const char *aMsg = NULL) : LogicError(aMsg) {}
148 EDocumentNotEmpty(RT_SRC_POS_DECL) : LogicError(RT_SRC_POS_ARGS) {}
149};
150
151class RT_DECL_CLASS ENodeIsNotElement : public LogicError
152{
153public:
154 ENodeIsNotElement(const char *aMsg = NULL) : LogicError(aMsg) {}
155 ENodeIsNotElement(RT_SRC_POS_DECL) : LogicError(RT_SRC_POS_ARGS) {}
156};
157
158// Runtime errors
159//////////////////////////////////////////////////////////////////////////////
160
161class RT_DECL_CLASS ENoMemory : public RuntimeError, public std::bad_alloc
162{
163public:
164 ENoMemory(const char *aMsg = NULL) : RuntimeError (aMsg) {}
165 virtual ~ENoMemory() throw() {}
166};
167
168class RT_DECL_CLASS EIPRTFailure : public RuntimeError
169{
170public:
171
172 EIPRTFailure (int aRC);
173
174 int rc() const { return mRC; }
175
176private:
177 int mRC;
178};
179
180
181/**
182 * The Stream class is a base class for I/O streams.
183 */
184class RT_DECL_CLASS Stream
185{
186public:
187
188 virtual ~Stream() {}
189
190 virtual const char *uri() const = 0;
191
192 /**
193 * Returns the current read/write position in the stream. The returned
194 * position is a zero-based byte offset from the beginning of the file.
195 *
196 * Throws ENotImplemented if this operation is not implemented for the
197 * given stream.
198 */
199 virtual uint64_t pos() const = 0;
200
201 /**
202 * Sets the current read/write position in the stream.
203 *
204 * @param aPos Zero-based byte offset from the beginning of the stream.
205 *
206 * Throws ENotImplemented if this operation is not implemented for the
207 * given stream.
208 */
209 virtual void setPos (uint64_t aPos) = 0;
210};
211
212/**
213 * The Input class represents an input stream.
214 *
215 * This input stream is used to read the settings tree from.
216 * This is an abstract class that must be subclassed in order to fill it with
217 * useful functionality.
218 */
219class RT_DECL_CLASS Input : virtual public Stream
220{
221public:
222
223 /**
224 * Reads from the stream to the supplied buffer.
225 *
226 * @param aBuf Buffer to store read data to.
227 * @param aLen Buffer length.
228 *
229 * @return Number of bytes read.
230 */
231 virtual int read (char *aBuf, int aLen) = 0;
232};
233
234/**
235 *
236 */
237class RT_DECL_CLASS Output : virtual public Stream
238{
239public:
240
241 /**
242 * Writes to the stream from the supplied buffer.
243 *
244 * @param aBuf Buffer to write data from.
245 * @param aLen Buffer length.
246 *
247 * @return Number of bytes written.
248 */
249 virtual int write (const char *aBuf, int aLen) = 0;
250
251 /**
252 * Truncates the stream from the current position and upto the end.
253 * The new file size will become exactly #pos() bytes.
254 *
255 * Throws ENotImplemented if this operation is not implemented for the
256 * given stream.
257 */
258 virtual void truncate() = 0;
259};
260
261
262//////////////////////////////////////////////////////////////////////////////
263
264/**
265 * The File class is a stream implementation that reads from and writes to
266 * regular files.
267 *
268 * The File class uses IPRT File API for file operations. Note that IPRT File
269 * API is not thread-safe. This means that if you pass the same RTFILE handle to
270 * different File instances that may be simultaneously used on different
271 * threads, you should care about serialization; otherwise you will get garbage
272 * when reading from or writing to such File instances.
273 */
274class RT_DECL_CLASS File : public Input, public Output
275{
276public:
277
278 /**
279 * Possible file access modes.
280 */
281 enum Mode { Mode_Read, Mode_WriteCreate, Mode_Overwrite, Mode_ReadWrite };
282
283 /**
284 * Opens a file with the given name in the given mode. If @a aMode is Read
285 * or ReadWrite, the file must exist. If @a aMode is Write, the file must
286 * not exist. Otherwise, an EIPRTFailure excetion will be thrown.
287 *
288 * @param aMode File mode.
289 * @param aFileName File name.
290 */
291 File (Mode aMode, const char *aFileName);
292
293 /**
294 * Uses the given file handle to perform file operations. This file
295 * handle must be already open in necessary mode (read, or write, or mixed).
296 *
297 * The read/write position of the given handle will be reset to the
298 * beginning of the file on success.
299 *
300 * Note that the given file handle will not be automatically closed upon
301 * this object destruction.
302 *
303 * @note It you pass the same RTFILE handle to more than one File instance,
304 * please make sure you have provided serialization in case if these
305 * instasnces are to be simultaneously used by different threads.
306 * Otherwise you may get garbage when reading or writing.
307 *
308 * @param aHandle Open file handle.
309 * @param aFileName File name (for reference).
310 */
311 File (RTFILE aHandle, const char *aFileName = NULL);
312
313 /**
314 * Destroys the File object. If the object was created from a file name
315 * the corresponding file will be automatically closed. If the object was
316 * created from a file handle, it will remain open.
317 */
318 virtual ~File();
319
320 const char *uri() const;
321
322 uint64_t pos() const;
323 void setPos (uint64_t aPos);
324
325 /**
326 * See Input::read(). If this method is called in wrong file mode,
327 * LogicError will be thrown.
328 */
329 int read (char *aBuf, int aLen);
330
331 /**
332 * See Output::write(). If this method is called in wrong file mode,
333 * LogicError will be thrown.
334 */
335 int write (const char *aBuf, int aLen);
336
337 /**
338 * See Output::truncate(). If this method is called in wrong file mode,
339 * LogicError will be thrown.
340 */
341 void truncate();
342
343private:
344
345 /* Obscure class data */
346 struct Data;
347 Data *m;
348
349 /* auto_ptr data doesn't have proper copy semantics */
350 DECLARE_CLS_COPY_CTOR_ASSIGN_NOOP (File)
351};
352
353/**
354 * The MemoryBuf class represents a stream implementation that reads from the
355 * memory buffer.
356 */
357class RT_DECL_CLASS MemoryBuf : public Input
358{
359public:
360
361 MemoryBuf (const char *aBuf, size_t aLen, const char *aURI = NULL);
362
363 virtual ~MemoryBuf();
364
365 const char *uri() const;
366
367 int read (char *aBuf, int aLen);
368 uint64_t pos() const;
369 void setPos (uint64_t aPos);
370
371private:
372 /* Obscure class data */
373 struct Data;
374 Data *m;
375
376 /* auto_ptr data doesn't have proper copy semantics */
377 DECLARE_CLS_COPY_CTOR_ASSIGN_NOOP (MemoryBuf)
378};
379
380
381/*
382 * GlobalLock
383 *
384 *
385 */
386
387typedef xmlParserInput* FNEXTERNALENTITYLOADER(const char *aURI,
388 const char *aID,
389 xmlParserCtxt *aCtxt);
390typedef FNEXTERNALENTITYLOADER *PFNEXTERNALENTITYLOADER;
391
392class RT_DECL_CLASS GlobalLock
393{
394public:
395 GlobalLock();
396 ~GlobalLock();
397
398 void setExternalEntityLoader(PFNEXTERNALENTITYLOADER pFunc);
399
400 static xmlParserInput* callDefaultLoader(const char *aURI,
401 const char *aID,
402 xmlParserCtxt *aCtxt);
403
404private:
405 /* Obscure class data. */
406 struct Data;
407 struct Data *m;
408};
409
410/**
411 * Node:
412 * an XML node, which represents either an element or text content
413 * or an attribute.
414 *
415 * For elements, getName() returns the element name, and getValue()
416 * returns the text contents, if any.
417 *
418 * For attributes, getName() returns the attribute name, and getValue()
419 * returns the attribute value, if any.
420 *
421 * Since the default constructor is private, one can create new nodes
422 * only through factory methods provided by the XML classes. These are:
423 *
424 * -- xml::Document::createRootElement()
425 * -- xml::Node::createChild()
426 * -- xml::Node::addContent()
427 * -- xml::Node::setAttribute()
428 */
429
430class ElementNode;
431typedef std::list<const ElementNode*> ElementNodesList;
432
433class AttributeNode;
434
435class ContentNode;
436
437class RT_DECL_CLASS Node
438{
439public:
440 ~Node();
441
442 const char* getName() const;
443 const char* getValue() const;
444 bool copyValue(int32_t &i) const;
445 bool copyValue(uint32_t &i) const;
446 bool copyValue(int64_t &i) const;
447 bool copyValue(uint64_t &i) const;
448
449 int getLineNumber() const;
450
451 int isElement()
452 {
453 return mType == IsElement;
454 }
455
456protected:
457 typedef enum {IsElement, IsAttribute, IsContent} EnumType;
458 EnumType mType;
459
460 // hide the default constructor so people use only our factory methods
461 Node(EnumType type);
462 Node(const Node &x); // no copying
463
464 void buildChildren();
465
466 /* Obscure class data */
467 struct Data;
468 Data *m;
469};
470
471class RT_DECL_CLASS ElementNode : public Node
472{
473public:
474 int getChildElements(ElementNodesList &children,
475 const char *pcszMatch = NULL) const;
476
477 const ElementNode* findChildElement(const char *pcszMatch) const;
478 const ElementNode* findChildElementFromId(const char *pcszId) const;
479
480 const AttributeNode* findAttribute(const char *pcszMatch) const;
481 bool getAttributeValue(const char *pcszMatch, const char *&ppcsz) const;
482 bool getAttributeValue(const char *pcszMatch, int64_t &i) const;
483 bool getAttributeValue(const char *pcszMatch, uint64_t &i) const;
484
485 ElementNode* createChild(const char *pcszElementName);
486 ContentNode* addContent(const char *pcszContent);
487 AttributeNode* setAttribute(const char *pcszName, const char *pcszValue);
488
489protected:
490 // hide the default constructor so people use only our factory methods
491 ElementNode();
492 ElementNode(const ElementNode &x); // no copying
493
494 friend class Node;
495 friend class Document;
496 friend class XmlFileParser;
497};
498
499class RT_DECL_CLASS ContentNode : public Node
500{
501public:
502
503protected:
504 // hide the default constructor so people use only our factory methods
505 ContentNode();
506 ContentNode(const ContentNode &x); // no copying
507
508 friend class Node;
509 friend class ElementNode;
510};
511
512class RT_DECL_CLASS AttributeNode : public Node
513{
514public:
515
516protected:
517 // hide the default constructor so people use only our factory methods
518 AttributeNode();
519 AttributeNode(const AttributeNode &x); // no copying
520
521 friend class Node;
522 friend class ElementNode;
523};
524
525/*
526 * NodesLoop
527 *
528 */
529
530class RT_DECL_CLASS NodesLoop
531{
532public:
533 NodesLoop(const ElementNode &node, const char *pcszMatch = NULL);
534 ~NodesLoop();
535 const ElementNode* forAllNodes() const;
536
537private:
538 /* Obscure class data */
539 struct Data;
540 Data *m;
541};
542
543/*
544 * Document
545 *
546 */
547
548class RT_DECL_CLASS Document
549{
550public:
551 Document();
552 ~Document();
553
554 Document(const Document &x);
555 Document& operator=(const Document &x);
556
557 const ElementNode* getRootElement() const;
558
559 ElementNode* createRootElement(const char *pcszRootElementName);
560
561private:
562 friend class XmlFileParser;
563 friend class XmlFileWriter;
564
565 void refreshInternals();
566
567 /* Obscure class data */
568 struct Data;
569 Data *m;
570};
571
572/*
573 * XmlParserBase
574 *
575 */
576
577class RT_DECL_CLASS XmlParserBase
578{
579protected:
580 XmlParserBase();
581 ~XmlParserBase();
582
583 xmlParserCtxtPtr m_ctxt;
584};
585
586/*
587 * XmlFileParser
588 *
589 */
590
591class RT_DECL_CLASS XmlFileParser : public XmlParserBase
592{
593public:
594 XmlFileParser();
595 ~XmlFileParser();
596
597 void read(const char *pcszFilename, Document &doc);
598
599private:
600 /* Obscure class data */
601 struct Data;
602 struct Data *m;
603
604 static int ReadCallback(void *aCtxt, char *aBuf, int aLen);
605 static int CloseCallback (void *aCtxt);
606};
607
608/*
609 * XmlFileWriter
610 *
611 */
612
613class RT_DECL_CLASS XmlFileWriter
614{
615public:
616 XmlFileWriter(Document &doc);
617 ~XmlFileWriter();
618
619 void write(const char *pcszFilename);
620
621 static int WriteCallback(void *aCtxt, const char *aBuf, int aLen);
622 static int CloseCallback (void *aCtxt);
623
624private:
625 /* Obscure class data */
626 struct Data;
627 Data *m;
628};
629
630#if defined(_MSC_VER)
631#pragma warning (default:4251)
632#endif
633
634#endif /* IN_RING3 */
635
636/** @} */
637
638} // end namespace xml
639
640#endif /* ___VBox_vboxxml_h */
Note: See TracBrowser for help on using the repository browser.

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