Added classes for auto unlocking read only and read write mutex on
[pwlib.git] / include / ptclib / pxml.h
blobdf37ad4deb28289496ef4216d0d34235d0d1e9f6
1 /*
2 * pxml.h
4 * XML parser support
6 * Portable Windows Library
8 * Copyright (c) 2002 Equivalence Pty. Ltd.
10 * The contents of this file are subject to the Mozilla Public License
11 * Version 1.0 (the "License"); you may not use this file except in
12 * compliance with the License. You may obtain a copy of the License at
13 * http://www.mozilla.org/MPL/
15 * Software distributed under the License is distributed on an "AS IS"
16 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
17 * the License for the specific language governing rights and limitations
18 * under the License.
20 * The Original Code is Portable Windows Library.
22 * The Initial Developer of the Original Code is Equivalence Pty. Ltd.
24 * Contributor(s): ______________________________________.
26 * $Log$
27 * Revision 1.23 2004/04/21 00:35:02 csoutheren
28 * Added a stream parser for protocols like XMPP where each child of the root is to be considered a separate document/message.
29 * Thanks to Federico Pinna and Reitek S.p.A.
31 * Revision 1.22 2003/04/27 23:54:13 craigs
32 * Removed deprecated options
34 * Revision 1.21 2003/03/31 07:41:50 craigs
35 * Fixed problem with accidental introduced dependency on expat.h
37 * Revision 1.20 2003/03/31 06:21:19 craigs
38 * Split the expat wrapper from the XML file handling to allow reuse of the parser
40 * Revision 1.19 2003/01/13 02:14:02 robertj
41 * Improved error logging for auto-loaded XML
43 * Revision 1.18 2002/12/16 06:38:24 robertj
44 * Added ability to specify certain elemets (by name) that are exempt from
45 * the indent formatting. Useful for XML/RPC where leading white space is
46 * not ignored by all servers.
48 * Revision 1.17 2002/11/26 05:53:57 craigs
49 * Added ability to auto-reload from URL
51 * Revision 1.16 2002/11/21 08:09:04 craigs
52 * Changed to not overwrite XML data if load fails
54 * Revision 1.15 2002/11/19 07:37:38 craigs
55 * Added locking functions and LoadURL function
57 * Revision 1.14 2002/11/06 22:47:24 robertj
58 * Fixed header comment (copyright etc)
62 #ifndef _PXML_H
63 #define _PXML_H
65 #ifdef P_USE_PRAGMA
66 #pragma interface
67 #endif
69 #include <ptlib.h>
70 #include <ptclib/http.h>
72 ////////////////////////////////////////////////////////////
74 class PXMLElement;
75 class PXMLData;
77 class PXMLParser : public PObject
79 PCLASSINFO(PXMLParser, PObject);
80 public:
81 enum Options {
82 Indent = 1,
83 NewLineAfterElement = 2,
84 NoIgnoreWhiteSpace = 4, // ignored
85 CloseExtended = 8, // ignored
86 WithNS = 16,
89 PXMLParser(int options = -1);
90 ~PXMLParser();
91 BOOL Parse(const char * data, int dataLen, BOOL final);
92 void GetErrorInfo(PString & errorString, PINDEX & errorCol, PINDEX & errorLine);
94 virtual void StartElement(const char * name, const char **attrs);
95 virtual void EndElement(const char * name);
96 virtual void AddCharacterData(const char * data, int len);
97 virtual void XmlDecl(const char * version, const char * encoding, int standAlone);
98 virtual void StartDocTypeDecl(const char * docTypeName,
99 const char * sysid,
100 const char * pubid,
101 int hasInternalSubSet);
102 virtual void EndDocTypeDecl();
103 virtual void StartNamespaceDeclHandler(const char * prefix, const char * uri);
104 virtual void EndNamespaceDeclHandler(const char * prefix);
106 PString GetVersion() const { return version; }
107 PString GetEncoding() const { return encoding; }
108 BOOL GetStandAlone() const { return standAlone; }
110 PXMLElement * GetXMLTree() const;
111 PXMLElement * SetXMLTree(PXMLElement * newRoot);
113 protected:
114 int options;
115 void * expat;
116 PXMLElement * rootElement;
117 PXMLElement * currentElement;
118 PXMLData * lastElement;
119 PString version, encoding;
120 int standAlone;
123 class PXMLObject;
124 class PXMLElement;
125 class PXMLData;
127 ////////////////////////////////////////////////////////////
129 class PXMLBase : public PObject
131 public:
132 PXMLBase(int _options = -1)
133 : options(_options) { if (options < 0) options = 0; }
135 void SetOptions(int _options)
136 { options = _options; }
138 int GetOptions() const { return options; }
140 virtual BOOL IsNoIndentElement(
141 const PString & /*elementName*/
142 ) const
144 return FALSE;
147 protected:
148 int options;
152 class PXML : public PXMLBase
154 PCLASSINFO(PXML, PObject);
155 public:
157 PXML(
158 int options = -1,
159 const char * noIndentElements = NULL
161 PXML(
162 const PString & data,
163 int options = -1,
164 const char * noIndentElements = NULL
167 PXML(const PXML & xml);
169 ~PXML();
171 BOOL IsDirty() const;
173 BOOL Load(const PString & data, int options = -1);
175 BOOL StartAutoReloadURL(const PURL & url,
176 const PTimeInterval & timeout,
177 const PTimeInterval & refreshTime,
178 int _options = -1);
179 BOOL StopAutoReloadURL();
180 PString GetAutoReloadStatus() { PWaitAndSignal m(autoLoadMutex); PString str = autoLoadError; return str; }
181 BOOL AutoLoadURL();
182 virtual void OnAutoLoad(BOOL ok);
184 BOOL LoadURL(const PURL & url);
185 BOOL LoadURL(const PURL & url, const PTimeInterval & timeout, int _options = -1);
186 BOOL LoadFile(const PFilePath & fn, int options = -1);
188 virtual void OnLoaded() { }
190 BOOL Save(int options = -1);
191 BOOL Save(PString & data, int options = -1);
192 BOOL SaveFile(const PFilePath & fn, int options = -1);
194 void RemoveAll();
196 BOOL IsNoIndentElement(
197 const PString & elementName
198 ) const;
200 void PrintOn(ostream & strm) const;
202 PXMLElement * GetElement(const PCaselessString & name, PINDEX idx = 0) const;
203 PXMLElement * GetElement(PINDEX idx) const;
204 PINDEX GetNumElements() const;
205 PXMLElement * GetRootElement() const { return rootElement; }
206 PXMLElement * SetRootElement(PXMLElement * p);
207 PXMLElement * SetRootElement(const PString & documentType);
208 BOOL RemoveElement(PINDEX idx);
210 PCaselessString GetDocumentType() const;
212 PString GetErrorString() const { return errorString; }
213 PINDEX GetErrorColumn() const { return errorCol; }
214 PINDEX GetErrorLine() const { return errorLine; }
216 PMutex & GetMutex() { return rootMutex; }
218 PDECLARE_NOTIFIER(PTimer, PXML, AutoReloadTimeout);
219 PDECLARE_NOTIFIER(PThread, PXML, AutoReloadThread);
221 // static methods to create XML tags
222 static PString CreateStartTag (const PString & text);
223 static PString CreateEndTag (const PString & text);
224 static PString CreateTagNoData (const PString & text);
225 static PString CreateTag (const PString & text, const PString & data);
227 protected:
228 void Construct(int options, const char * noIndentElements);
229 PXMLElement * rootElement;
230 PMutex rootMutex;
232 BOOL loadFromFile;
233 PFilePath loadFilename;
234 PString version, encoding;
235 int standAlone;
237 PTimer autoLoadTimer;
238 PURL autoloadURL;
239 PTimeInterval autoLoadWaitTime;
240 PMutex autoLoadMutex;
241 PString autoLoadError;
243 PString errorString;
244 PINDEX errorCol;
245 PINDEX errorLine;
247 PSortedStringList noIndentElements;
250 ////////////////////////////////////////////////////////////
252 PARRAY(PXMLObjectArray, PXMLObject);
254 class PXMLObject : public PObject {
255 PCLASSINFO(PXMLObject, PObject);
256 public:
257 PXMLObject(PXMLElement * _parent)
258 : parent(_parent) { dirty = FALSE; }
260 PXMLElement * GetParent()
261 { return parent; }
263 PXMLObject * GetNextObject();
265 void SetParent(PXMLElement * newParent)
267 PAssert(parent == NULL, "Cannot reparent PXMLElement");
268 parent = newParent;
271 virtual void Output(ostream & strm, const PXMLBase & xml, int indent) const = 0;
273 virtual BOOL IsElement() const = 0;
275 void SetDirty();
276 BOOL IsDirty() const { return dirty; }
278 virtual PXMLObject * Clone(PXMLElement * parent) const = 0;
280 protected:
281 PXMLElement * parent;
282 BOOL dirty;
285 ////////////////////////////////////////////////////////////
287 class PXMLData : public PXMLObject {
288 PCLASSINFO(PXMLData, PXMLObject);
289 public:
290 PXMLData(PXMLElement * _parent, const PString & data);
291 PXMLData(PXMLElement * _parent, const char * data, int len);
293 BOOL IsElement() const { return FALSE; }
295 void SetString(const PString & str, BOOL dirty = TRUE);
297 PString GetString() const { return value; }
299 void Output(ostream & strm, const PXMLBase & xml, int indent) const;
301 PXMLObject * Clone(PXMLElement * parent) const;
303 protected:
304 PString value;
307 ////////////////////////////////////////////////////////////
309 class PXMLElement : public PXMLObject {
310 PCLASSINFO(PXMLElement, PXMLObject);
311 public:
312 PXMLElement(PXMLElement * _parent, const char * name = NULL);
313 PXMLElement(PXMLElement * _parent, const PString & name, const PString & data);
315 BOOL IsElement() const { return TRUE; }
317 void PrintOn(ostream & strm) const;
318 void Output(ostream & strm, const PXMLBase & xml, int indent) const;
320 PCaselessString GetName() const
321 { return name; }
323 void SetName(const PString & v)
324 { name = v; }
326 PINDEX GetSize() const
327 { return subObjects.GetSize(); }
329 PXMLObject * AddSubObject(PXMLObject * elem, BOOL dirty = TRUE);
331 PXMLElement * AddChild (PXMLElement * elem, BOOL dirty = TRUE);
332 PXMLData * AddChild (PXMLData * elem, BOOL dirty = TRUE);
334 void SetAttribute(const PCaselessString & key,
335 const PString & value,
336 BOOL setDirty = TRUE);
338 PString GetAttribute(const PCaselessString & key) const;
339 PString GetKeyAttribute(PINDEX idx) const;
340 PString GetDataAttribute(PINDEX idx) const;
341 BOOL HasAttribute(const PCaselessString & key);
342 BOOL HasAttributes() const { return attributes.GetSize() > 0; }
343 PINDEX GetNumAttributes() const { return attributes.GetSize(); }
345 PXMLElement * GetElement(const PCaselessString & name, PINDEX idx = 0) const;
346 PXMLObject * GetElement(PINDEX idx = 0) const;
347 BOOL RemoveElement(PINDEX idx);
349 PINDEX FindObject(PXMLObject * ptr) const;
351 BOOL HasSubObjects() const
352 { return subObjects.GetSize() != 0; }
354 PXMLObjectArray GetSubObjects() const
355 { return subObjects; }
357 PString GetData() const;
359 PXMLObject * Clone(PXMLElement * parent) const;
361 protected:
362 PCaselessString name;
363 PStringToString attributes;
364 PXMLObjectArray subObjects;
365 BOOL dirty;
368 ////////////////////////////////////////////////////////////
370 class PXMLSettings : public PXML
372 PCLASSINFO(PXMLSettings, PXML);
373 public:
374 PXMLSettings(int options = PXMLParser::NewLineAfterElement);
375 PXMLSettings(const PString & data, int options = PXMLParser::NewLineAfterElement);
376 PXMLSettings(const PConfig & data, int options = PXMLParser::NewLineAfterElement);
378 BOOL Load(const PString & data);
379 BOOL LoadFile(const PFilePath & fn);
381 BOOL Save();
382 BOOL Save(PString & data);
383 BOOL SaveFile(const PFilePath & fn);
385 void SetAttribute(const PCaselessString & section, const PString & key, const PString & value);
387 PString GetAttribute(const PCaselessString & section, const PString & key) const;
388 BOOL HasAttribute(const PCaselessString & section, const PString & key) const;
390 void ToConfig(PConfig & cfg) const;
393 ////////////////////////////////////////////////////////////
395 class PXMLStreamParser : public PXMLParser
397 PCLASSINFO(PXMLStreamParser, PXMLParser);
398 public:
399 PXMLStreamParser();
401 virtual void EndElement(const char * name);
402 virtual PXML * Read(PChannel * channel);
404 protected:
405 BOOL rootOpen;
406 PQueue<PXML> messages;
409 #endif