VirtualBox

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

Last change on this file since 15366 was 14923, checked in by vboxsync, 16 years ago

Main: fix another windows build break

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