00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
#ifndef _PXML_H
00063
#define _PXML_H
00064
00065
#ifdef P_USE_PRAGMA
00066
#pragma interface
00067
#endif
00068
00069
#include <ptlib.h>
00070
#include <ptclib/http.h>
00071
00073
00074
class PXMLElement;
00075
class PXMLData;
00076
00077 class PXMLParser :
public PObject
00078 {
00079
PCLASSINFO(
PXMLParser,
PObject);
00080
public:
00081 enum Options {
00082
Indent = 1,
00083
NewLineAfterElement = 2,
00084
NoIgnoreWhiteSpace = 4,
00085
CloseExtended = 8,
00086
WithNS = 16,
00087 };
00088
00089
PXMLParser(
int options = -1);
00090
~PXMLParser();
00091 BOOL Parse(
const char * data,
int dataLen, BOOL
final);
00092
void GetErrorInfo(
PString & errorString, PINDEX & errorCol, PINDEX & errorLine);
00093
00094
virtual void StartElement(
const char * name,
const char **attrs);
00095
virtual void EndElement(
const char * name);
00096
virtual void AddCharacterData(
const char * data,
int len);
00097
virtual void XmlDecl(
const char * version,
const char * encoding,
int standAlone);
00098
virtual void StartDocTypeDecl(
const char * docTypeName,
00099
const char * sysid,
00100
const char * pubid,
00101
int hasInternalSubSet);
00102
virtual void EndDocTypeDecl();
00103
virtual void StartNamespaceDeclHandler(
const char * prefix,
const char * uri);
00104
virtual void EndNamespaceDeclHandler(
const char * prefix);
00105
00106 PString GetVersion()
const {
return version; }
00107 PString GetEncoding()
const {
return encoding; }
00108 BOOL
GetStandAlone()
const {
return standAlone; }
00109
00110
PXMLElement *
GetXMLTree() const;
00111
PXMLElement * SetXMLTree(
PXMLElement * newRoot);
00112
00113 protected:
00114 int options;
00115 void * expat;
00116 PXMLElement * rootElement;
00117 PXMLElement * currentElement;
00118 PXMLData * lastElement;
00119 PString version, encoding;
00120 int standAlone;
00121 };
00122
00123 class
PXMLObject;
00124 class
PXMLElement;
00125 class
PXMLData;
00126
00128
00129 class
PXMLBase : public
PObject
00130 {
00131
public:
00132 PXMLBase(
int _options = -1)
00133 : options(_options) {
if (options < 0) options = 0; }
00134
00135 void SetOptions(
int _options)
00136 { options = _options; }
00137
00138 int GetOptions()
const {
return options; }
00139
00140 virtual BOOL IsNoIndentElement(
00141
const PString &
00142 )
const
00143
{
00144
return FALSE;
00145 }
00146
00147
protected:
00148 int options;
00149 };
00150
00151
00152 class PXML :
public PXMLBase
00153 {
00154
PCLASSINFO(
PXML,
PObject);
00155
public:
00156
00157
PXML(
00158
int options = -1,
00159
const char * noIndentElements = NULL
00160 );
00161
PXML(
00162
const PString & data,
00163
int options = -1,
00164
const char * noIndentElements = NULL
00165 );
00166
00167
PXML(
const PXML & xml);
00168
00169 ~
PXML();
00170
00171 BOOL IsDirty()
const;
00172
00173 BOOL Load(
const PString & data,
int options = -1);
00174
00175 BOOL StartAutoReloadURL(
const PURL & url,
00176
const PTimeInterval & timeout,
00177
const PTimeInterval & refreshTime,
00178
int _options = -1);
00179 BOOL StopAutoReloadURL();
00180 PString GetAutoReloadStatus() {
PWaitAndSignal m(autoLoadMutex);
PString str = autoLoadError;
return str; }
00181 BOOL AutoLoadURL();
00182
virtual void OnAutoLoad(BOOL ok);
00183
00184 BOOL LoadURL(
const PURL & url);
00185 BOOL LoadURL(
const PURL & url,
const PTimeInterval & timeout,
int _options = -1);
00186 BOOL LoadFile(
const PFilePath & fn,
int options = -1);
00187
00188 virtual void OnLoaded() { }
00189
00190 BOOL Save(
int options = -1);
00191 BOOL Save(
PString & data,
int options = -1);
00192 BOOL SaveFile(
const PFilePath & fn,
int options = -1);
00193
00194
void RemoveAll();
00195
00196 BOOL IsNoIndentElement(
00197
const PString & elementName
00198 )
const;
00199
00200
void PrintOn(ostream & strm)
const;
00201
00202
PXMLElement * GetElement(
const PCaselessString & name, PINDEX idx = 0)
const;
00203
PXMLElement * GetElement(PINDEX idx)
const;
00204 PINDEX GetNumElements() const;
00205 PXMLElement * GetRootElement()
const {
return rootElement; }
00206
PXMLElement * SetRootElement(
PXMLElement * p);
00207
PXMLElement * SetRootElement(
const PString & documentType);
00208 BOOL RemoveElement(PINDEX idx);
00209
00210
PCaselessString GetDocumentType() const;
00211
00212 PString GetErrorString()
const {
return errorString; }
00213 PINDEX GetErrorColumn()
const {
return errorCol; }
00214 PINDEX GetErrorLine()
const {
return errorLine; }
00215
00216 PMutex & GetMutex() {
return rootMutex; }
00217
00218
PDECLARE_NOTIFIER(
PTimer,
PXML, AutoReloadTimeout);
00219
PDECLARE_NOTIFIER(
PThread,
PXML, AutoReloadThread);
00220
00221
00222
static PString CreateStartTag (
const PString & text);
00223
static PString CreateEndTag (
const PString & text);
00224
static PString CreateTagNoData (
const PString & text);
00225
static PString CreateTag (
const PString & text,
const PString & data);
00226
00227
protected:
00228
void Construct(
int options,
const char * noIndentElements);
00229 PXMLElement * rootElement;
00230 PMutex rootMutex;
00231
00232 BOOL loadFromFile;
00233 PFilePath loadFilename;
00234 PString version, encoding;
00235 int standAlone;
00236
00237 PTimer autoLoadTimer;
00238 PURL autoloadURL;
00239 PTimeInterval autoLoadWaitTime;
00240 PMutex autoLoadMutex;
00241 PString autoLoadError;
00242
00243 PString errorString;
00244 PINDEX errorCol;
00245 PINDEX errorLine;
00246
00247 PSortedStringList noIndentElements;
00248 };
00249
00251
00252
PARRAY(PXMLObjectArray,
PXMLObject);
00253
00254 class PXMLObject :
public PObject {
00255
PCLASSINFO(
PXMLObject,
PObject);
00256
public:
00257 PXMLObject(
PXMLElement * _parent)
00258 : parent(_parent) { dirty = FALSE; }
00259
00260 PXMLElement * GetParent()
00261 {
return parent; }
00262
00263
PXMLObject * GetNextObject();
00264
00265 void SetParent(
PXMLElement * newParent)
00266 {
00267
PAssert(parent == NULL,
"Cannot reparent PXMLElement");
00268 parent = newParent;
00269 }
00270
00271
virtual void Output(ostream & strm,
const PXMLBase & xml,
int indent)
const = 0;
00272
00273
virtual BOOL IsElement() const = 0;
00274
00275
void SetDirty();
00276 BOOL IsDirty()
const {
return dirty; }
00277
00278
virtual PXMLObject *
Clone(
PXMLElement * parent)
const = 0;
00279
00280
protected:
00281 PXMLElement * parent;
00282 BOOL dirty;
00283 };
00284
00286
00287 class PXMLData :
public PXMLObject {
00288
PCLASSINFO(
PXMLData,
PXMLObject);
00289
public:
00290
PXMLData(
PXMLElement * _parent,
const PString & data);
00291
PXMLData(
PXMLElement * _parent,
const char * data,
int len);
00292
00293 BOOL IsElement()
const {
return FALSE; }
00294
00295
void SetString(
const PString & str, BOOL dirty = TRUE);
00296
00297 PString GetString()
const {
return value; }
00298
00299
void Output(ostream & strm,
const PXMLBase & xml,
int indent)
const;
00300
00301
PXMLObject *
Clone(
PXMLElement * parent)
const;
00302
00303
protected:
00304 PString value;
00305 };
00306
00308
00309 class PXMLElement :
public PXMLObject {
00310
PCLASSINFO(
PXMLElement,
PXMLObject);
00311
public:
00312
PXMLElement(
PXMLElement * _parent,
const char * name = NULL);
00313
PXMLElement(
PXMLElement * _parent,
const PString & name,
const PString & data);
00314
00315 BOOL IsElement()
const {
return TRUE; }
00316
00317
void PrintOn(ostream & strm)
const;
00318
void Output(ostream & strm,
const PXMLBase & xml,
int indent)
const;
00319
00320 PCaselessString GetName()
const
00321
{
return name; }
00322
00323 void SetName(
const PString & v)
00324 { name = v; }
00325
00326 PINDEX GetSize()
const
00327
{
return subObjects.GetSize(); }
00328
00329
PXMLObject * AddSubObject(
PXMLObject * elem, BOOL dirty = TRUE);
00330
00331
PXMLElement * AddChild (
PXMLElement * elem, BOOL dirty = TRUE);
00332
PXMLData * AddChild (
PXMLData * elem, BOOL dirty = TRUE);
00333
00334
void SetAttribute(
const PCaselessString & key,
00335
const PString & value,
00336 BOOL setDirty = TRUE);
00337
00338
PString GetAttribute(
const PCaselessString & key)
const;
00339
PString GetKeyAttribute(PINDEX idx)
const;
00340
PString GetDataAttribute(PINDEX idx)
const;
00341 BOOL HasAttribute(
const PCaselessString & key);
00342 BOOL HasAttributes()
const {
return attributes.GetSize() > 0; }
00343 PINDEX GetNumAttributes()
const {
return attributes.GetSize(); }
00344
00345
PXMLElement * GetElement(
const PCaselessString & name, PINDEX idx = 0)
const;
00346
PXMLObject * GetElement(PINDEX idx = 0)
const;
00347 BOOL RemoveElement(PINDEX idx);
00348
00349 PINDEX FindObject(
PXMLObject * ptr)
const;
00350
00351 BOOL HasSubObjects()
const
00352
{
return subObjects.GetSize() != 0; }
00353
00354 PXMLObjectArray GetSubObjects()
const
00355
{
return subObjects; }
00356
00357
PString GetData() const;
00358
00359
PXMLObject * Clone(
PXMLElement * parent) const;
00360
00361 protected:
00362 PCaselessString name;
00363 PStringToString attributes;
00364 PXMLObjectArray subObjects;
00365 BOOL dirty;
00366 };
00367
00369
00370 class
PXMLSettings : public
PXML
00371 {
00372
PCLASSINFO(
PXMLSettings, PXML);
00373
public:
00374
PXMLSettings(
int options = PXMLParser::NewLineAfterElement);
00375
PXMLSettings(
const PString & data,
int options = PXMLParser::NewLineAfterElement);
00376
PXMLSettings(
const PConfig & data,
int options = PXMLParser::NewLineAfterElement);
00377
00378 BOOL Load(
const PString & data);
00379 BOOL LoadFile(
const PFilePath & fn);
00380
00381 BOOL Save();
00382 BOOL Save(
PString & data);
00383 BOOL SaveFile(
const PFilePath & fn);
00384
00385
void SetAttribute(
const PCaselessString & section,
const PString & key,
const PString & value);
00386
00387
PString GetAttribute(
const PCaselessString & section,
const PString & key)
const;
00388 BOOL HasAttribute(
const PCaselessString & section,
const PString & key)
const;
00389
00390
void ToConfig(
PConfig & cfg)
const;
00391 };
00392
00394
00395 class PXMLStreamParser :
public PXMLParser
00396 {
00397
PCLASSINFO(
PXMLStreamParser,
PXMLParser);
00398
public:
00399
PXMLStreamParser();
00400
00401
virtual void EndElement(
const char * name);
00402
virtual PXML * Read(
PChannel * channel);
00403
00404
protected:
00405 BOOL rootOpen;
00406 PQueue<PXML> messages;
00407 };
00408
00409
#endif