VirtualBox

source: vbox/trunk/include/iprt/cpp/xml.h@ 48781

Last change on this file since 48781 was 48781, checked in by vboxsync, 11 years ago

iprt/list.h,xml.h: Because of gcc, we need a C++ version of a bunch of the RTListXxx macros that uses RT_FROM_CPP_MEMBER instead of RT_FROM_MEMBER. I don't dare speculate on the compilers optimizing the two macros in the same way, thus two sets of macros.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 23.8 KB
Line 
1/** @file
2 * IPRT - XML Helper APIs.
3 */
4
5/*
6 * Copyright (C) 2007-2012 Oracle Corporation
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
26#ifndef ___iprt_xml_h
27#define ___iprt_xml_h
28
29#ifndef IN_RING3
30# error "There are no XML APIs available in Ring-0 Context!"
31#endif
32
33/*#define USE_STD_LIST_FOR_CHILDREN*/
34
35#include <iprt/list.h>
36#include <iprt/cpp/exception.h>
37
38#include <list>
39#include <memory>
40
41
42/** @defgroup grp_rt_cpp_xml C++ XML support
43 * @ingroup grp_rt_cpp
44 * @{
45 */
46
47/* Forwards */
48typedef struct _xmlParserInput xmlParserInput;
49typedef xmlParserInput *xmlParserInputPtr;
50typedef struct _xmlParserCtxt xmlParserCtxt;
51typedef xmlParserCtxt *xmlParserCtxtPtr;
52typedef struct _xmlError xmlError;
53typedef xmlError *xmlErrorPtr;
54
55typedef struct _xmlAttr xmlAttr;
56typedef struct _xmlNode xmlNode;
57
58/** @} */
59
60namespace xml
61{
62
63/**
64 * @addtogroup grp_rt_cpp_xml
65 * @{
66 */
67
68// Exceptions
69//////////////////////////////////////////////////////////////////////////////
70
71class RT_DECL_CLASS LogicError : public RTCError
72{
73public:
74
75 LogicError(const char *aMsg = NULL)
76 : RTCError(aMsg)
77 {}
78
79 LogicError(RT_SRC_POS_DECL);
80};
81
82class RT_DECL_CLASS RuntimeError : public RTCError
83{
84public:
85
86 RuntimeError(const char *aMsg = NULL)
87 : RTCError(aMsg)
88 {}
89};
90
91class RT_DECL_CLASS XmlError : public RuntimeError
92{
93public:
94 XmlError(xmlErrorPtr aErr);
95
96 static char* Format(xmlErrorPtr aErr);
97};
98
99// Logical errors
100//////////////////////////////////////////////////////////////////////////////
101
102class RT_DECL_CLASS ENotImplemented : public LogicError
103{
104public:
105 ENotImplemented(const char *aMsg = NULL) : LogicError(aMsg) {}
106 ENotImplemented(RT_SRC_POS_DECL) : LogicError(RT_SRC_POS_ARGS) {}
107};
108
109class RT_DECL_CLASS EInvalidArg : public LogicError
110{
111public:
112 EInvalidArg(const char *aMsg = NULL) : LogicError(aMsg) {}
113 EInvalidArg(RT_SRC_POS_DECL) : LogicError(RT_SRC_POS_ARGS) {}
114};
115
116class RT_DECL_CLASS EDocumentNotEmpty : public LogicError
117{
118public:
119 EDocumentNotEmpty(const char *aMsg = NULL) : LogicError(aMsg) {}
120 EDocumentNotEmpty(RT_SRC_POS_DECL) : LogicError(RT_SRC_POS_ARGS) {}
121};
122
123class RT_DECL_CLASS ENodeIsNotElement : public LogicError
124{
125public:
126 ENodeIsNotElement(const char *aMsg = NULL) : LogicError(aMsg) {}
127 ENodeIsNotElement(RT_SRC_POS_DECL) : LogicError(RT_SRC_POS_ARGS) {}
128};
129
130// Runtime errors
131//////////////////////////////////////////////////////////////////////////////
132
133class RT_DECL_CLASS EIPRTFailure : public RuntimeError
134{
135public:
136
137 EIPRTFailure(int aRC, const char *pcszContext, ...);
138
139 int rc() const
140 {
141 return mRC;
142 }
143
144private:
145 int mRC;
146};
147
148/**
149 * The Stream class is a base class for I/O streams.
150 */
151class RT_DECL_CLASS Stream
152{
153public:
154
155 virtual ~Stream() {}
156
157 virtual const char *uri() const = 0;
158
159 /**
160 * Returns the current read/write position in the stream. The returned
161 * position is a zero-based byte offset from the beginning of the file.
162 *
163 * Throws ENotImplemented if this operation is not implemented for the
164 * given stream.
165 */
166 virtual uint64_t pos() const = 0;
167
168 /**
169 * Sets the current read/write position in the stream.
170 *
171 * @param aPos Zero-based byte offset from the beginning of the stream.
172 *
173 * Throws ENotImplemented if this operation is not implemented for the
174 * given stream.
175 */
176 virtual void setPos (uint64_t aPos) = 0;
177};
178
179/**
180 * The Input class represents an input stream.
181 *
182 * This input stream is used to read the settings tree from.
183 * This is an abstract class that must be subclassed in order to fill it with
184 * useful functionality.
185 */
186class RT_DECL_CLASS Input : virtual public Stream
187{
188public:
189
190 /**
191 * Reads from the stream to the supplied buffer.
192 *
193 * @param aBuf Buffer to store read data to.
194 * @param aLen Buffer length.
195 *
196 * @return Number of bytes read.
197 */
198 virtual int read (char *aBuf, int aLen) = 0;
199};
200
201/**
202 *
203 */
204class RT_DECL_CLASS Output : virtual public Stream
205{
206public:
207
208 /**
209 * Writes to the stream from the supplied buffer.
210 *
211 * @param aBuf Buffer to write data from.
212 * @param aLen Buffer length.
213 *
214 * @return Number of bytes written.
215 */
216 virtual int write (const char *aBuf, int aLen) = 0;
217
218 /**
219 * Truncates the stream from the current position and upto the end.
220 * The new file size will become exactly #pos() bytes.
221 *
222 * Throws ENotImplemented if this operation is not implemented for the
223 * given stream.
224 */
225 virtual void truncate() = 0;
226};
227
228
229//////////////////////////////////////////////////////////////////////////////
230
231/**
232 * The File class is a stream implementation that reads from and writes to
233 * regular files.
234 *
235 * The File class uses IPRT File API for file operations. Note that IPRT File
236 * API is not thread-safe. This means that if you pass the same RTFILE handle to
237 * different File instances that may be simultaneously used on different
238 * threads, you should care about serialization; otherwise you will get garbage
239 * when reading from or writing to such File instances.
240 */
241class RT_DECL_CLASS File : public Input, public Output
242{
243public:
244
245 /**
246 * Possible file access modes.
247 */
248 enum Mode { Mode_Read, Mode_WriteCreate, Mode_Overwrite, Mode_ReadWrite };
249
250 /**
251 * Opens a file with the given name in the given mode. If @a aMode is Read
252 * or ReadWrite, the file must exist. If @a aMode is Write, the file must
253 * not exist. Otherwise, an EIPRTFailure excetion will be thrown.
254 *
255 * @param aMode File mode.
256 * @param aFileName File name.
257 * @param aFlushIt Whether to flush a writable file before closing it.
258 */
259 File(Mode aMode, const char *aFileName, bool aFlushIt = false);
260
261 /**
262 * Uses the given file handle to perform file operations. This file
263 * handle must be already open in necessary mode (read, or write, or mixed).
264 *
265 * The read/write position of the given handle will be reset to the
266 * beginning of the file on success.
267 *
268 * Note that the given file handle will not be automatically closed upon
269 * this object destruction.
270 *
271 * @note It you pass the same RTFILE handle to more than one File instance,
272 * please make sure you have provided serialization in case if these
273 * instasnces are to be simultaneously used by different threads.
274 * Otherwise you may get garbage when reading or writing.
275 *
276 * @param aHandle Open file handle.
277 * @param aFileName File name (for reference).
278 * @param aFlushIt Whether to flush a writable file before closing it.
279 */
280 File(RTFILE aHandle, const char *aFileName = NULL, bool aFlushIt = false);
281
282 /**
283 * Destroys the File object. If the object was created from a file name
284 * the corresponding file will be automatically closed. If the object was
285 * created from a file handle, it will remain open.
286 */
287 virtual ~File();
288
289 const char *uri() const;
290
291 uint64_t pos() const;
292 void setPos(uint64_t aPos);
293
294 /**
295 * See Input::read(). If this method is called in wrong file mode,
296 * LogicError will be thrown.
297 */
298 int read(char *aBuf, int aLen);
299
300 /**
301 * See Output::write(). If this method is called in wrong file mode,
302 * LogicError will be thrown.
303 */
304 int write(const char *aBuf, int aLen);
305
306 /**
307 * See Output::truncate(). If this method is called in wrong file mode,
308 * LogicError will be thrown.
309 */
310 void truncate();
311
312private:
313
314 /* Obscure class data */
315 struct Data;
316 Data *m;
317
318 /* auto_ptr data doesn't have proper copy semantics */
319 DECLARE_CLS_COPY_CTOR_ASSIGN_NOOP (File)
320};
321
322/**
323 * The MemoryBuf class represents a stream implementation that reads from the
324 * memory buffer.
325 */
326class RT_DECL_CLASS MemoryBuf : public Input
327{
328public:
329
330 MemoryBuf (const char *aBuf, size_t aLen, const char *aURI = NULL);
331
332 virtual ~MemoryBuf();
333
334 const char *uri() const;
335
336 int read(char *aBuf, int aLen);
337 uint64_t pos() const;
338 void setPos(uint64_t aPos);
339
340private:
341 /* Obscure class data */
342 struct Data;
343 Data *m;
344
345 /* auto_ptr data doesn't have proper copy semantics */
346 DECLARE_CLS_COPY_CTOR_ASSIGN_NOOP(MemoryBuf)
347};
348
349
350/*
351 * GlobalLock
352 *
353 *
354 */
355
356typedef xmlParserInput* FNEXTERNALENTITYLOADER(const char *aURI,
357 const char *aID,
358 xmlParserCtxt *aCtxt);
359typedef FNEXTERNALENTITYLOADER *PFNEXTERNALENTITYLOADER;
360
361class RT_DECL_CLASS GlobalLock
362{
363public:
364 GlobalLock();
365 ~GlobalLock();
366
367 void setExternalEntityLoader(PFNEXTERNALENTITYLOADER pFunc);
368
369 static xmlParserInput* callDefaultLoader(const char *aURI,
370 const char *aID,
371 xmlParserCtxt *aCtxt);
372
373private:
374 /* Obscure class data. */
375 struct Data;
376 struct Data *m;
377};
378
379class ElementNode;
380typedef std::list<const ElementNode*> ElementNodesList;
381
382class AttributeNode;
383
384class ContentNode;
385
386/**
387 * Node base class.
388 *
389 * Cannot be used directly, but ElementNode, ContentNode and AttributeNode
390 * derive from this. This does implement useful public methods though.
391 *
392 *
393 */
394class RT_DECL_CLASS Node
395{
396public:
397 ~Node();
398
399 const char *getName() const;
400 const char *getPrefix() const;
401 const char *getNamespaceURI() const;
402 bool nameEquals(const char *pcszNamespace, const char *pcsz) const;
403 bool nameEquals(const char *pcsz) const
404 {
405 return nameEquals(NULL, pcsz);
406 }
407 bool nameEqualsN(const char *pcszNamespace, const char *pcsz, size_t cchMax) const;
408
409 const char *getValue() const;
410 bool copyValue(int32_t &i) const;
411 bool copyValue(uint32_t &i) const;
412 bool copyValue(int64_t &i) const;
413 bool copyValue(uint64_t &i) const;
414
415 /** @name Introspection.
416 * @{ */
417 /** Is this an ElementNode instance.
418 * @returns true / false */
419 bool isElement() const
420 {
421 return m_Type == IsElement;
422 }
423
424 /** Is this an ContentNode instance.
425 * @returns true / false */
426 bool isContent() const
427 {
428 return m_Type == IsContent;
429 }
430
431 /** Is this an AttributeNode instance.
432 * @returns true / false */
433 bool isAttribute() const
434 {
435 return m_Type == IsElement;
436 }
437
438 int getLineNumber() const;
439
440 /** @} */
441
442#ifndef USE_STD_LIST_FOR_CHILDREN
443 /** @name General tree enumeration.
444 *
445 * Use the introspection methods isElement() and isContent() before doing static
446 * casting. Parents are always or ElementNode type, but siblings and children
447 * can be of both ContentNode and ElementNode types.
448 *
449 * @remarks Careful mixing tree walking with node removal!
450 * @{
451 */
452 /** Get the parent node
453 * @returns Pointer to the parent node, or NULL if root. */
454 const Node *getParent() const
455 {
456 return m_pParent;
457 }
458
459 /** Get the first child node.
460 * @returns Pointer to the first child node, NULL if no children. */
461 const Node *getFirstChild() const
462 {
463 return RTListGetFirstCpp(&m_children, const Node, m_childEntry);
464 }
465
466 /** Get the last child node.
467 * @returns Pointer to the last child node, NULL if no children. */
468 const Node *getLastChild() const
469 {
470 return RTListGetLastCpp(&m_children, const Node, m_childEntry);
471 }
472
473 /** Get the previous sibling.
474 * @returns Pointer to the previous sibling node, NULL if first child. */
475 const Node *getPrevSibiling() const
476 {
477 if (!m_pParent)
478 return NULL;
479 return RTListGetPrevCpp(&m_pParent->m_children, this, const Node, m_childEntry);
480 }
481
482 /** Get the next sibling.
483 * @returns Pointer to the next sibling node, NULL if last child. */
484 const Node *getNextSibiling() const
485 {
486 if (!m_pParent)
487 return NULL;
488 return RTListGetNextCpp(&m_pParent->m_children, this, const Node, m_childEntry);
489 }
490 /** @} */
491#endif
492
493protected:
494 /** Node types. */
495 typedef enum { IsElement, IsAttribute, IsContent } EnumType;
496
497 EnumType m_Type; /**< The type of node this is an instance of. */
498 Node *m_pParent; /**< The parent node, NULL if root. */
499 xmlNode *m_plibNode; ///< != NULL if this is an element or content node
500 xmlAttr *m_plibAttr; ///< != NULL if this is an attribute node
501 const char *m_pcszNamespacePrefix; ///< not always set
502 const char *m_pcszNamespaceHref; ///< full http:// spec
503 const char *m_pcszName; ///< element or attribute name, points either into plibNode or plibAttr;
504 ///< NULL if this is a content node
505
506#ifndef USE_STD_LIST_FOR_CHILDREN
507 /** Child list entry of this node. (List head m_pParent->m_children.) */
508 RTLISTNODE m_childEntry;
509 /** Child elements, if this is an element; can be empty. */
510 RTLISTANCHOR m_children;
511#endif
512
513 // hide the default constructor so people use only our factory methods
514 Node(EnumType type,
515 Node *pParent,
516 xmlNode *plibNode,
517 xmlAttr *plibAttr);
518 Node(const Node &x); // no copying
519
520 void buildChildren(const ElementNode &elmRoot);
521
522 /* Obscure class data */
523 struct Data;
524 Data *m;
525
526 friend class AttributeNode;
527 friend class ElementNode; /* C list hack. */
528};
529
530/**
531 * Node subclass that represents an element.
532 *
533 * For elements, Node::getName() returns the element name, and Node::getValue()
534 * returns the text contents, if any.
535 *
536 * Since the Node constructor is private, one can create element nodes
537 * only through the following factory methods:
538 *
539 * -- Document::createRootElement()
540 * -- ElementNode::createChild()
541 */
542class RT_DECL_CLASS ElementNode : public Node
543{
544public:
545 int getChildElements(ElementNodesList &children,
546 const char *pcszMatch = NULL) const;
547
548 const ElementNode* findChildElement(const char *pcszNamespace,
549 const char *pcszMatch) const;
550 const ElementNode* findChildElement(const char *pcszMatch) const
551 {
552 return findChildElement(NULL, pcszMatch);
553 }
554 const ElementNode* findChildElementFromId(const char *pcszId) const;
555
556 const ElementNode *findChildElementDeep(const char *pcszNamespace, const char *pcszPath) const;
557 const ElementNode *findChildElementDeep(const char *pcszPath) const
558 {
559 return findChildElementDeep(NULL, pcszPath);
560 }
561
562 const AttributeNode* findAttribute(const char *pcszMatch) const;
563 bool getAttributeValue(const char *pcszMatch, const char *&pcsz) const;
564 bool getAttributeValue(const char *pcszMatch, RTCString &str) const;
565 bool getAttributeValuePath(const char *pcszMatch, RTCString &str) const;
566 bool getAttributeValue(const char *pcszMatch, int32_t &i) const;
567 bool getAttributeValue(const char *pcszMatch, uint32_t &i) const;
568 bool getAttributeValue(const char *pcszMatch, int64_t &i) const;
569 bool getAttributeValue(const char *pcszMatch, uint64_t &i) const;
570 bool getAttributeValue(const char *pcszMatch, bool &f) const;
571
572 /** @name Variants that for clarity does not use references for output params.
573 * @{ */
574 bool getAttributeValue(const char *pcszMatch, const char **ppcsz) const { return getAttributeValue(pcszMatch, *ppcsz); }
575 bool getAttributeValue(const char *pcszMatch, RTCString *pStr) const { return getAttributeValue(pcszMatch, *pStr); }
576 bool getAttributeValuePath(const char *pcszMatch, RTCString *pStr) const { return getAttributeValuePath(pcszMatch, *pStr); }
577 bool getAttributeValue(const char *pcszMatch, int32_t *pi) const { return getAttributeValue(pcszMatch, *pi); }
578 bool getAttributeValue(const char *pcszMatch, uint32_t *pu) const { return getAttributeValue(pcszMatch, *pu); }
579 bool getAttributeValue(const char *pcszMatch, int64_t *pi) const { return getAttributeValue(pcszMatch, *pi); }
580 bool getAttributeValue(const char *pcszMatch, uint64_t *pu) const { return getAttributeValue(pcszMatch, *pu); }
581 bool getAttributeValue(const char *pcszMatch, bool *pf) const { return getAttributeValue(pcszMatch, *pf); }
582 /** @} */
583
584
585 ElementNode* createChild(const char *pcszElementName);
586
587 ContentNode* addContent(const char *pcszContent);
588 ContentNode* addContent(const RTCString &strContent)
589 {
590 return addContent(strContent.c_str());
591 }
592
593 AttributeNode* setAttribute(const char *pcszName, const char *pcszValue);
594 AttributeNode* setAttribute(const char *pcszName, const RTCString &strValue)
595 {
596 return setAttribute(pcszName, strValue.c_str());
597 }
598 AttributeNode* setAttributePath(const char *pcszName, const RTCString &strValue);
599 AttributeNode* setAttribute(const char *pcszName, int32_t i);
600 AttributeNode* setAttribute(const char *pcszName, uint32_t i);
601 AttributeNode* setAttribute(const char *pcszName, int64_t i);
602 AttributeNode* setAttribute(const char *pcszName, uint64_t i);
603 AttributeNode* setAttributeHex(const char *pcszName, uint32_t i);
604 AttributeNode* setAttribute(const char *pcszName, bool f);
605
606protected:
607 // hide the default constructor so people use only our factory methods
608 ElementNode(const ElementNode *pelmRoot, Node *pParent, xmlNode *plibNode);
609 ElementNode(const ElementNode &x); // no copying
610
611 const ElementNode *m_pelmRoot;
612
613 friend class Node;
614 friend class Document;
615 friend class XmlFileParser;
616};
617
618/**
619 * Node subclass that represents content (non-element text).
620 *
621 * Since the Node constructor is private, one can create new content nodes
622 * only through the following factory methods:
623 *
624 * -- ElementNode::addContent()
625 */
626class RT_DECL_CLASS ContentNode : public Node
627{
628public:
629
630protected:
631 // hide the default constructor so people use only our factory methods
632 ContentNode(Node *pParent, xmlNode *plibNode);
633 ContentNode(const ContentNode &x); // no copying
634
635 friend class Node;
636 friend class ElementNode;
637};
638
639/**
640 * Node subclass that represents an attribute of an element.
641 *
642 * For attributes, Node::getName() returns the attribute name, and Node::getValue()
643 * returns the attribute value, if any.
644 *
645 * Since the Node constructor is private, one can create new attribute nodes
646 * only through the following factory methods:
647 *
648 * -- ElementNode::setAttribute()
649 */
650class RT_DECL_CLASS AttributeNode : public Node
651{
652public:
653
654protected:
655 // hide the default constructor so people use only our factory methods
656 AttributeNode(const ElementNode &elmRoot,
657 Node *pParent,
658 xmlAttr *plibAttr,
659 const char **ppcszKey);
660 AttributeNode(const AttributeNode &x); // no copying
661
662 RTCString m_strKey;
663
664 friend class Node;
665 friend class ElementNode;
666};
667
668/**
669 * Handy helper class with which one can loop through all or some children
670 * of a particular element. See NodesLoop::forAllNodes() for details.
671 */
672class RT_DECL_CLASS NodesLoop
673{
674public:
675 NodesLoop(const ElementNode &node, const char *pcszMatch = NULL);
676 ~NodesLoop();
677 const ElementNode* forAllNodes() const;
678
679private:
680 /* Obscure class data */
681 struct Data;
682 Data *m;
683};
684
685/**
686 * The XML document class. An instance of this needs to be created by a user
687 * of the XML classes and then passed to
688 *
689 * -- XmlMemParser or XmlFileParser to read an XML document; those classes then
690 * fill the caller's Document with ElementNode, ContentNode and AttributeNode
691 * instances. The typical sequence then is:
692 * @code
693 Document doc;
694 XmlFileParser parser;
695 parser.read("file.xml", doc);
696 Element *pelmRoot = doc.getRootElement();
697 @endcode
698 *
699 * -- XmlMemWriter or XmlFileWriter to write out an XML document after it has
700 * been created and filled. Example:
701 *
702 * @code
703 Document doc;
704 Element *pelmRoot = doc.createRootElement();
705 // add children
706 xml::XmlFileWriter writer(doc);
707 writer.write("file.xml", true);
708 @endcode
709 */
710class RT_DECL_CLASS Document
711{
712public:
713 Document();
714 ~Document();
715
716 Document(const Document &x);
717 Document& operator=(const Document &x);
718
719 const ElementNode* getRootElement() const;
720 ElementNode* getRootElement();
721
722 ElementNode* createRootElement(const char *pcszRootElementName,
723 const char *pcszComment = NULL);
724
725private:
726 friend class XmlMemParser;
727 friend class XmlFileParser;
728 friend class XmlMemWriter;
729 friend class XmlFileWriter;
730
731 void refreshInternals();
732
733 /* Obscure class data */
734 struct Data;
735 Data *m;
736};
737
738/*
739 * XmlParserBase
740 *
741 */
742
743class RT_DECL_CLASS XmlParserBase
744{
745protected:
746 XmlParserBase();
747 ~XmlParserBase();
748
749 xmlParserCtxtPtr m_ctxt;
750};
751
752/*
753 * XmlMemParser
754 *
755 */
756
757class RT_DECL_CLASS XmlMemParser : public XmlParserBase
758{
759public:
760 XmlMemParser();
761 ~XmlMemParser();
762
763 void read(const void* pvBuf, size_t cbSize, const RTCString &strFilename, Document &doc);
764};
765
766/*
767 * XmlFileParser
768 *
769 */
770
771class RT_DECL_CLASS XmlFileParser : public XmlParserBase
772{
773public:
774 XmlFileParser();
775 ~XmlFileParser();
776
777 void read(const RTCString &strFilename, Document &doc);
778
779private:
780 /* Obscure class data */
781 struct Data;
782 struct Data *m;
783
784 static int ReadCallback(void *aCtxt, char *aBuf, int aLen);
785 static int CloseCallback (void *aCtxt);
786};
787
788/*
789 * XmlMemParser
790 *
791 */
792
793class RT_DECL_CLASS XmlMemWriter
794{
795public:
796 XmlMemWriter();
797 ~XmlMemWriter();
798
799 void write(const Document &doc, void** ppvBuf, size_t *pcbSize);
800
801private:
802 void* m_pBuf;
803};
804
805/*
806 * XmlFileWriter
807 *
808 */
809
810class RT_DECL_CLASS XmlFileWriter
811{
812public:
813 XmlFileWriter(Document &doc);
814 ~XmlFileWriter();
815
816 /**
817 * Writes the XML document to the specified file.
818 *
819 * @param pcszFilename The name of the output file.
820 * @param fSafe If @c true, some extra safety precautions will be
821 * taken when writing the file:
822 * -# The file is written with a '-tmp' suffix.
823 * -# It is flushed to disk after writing.
824 * -# Any original file is renamed to '-prev'.
825 * -# The '-tmp' file is then renamed to the
826 * specified name.
827 * -# The directory changes are flushed to disk.
828 * The suffixes are available via s_pszTmpSuff and
829 * s_pszPrevSuff.
830 */
831 void write(const char *pcszFilename, bool fSafe);
832
833 static int WriteCallback(void *aCtxt, const char *aBuf, int aLen);
834 static int CloseCallback(void *aCtxt);
835
836 /** The suffix used by XmlFileWriter::write() for the temporary file. */
837 static const char * const s_pszTmpSuff;
838 /** The suffix used by XmlFileWriter::write() for the previous (backup) file. */
839 static const char * const s_pszPrevSuff;
840
841private:
842 void writeInternal(const char *pcszFilename, bool fSafe);
843
844 /* Obscure class data */
845 struct Data;
846 Data *m;
847};
848
849#if defined(_MSC_VER)
850#pragma warning (default:4251)
851#endif
852
853/** @} */
854
855} // end namespace xml
856
857#endif /* !___iprt_xml_h */
858
Note: See TracBrowser for help on using the repository browser.

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