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 #include "TSAXParser.h"
00041 #include "TXMLAttr.h"
00042 #include "Varargs.h"
00043 #include "TObjString.h"
00044 #include "TList.h"
00045 #include "TClass.h"
00046
00047 #include <libxml/parser.h>
00048 #include <libxml/parserInternals.h>
00049
00050
00051 class TSAXParserCallback {
00052 public:
00053 static void StartDocument(void *fParser);
00054 static void EndDocument(void *fParser);
00055 static void StartElement(void *fParser, const xmlChar *name, const xmlChar **p);
00056 static void EndElement(void *fParser, const xmlChar *name);
00057 static void Characters(void *fParser, const xmlChar *ch, Int_t len);
00058 static void Comment(void *fParser, const xmlChar *value);
00059 static void CdataBlock(void *fParser, const xmlChar *value, Int_t len);
00060 static void Warning(void *fParser, const char *fmt, ...);
00061 static void Error(void *fParser, const char *fmt, ...);
00062 static void FatalError(void *fParser, const char *fmt, ...);
00063 };
00064
00065
00066 ClassImp(TSAXParser)
00067
00068
00069 TSAXParser::TSAXParser()
00070 {
00071
00072
00073 fSAXHandler = new xmlSAXHandler;
00074 memset(fSAXHandler, 0, sizeof(xmlSAXHandler));
00075
00076 fSAXHandler->startDocument =
00077 (startDocumentSAXFunc)TSAXParserCallback::StartDocument;
00078 fSAXHandler->endDocument =
00079 (endDocumentSAXFunc)TSAXParserCallback::EndDocument;
00080 fSAXHandler->startElement =
00081 (startElementSAXFunc)TSAXParserCallback::StartElement;
00082 fSAXHandler->endElement =
00083 (endElementSAXFunc)TSAXParserCallback::EndElement;
00084 fSAXHandler->characters =
00085 (charactersSAXFunc)TSAXParserCallback::Characters;
00086 fSAXHandler->comment =
00087 (commentSAXFunc)TSAXParserCallback::Comment;
00088 fSAXHandler->cdataBlock =
00089 (cdataBlockSAXFunc)TSAXParserCallback::CdataBlock;
00090 fSAXHandler->warning =
00091 (warningSAXFunc)TSAXParserCallback::Warning;
00092 fSAXHandler->error =
00093 (errorSAXFunc)TSAXParserCallback::Error;
00094 fSAXHandler->fatalError =
00095 (fatalErrorSAXFunc)TSAXParserCallback::FatalError;
00096 }
00097
00098
00099 TSAXParser::~TSAXParser()
00100 {
00101
00102
00103 ReleaseUnderlying();
00104
00105 delete fSAXHandler;
00106 }
00107
00108
00109 void TSAXParser::OnStartDocument()
00110 {
00111
00112
00113 Emit("OnStartDocument()");
00114 }
00115
00116
00117 void TSAXParser::OnEndDocument()
00118 {
00119
00120
00121 Emit("OnEndDocument()");
00122 }
00123
00124
00125 void TSAXParser::OnStartElement(const char *name, const TList *attributes)
00126 {
00127
00128
00129
00130
00131
00132 Long_t args[2];
00133 args[0] = (Long_t)name;
00134 args[1] = (Long_t)attributes;
00135
00136 Emit("OnStartElement(const char *, const TList *)", args);
00137 }
00138
00139
00140 void TSAXParser::OnEndElement(const char *name)
00141 {
00142
00143
00144 Emit("OnEndElement(const char *)", name);
00145 }
00146
00147
00148 void TSAXParser::OnCharacters(const char *characters)
00149 {
00150
00151
00152
00153 Emit("OnCharacters(const char *)", characters);
00154 }
00155
00156
00157 void TSAXParser::OnComment(const char *text)
00158 {
00159
00160
00161 Emit("OnComment(const char *)", text);
00162 }
00163
00164
00165 void TSAXParser::OnWarning(const char *text)
00166 {
00167
00168
00169 Emit("OnWarning(const char *)", text);
00170 }
00171
00172
00173 Int_t TSAXParser::OnError(const char *text)
00174 {
00175
00176
00177
00178 Emit("OnError(const char *)", text);
00179 return -3;
00180 }
00181
00182
00183 Int_t TSAXParser::OnFatalError(const char *text)
00184 {
00185
00186
00187
00188 Emit("OnFatalError(const char *)", text);
00189 return -4;
00190 }
00191
00192
00193 void TSAXParser::OnCdataBlock(const char *text, Int_t len)
00194 {
00195
00196
00197 Long_t args[2];
00198 args[0] = (Long_t)text;
00199 args[1] = len;
00200
00201 Emit("OnCdataBlock(const char *, Int_t)", args);
00202 }
00203
00204
00205 Int_t TSAXParser::Parse()
00206 {
00207
00208
00209
00210
00211
00212 if (!fContext) {
00213 return -2;
00214 }
00215
00216 xmlSAXHandlerPtr oldSAX = fContext->sax;
00217 fContext->sax = fSAXHandler;
00218 fContext->userData = this;
00219
00220 InitializeContext();
00221
00222 xmlParseDocument(fContext);
00223
00224 fContext->sax = oldSAX;
00225
00226 if (!fContext->wellFormed && fParseCode == 0) {
00227 fParseCode = -5;
00228 }
00229
00230 ReleaseUnderlying();
00231
00232 return fParseCode;
00233 }
00234
00235
00236 Int_t TSAXParser::ParseFile(const char *filename)
00237 {
00238
00239
00240
00241
00242
00243 if (fContext) {
00244 return -1;
00245 }
00246
00247 fContext = xmlCreateFileParserCtxt(filename);
00248 return Parse();
00249 }
00250
00251
00252 Int_t TSAXParser::ParseBuffer(const char *contents, Int_t len)
00253 {
00254
00255
00256
00257
00258
00259
00260 if (fContext) {
00261 return -1;
00262 }
00263
00264 fContext = xmlCreateMemoryParserCtxt(contents, len);
00265 return Parse();
00266 }
00267
00268
00269
00270
00271
00272 void TSAXParserCallback::StartDocument(void *fParser)
00273 {
00274
00275
00276 TSAXParser *parser = (TSAXParser*)fParser;
00277 parser->OnStartDocument();
00278 }
00279
00280
00281 void TSAXParserCallback::EndDocument(void *fParser)
00282 {
00283
00284
00285 TSAXParser *parser = (TSAXParser*)fParser;
00286 parser->OnEndDocument();
00287 }
00288
00289
00290 void TSAXParserCallback::StartElement(void *fParser, const xmlChar *name,
00291 const xmlChar **p)
00292 {
00293
00294
00295
00296 TSAXParser *parser = (TSAXParser*)fParser;
00297 TList *attributes = new TList;
00298
00299 if (p) {
00300 for (const xmlChar **cur = p; cur && *cur; cur += 2) {
00301 attributes->Add(new TXMLAttr((const char*)*cur,
00302 (const char*)*(cur + 1)));
00303 }
00304 }
00305
00306 parser->OnStartElement((const char*) name, attributes);
00307
00308 attributes->Delete();
00309 delete attributes;
00310 }
00311
00312
00313 void TSAXParserCallback::EndElement(void *fParser, const xmlChar *name)
00314 {
00315
00316
00317 TSAXParser *parser = (TSAXParser*)fParser;
00318 parser->OnEndElement((const char*) name);
00319 }
00320
00321
00322 void TSAXParserCallback::Characters(void *fParser, const xmlChar *ch,
00323 Int_t len)
00324 {
00325
00326
00327
00328
00329 TSAXParser *parser = (TSAXParser*)fParser;
00330
00331 char *str = new char[len+1];
00332 strlcpy(str, (const char*) ch, len+1);
00333 str[len] = '\0';
00334
00335 parser->OnCharacters(str);
00336
00337 delete [] str;
00338 }
00339
00340
00341 void TSAXParserCallback::Comment(void *fParser, const xmlChar *value)
00342 {
00343
00344
00345
00346 TSAXParser *parser = (TSAXParser*)fParser;
00347 parser->OnComment((const char*) value);
00348 }
00349
00350
00351 void TSAXParserCallback::Warning(void * fParser, const char *va_(fmt), ...)
00352 {
00353
00354
00355
00356 TSAXParser *parser = (TSAXParser*)fParser;
00357
00358 va_list arg;
00359 char buff[1024];
00360
00361 va_start(arg, va_(fmt));
00362 vsnprintf(buff, sizeof(buff)/sizeof(buff[0]), va_(fmt), arg);
00363 va_end(arg);
00364
00365 parser->OnWarning(buff);
00366 }
00367
00368
00369 void TSAXParserCallback::Error(void *fParser, const char *va_(fmt), ...)
00370 {
00371
00372
00373
00374 Int_t errorcode;
00375 TSAXParser *parser = (TSAXParser*)fParser;
00376 va_list arg;
00377 char buff[1024];
00378
00379 va_start(arg, va_(fmt));
00380 vsnprintf(buff, sizeof(buff)/sizeof(buff[0]), va_(fmt), arg);
00381 va_end(arg);
00382
00383 errorcode = parser->OnError(buff);
00384 if (errorcode < 0) {
00385 parser->SetParseCode(errorcode);
00386 }
00387
00388 if (errorcode < 0 && parser->GetStopOnError()) {
00389
00390 parser->StopParser();
00391 }
00392 }
00393
00394
00395 void TSAXParserCallback::FatalError(void *fParser, const char *va_(fmt), ...)
00396 {
00397
00398
00399
00400 Int_t errorcode;
00401 TSAXParser *parser = (TSAXParser*)fParser;
00402 va_list arg;
00403 char buff[1024];
00404
00405 va_start(arg, va_(fmt));
00406 vsnprintf(buff, sizeof(buff)/sizeof(buff[0]), va_(fmt), arg);
00407 va_end(arg);
00408
00409 errorcode = parser->OnFatalError(buff);
00410 if (errorcode < 0) {
00411 parser->SetParseCode(errorcode);
00412 parser->StopParser();
00413 }
00414 }
00415
00416
00417 void TSAXParserCallback::CdataBlock(void *fParser, const xmlChar *value,
00418 Int_t len)
00419 {
00420
00421
00422 TSAXParser *parser = (TSAXParser*)fParser;
00423 parser->OnCdataBlock((const char*)value, len);
00424 }
00425
00426
00427 void TSAXParser::ConnectToHandler(const char *handlerName, void *handler)
00428 {
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439 const TString kFunctionsName [] = {
00440 "OnStartDocument()",
00441 "OnEndDocument()",
00442 "OnStartElement(const char *, const TList *)",
00443 "OnEndElement(const char *)",
00444 "OnCharacters(const char *)",
00445 "OnComment(const char *)",
00446 "OnWarning(const char *)",
00447 "OnError(const char *)",
00448 "OnFatalError(const char *)",
00449 "OnCdataBlock(const char *, Int_t)"
00450 };
00451
00452 TClass *cl = TClass::GetClass(handlerName);
00453
00454 for (Int_t i = 0; i < 10; i++) {
00455 if (CheckConnectArgs(this, this->IsA(), kFunctionsName[i],
00456 cl, kFunctionsName[i]) != -1)
00457 Connect(kFunctionsName[i], handlerName, handler, kFunctionsName[i]);
00458 }
00459 }