VirtualBox

source: vbox/trunk/include/VBox/xml.h@ 17251

Last change on this file since 17251 was 16539, checked in by vboxsync, 16 years ago

Main: remove special string class in XML exceptions

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 13.4 KB
Line 
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#include "VBox/com/string.h"
57
58/*
59 * Shut up MSVC complaining that auto_ptr[_ref] template instantiations (as a
60 * result of private data member declarations of some classes below) need to
61 * be exported too to in order to be accessible by clients.
62 *
63 * The alternative is to instantiate a template before the data member
64 * declaration with the VBOXXML_CLASS prefix, but the standard disables
65 * explicit instantiations in a foreign namespace. In other words, a declaration
66 * like:
67 *
68 * template class VBOXXML_CLASS std::auto_ptr <Data>;
69 *
70 * right before the member declaration makes MSVC happy too, but this is not a
71 * valid C++ construct (and G++ spits it out). So, for now we just disable the
72 * warning and will come back to this problem one day later.
73 *
74 * We also disable another warning (4275) saying that a DLL-exported class
75 * inherits form a non-DLL-exported one (e.g. settings::ENoMemory ->
76 * std::bad_alloc). I can't get how it can harm yet.
77 */
78#if defined(_MSC_VER)
79#pragma warning (disable:4251)
80#pragma warning (disable:4275)
81#endif
82
83/* Forwards */
84typedef struct _xmlParserInput xmlParserInput;
85typedef xmlParserInput *xmlParserInputPtr;
86typedef struct _xmlParserCtxt xmlParserCtxt;
87typedef xmlParserCtxt *xmlParserCtxtPtr;
88typedef struct _xmlError xmlError;
89typedef xmlError *xmlErrorPtr;
90
91namespace xml
92{
93
94// Exceptions
95//////////////////////////////////////////////////////////////////////////////
96
97/**
98 * Base exception class.
99 */
100class VBOXXML_CLASS Error : public std::exception
101{
102public:
103
104 Error(const char *aMsg = NULL)
105 : m(aMsg) {}
106
107 virtual ~Error() throw() {}
108
109 void setWhat (const char *aMsg) { m = aMsg; }
110
111 const char* what() const throw() { return m.c_str(); }
112
113private:
114
115// Error() {}; // hide the default constructor to make sure the extended one above is always used
116
117 com::Utf8Str m;
118};
119
120class VBOXXML_CLASS LogicError : public Error
121{
122public:
123
124 LogicError (const char *aMsg = NULL)
125 : xml::Error(aMsg)
126 {}
127
128 LogicError (RT_SRC_POS_DECL);
129};
130
131class VBOXXML_CLASS RuntimeError : public Error
132{
133public:
134
135 RuntimeError (const char *aMsg = NULL) : Error (aMsg) {}
136};
137
138class VBOXXML_CLASS XmlError : public RuntimeError
139{
140public:
141
142 XmlError(xmlErrorPtr aErr);
143
144 static char *Format(xmlErrorPtr aErr);
145};
146
147// Logical errors
148//////////////////////////////////////////////////////////////////////////////
149
150class VBOXXML_CLASS ENotImplemented : public LogicError
151{
152public:
153
154 ENotImplemented (const char *aMsg = NULL) : LogicError (aMsg) {}
155 ENotImplemented (RT_SRC_POS_DECL) : LogicError (RT_SRC_POS_ARGS) {}
156};
157
158class VBOXXML_CLASS EInvalidArg : public LogicError
159{
160public:
161
162 EInvalidArg (const char *aMsg = NULL) : LogicError (aMsg) {}
163 EInvalidArg (RT_SRC_POS_DECL) : LogicError (RT_SRC_POS_ARGS) {}
164};
165
166// Runtime errors
167//////////////////////////////////////////////////////////////////////////////
168
169class VBOXXML_CLASS ENoMemory : public RuntimeError, public std::bad_alloc
170{
171public:
172
173 ENoMemory (const char *aMsg = NULL) : RuntimeError (aMsg) {}
174 virtual ~ENoMemory() throw() {}
175};
176
177class VBOXXML_CLASS EIPRTFailure : public RuntimeError
178{
179public:
180
181 EIPRTFailure (int aRC);
182
183 int rc() const { return mRC; }
184
185private:
186 int mRC;
187};
188
189
190/**
191 * The Stream class is a base class for I/O streams.
192 */
193class VBOXXML_CLASS Stream
194{
195public:
196
197 virtual ~Stream() {}
198
199 virtual const char *uri() const = 0;
200
201 /**
202 * Returns the current read/write position in the stream. The returned
203 * position is a zero-based byte offset from the beginning of the file.
204 *
205 * Throws ENotImplemented if this operation is not implemented for the
206 * given stream.
207 */
208 virtual uint64_t pos() const = 0;
209
210 /**
211 * Sets the current read/write position in the stream.
212 *
213 * @param aPos Zero-based byte offset from the beginning of the stream.
214 *
215 * Throws ENotImplemented if this operation is not implemented for the
216 * given stream.
217 */
218 virtual void setPos (uint64_t aPos) = 0;
219};
220
221/**
222 * The Input class represents an input stream.
223 *
224 * This input stream is used to read the settings tree from.
225 * This is an abstract class that must be subclassed in order to fill it with
226 * useful functionality.
227 */
228class VBOXXML_CLASS Input : virtual public Stream
229{
230public:
231
232 /**
233 * Reads from the stream to the supplied buffer.
234 *
235 * @param aBuf Buffer to store read data to.
236 * @param aLen Buffer length.
237 *
238 * @return Number of bytes read.
239 */
240 virtual int read (char *aBuf, int aLen) = 0;
241};
242
243/**
244 *
245 */
246class VBOXXML_CLASS Output : virtual public Stream
247{
248public:
249
250 /**
251 * Writes to the stream from the supplied buffer.
252 *
253 * @param aBuf Buffer to write data from.
254 * @param aLen Buffer length.
255 *
256 * @return Number of bytes written.
257 */
258 virtual int write (const char *aBuf, int aLen) = 0;
259
260 /**
261 * Truncates the stream from the current position and upto the end.
262 * The new file size will become exactly #pos() bytes.
263 *
264 * Throws ENotImplemented if this operation is not implemented for the
265 * given stream.
266 */
267 virtual void truncate() = 0;
268};
269
270
271//////////////////////////////////////////////////////////////////////////////
272
273/**
274 * The File class is a stream implementation that reads from and writes to
275 * regular files.
276 *
277 * The File class uses IPRT File API for file operations. Note that IPRT File
278 * API is not thread-safe. This means that if you pass the same RTFILE handle to
279 * different File instances that may be simultaneously used on different
280 * threads, you should care about serialization; otherwise you will get garbage
281 * when reading from or writing to such File instances.
282 */
283class VBOXXML_CLASS File : public Input, public Output
284{
285public:
286
287 /**
288 * Possible file access modes.
289 */
290 enum Mode { Mode_Read, Mode_Write, Mode_ReadWrite };
291
292 /**
293 * Opens a file with the given name in the given mode. If @a aMode is Read
294 * or ReadWrite, the file must exist. If @a aMode is Write, the file must
295 * not exist. Otherwise, an EIPRTFailure excetion will be thrown.
296 *
297 * @param aMode File mode.
298 * @param aFileName File name.
299 */
300 File (Mode aMode, const char *aFileName);
301
302 /**
303 * Uses the given file handle to perform file operations. This file
304 * handle must be already open in necessary mode (read, or write, or mixed).
305 *
306 * The read/write position of the given handle will be reset to the
307 * beginning of the file on success.
308 *
309 * Note that the given file handle will not be automatically closed upon
310 * this object destruction.
311 *
312 * @note It you pass the same RTFILE handle to more than one File instance,
313 * please make sure you have provided serialization in case if these
314 * instasnces are to be simultaneously used by different threads.
315 * Otherwise you may get garbage when reading or writing.
316 *
317 * @param aHandle Open file handle.
318 * @param aFileName File name (for reference).
319 */
320 File (RTFILE aHandle, const char *aFileName = NULL);
321
322 /**
323 * Destrroys the File object. If the object was created from a file name
324 * the corresponding file will be automatically closed. If the object was
325 * created from a file handle, it will remain open.
326 */
327 virtual ~File();
328
329 const char *uri() const;
330
331 uint64_t pos() const;
332 void setPos (uint64_t aPos);
333
334 /**
335 * See Input::read(). If this method is called in wrong file mode,
336 * LogicError will be thrown.
337 */
338 int read (char *aBuf, int aLen);
339
340 /**
341 * See Output::write(). If this method is called in wrong file mode,
342 * LogicError will be thrown.
343 */
344 int write (const char *aBuf, int aLen);
345
346 /**
347 * See Output::truncate(). If this method is called in wrong file mode,
348 * LogicError will be thrown.
349 */
350 void truncate();
351
352private:
353
354 /* Obscure class data */
355 struct Data;
356 std::auto_ptr <Data> m;
357
358 /* auto_ptr data doesn't have proper copy semantics */
359 DECLARE_CLS_COPY_CTOR_ASSIGN_NOOP (File)
360};
361
362/**
363 * The MemoryBuf class represents a stream implementation that reads from the
364 * memory buffer.
365 */
366class VBOXXML_CLASS MemoryBuf : public Input
367{
368public:
369
370 MemoryBuf (const char *aBuf, size_t aLen, const char *aURI = NULL);
371
372 virtual ~MemoryBuf();
373
374 const char *uri() const;
375
376 int read (char *aBuf, int aLen);
377 uint64_t pos() const;
378 void setPos (uint64_t aPos);
379
380private:
381 /* Obscure class data */
382 struct Data;
383 std::auto_ptr <Data> m;
384
385 /* auto_ptr data doesn't have proper copy semantics */
386 DECLARE_CLS_COPY_CTOR_ASSIGN_NOOP (MemoryBuf)
387};
388
389
390/*
391 * GlobalLock
392 *
393 *
394 */
395
396typedef xmlParserInput* FNEXTERNALENTITYLOADER(const char *aURI,
397 const char *aID,
398 xmlParserCtxt *aCtxt);
399typedef FNEXTERNALENTITYLOADER *PFNEXTERNALENTITYLOADER;
400
401class VBOXXML_CLASS GlobalLock
402{
403public:
404 GlobalLock();
405 ~GlobalLock();
406
407 void setExternalEntityLoader(PFNEXTERNALENTITYLOADER pFunc);
408
409 static xmlParserInput* callDefaultLoader(const char *aURI,
410 const char *aID,
411 xmlParserCtxt *aCtxt);
412
413private:
414 /* Obscure class data */
415 struct Data;
416 std::auto_ptr<Data> m;
417};
418
419/*
420 * Node
421 *
422 */
423
424class Node;
425typedef std::list<const Node*> NodesList;
426
427class VBOXXML_CLASS Node
428{
429public:
430 Node();
431 ~Node();
432
433 const char* getName() const;
434 const char* getValue() const;
435 bool copyValue(int32_t &i) const;
436 bool copyValue(uint32_t &i) const;
437 bool copyValue(int64_t &i) const;
438 bool copyValue(uint64_t &i) const;
439
440 int getLineNumber() const;
441
442 int getChildElements(NodesList &children,
443 const char *pcszMatch = NULL) const;
444
445 const Node* findChildElement(const char *pcszMatch) const;
446 const Node* findChildElementFromId(const char *pcszId) const;
447
448 const Node* findAttribute(const char *pcszMatch) const;
449 bool getAttributeValue(const char *pcszMatch, com::Utf8Str &str) const;
450 bool getAttributeValue(const char *pcszMatch, int64_t &i) const;
451 bool getAttributeValue(const char *pcszMatch, uint64_t &i) const;
452
453private:
454 friend class Document;
455 friend class XmlFileParser;
456
457 Node(const Node &x); // no copying
458
459 void buildChildren();
460
461 /* Obscure class data */
462 struct Data;
463 Data *m;
464};
465
466/*
467 * NodesLoop
468 *
469 */
470
471class VBOXXML_CLASS NodesLoop
472{
473public:
474 NodesLoop(const Node &node, const char *pcszMatch = NULL);
475 ~NodesLoop();
476 const Node* forAllNodes() const;
477
478private:
479 struct Data;
480 Data *m;
481};
482
483/*
484 * Document
485 *
486 */
487
488class VBOXXML_CLASS Document
489{
490public:
491 Document();
492 ~Document();
493 Document(const Document &x);
494 Document& operator=(const Document &x);
495
496 const Node* getRootElement() const;
497
498private:
499 friend class XmlFileParser;
500
501 void refreshInternals();
502
503 /* Obscure class data */
504 struct Data;
505 Data *m;
506};
507
508/*
509 * XmlParserBase
510 *
511 */
512
513class VBOXXML_CLASS XmlParserBase
514{
515protected:
516 XmlParserBase();
517 ~XmlParserBase();
518
519 xmlParserCtxtPtr m_ctxt;
520};
521
522/*
523 * XmlFileParser
524 *
525 */
526
527class VBOXXML_CLASS XmlFileParser : public XmlParserBase
528{
529public:
530 XmlFileParser();
531 ~XmlFileParser();
532
533 void read(const char *pcszFilename, Document &doc);
534
535private:
536 /* Obscure class data */
537 struct Data;
538 std::auto_ptr<Data> m;
539
540 static int ReadCallback(void *aCtxt, char *aBuf, int aLen);
541
542 static int CloseCallback (void *aCtxt);
543};
544
545
546
547#if defined(_MSC_VER)
548#pragma warning (default:4251)
549#endif
550
551#endif /* IN_RING3 */
552
553/** @} */
554
555} // end namespace xml
556
557#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