VirtualBox

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

Last change on this file since 16383 was 16325, checked in by vboxsync, 16 years ago

OVF: make com::xml and IAppliance use Utf8Str instead of std::string

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