37 static inline char *Name(
void *arg) {
return (
char *)arg +
sizeof(SXmlAttr_t); }
54 SXmlNode_t *fLastChild;
58 static inline char *Name(
void *arg) {
return (
char *)arg +
sizeof(SXmlNode_t); }
62 SXmlNode_t *fRootNode;
67 class TXMLOutputStream {
77 TXMLOutputStream(
const char *filename, Int_t bufsize = 20000)
79 fOut =
new std::ofstream(filename);
84 TXMLOutputStream(TString *outstr, Int_t bufsize = 20000)
91 void Init(Int_t bufsize)
93 fBuf = (
char *)malloc(bufsize);
95 fMaxAddr = fBuf + bufsize;
96 fLimitAddr = fBuf + int(bufsize * 0.75);
99 virtual ~TXMLOutputStream()
101 if (fCurrent != fBuf)
109 if (fCurrent != fBuf) {
111 fOut->write(fBuf, fCurrent - fBuf);
112 else if (fOutStr != 0)
113 fOutStr->Append(fBuf, fCurrent - fBuf);
118 void OutputChar(
char symb)
122 else if (fOutStr != 0)
123 fOutStr->Append(symb);
126 void Write(
const char *str)
128 int len = strlen(str);
129 if (fCurrent + len >= fMaxAddr) {
131 fOut->write(str, len);
134 *fCurrent++ = *str++;
135 if (fCurrent > fLimitAddr)
140 void Put(
char symb, Int_t cnt = 1)
142 if (fCurrent + cnt >= fMaxAddr)
144 if (fCurrent + cnt >= fMaxAddr)
145 for (
int n = 0; n < cnt; n++)
148 for (
int n = 0; n < cnt; n++)
150 if (fCurrent > fLimitAddr)
156 class TXMLEntity :
public TNamed {
159 TXMLEntity() : TNamed(), fSystem(kFALSE) {}
160 TXMLEntity(
const TString &name,
const TString &value, Bool_t sys) : TNamed(name, value), fSystem(sys) {}
161 Bool_t IsSystem()
const {
return fSystem; }
164 class TXMLInputStream {
187 TXMLInputStream(Bool_t isfilename,
const char *filename, Int_t ibufsize)
188 : fInp(0), fInpStr(0), fInpStrLen(0), fBuf(0), fBufSize(0), fMaxAddr(0), fLimitAddr(0), fTotalPos(0),
189 fCurrentLine(0), fEntities(), fCurrent(0)
192 fInp =
new std::ifstream(filename);
198 fInpStrLen = filename == 0 ? 0 : strlen(filename);
202 fBuf = (
char *)malloc(fBufSize);
207 int len = DoRead(fBuf, fBufSize);
209 fMaxAddr = fBuf + len;
210 fLimitAddr = fBuf + int(len * 0.75);
215 fEntities.SetOwner(kTRUE);
221 virtual ~TXMLInputStream()
232 inline Bool_t EndOfFile() {
return (fInp != 0) ? fInp->eof() : (fInpStrLen <= 0); }
237 inline Bool_t EndOfStream() {
return EndOfFile() && (fCurrent >= fMaxAddr); }
242 void AddEntity(TXMLEntity *ent) { fEntities.Add(ent); }
247 Int_t NumEntities()
const {
return fEntities.GetLast() + 1; }
252 TXMLEntity *FindEntity(
const char *beg, Int_t len)
256 for (Int_t n = 0; n <= fEntities.GetLast(); n++) {
257 TXMLEntity *entity = (TXMLEntity *)fEntities[n];
258 if ((Int_t)strlen(entity->GetName()) != len)
260 if (strncmp(beg, entity->GetName(), len) == 0)
269 int DoRead(
char *buf,
int maxsize)
276 fInp->get(buf, maxsize, 0);
277 resultsize = strlen(buf);
279 resultsize = strlcpy(buf, fInpStr, maxsize);
280 if (resultsize >= maxsize)
281 resultsize = maxsize - 1;
282 fInpStr += resultsize;
283 fInpStrLen -= resultsize;
291 Bool_t ExpandStream(
char *&curr)
296 int curlength = fMaxAddr - fBuf;
297 char *newbuf = (
char *)realloc(fBuf, fBufSize);
301 fMaxAddr = newbuf + (fMaxAddr - fBuf);
302 fCurrent = newbuf + (fCurrent - fBuf);
303 fLimitAddr = newbuf + (fLimitAddr - fBuf);
304 curr = newbuf + (curr - fBuf);
307 int len = DoRead(fMaxAddr, fBufSize - curlength);
311 fLimitAddr += int(len * 0.75);
320 if (fCurrent < fLimitAddr)
324 int rest_len = fMaxAddr - fCurrent;
325 memmove(fBuf, fCurrent, rest_len);
326 int read_len = DoRead(fBuf + rest_len, fBufSize - rest_len);
329 fMaxAddr = fBuf + rest_len + read_len;
330 fLimitAddr = fBuf + int((rest_len + read_len) * 0.75);
337 Int_t TotalPos() {
return fTotalPos; }
342 Int_t CurrentLine() {
return fCurrentLine; }
347 Bool_t ShiftCurrent(Int_t sz = 1)
349 for (
int n = 0; n < sz; n++) {
352 if (fCurrent >= fLimitAddr) {
354 if (fCurrent >= fMaxAddr)
366 Bool_t SkipSpaces(Bool_t tillendl = kFALSE)
368 while (fCurrent < fMaxAddr) {
369 char symb = *fCurrent;
370 if ((symb > 26) && (symb !=
' '))
376 if (tillendl && (symb == 10))
385 Bool_t CheckFor(
const char *str)
387 int len = strlen(str);
388 char *curr = fCurrent;
389 while (curr + len > fMaxAddr) {
390 if (!ExpandStream(curr))
394 if (*str++ != *curr++)
396 return ShiftCurrent(len);
403 Int_t SearchFor(
const char *str)
405 int len = strlen(str);
407 char *curr = fCurrent;
411 while (curr + len > fMaxAddr)
412 if (!ExpandStream(curr))
415 const char *chk = str;
418 if (*chk++ != *chk0++) {
424 return curr - fCurrent;
425 }
while (curr < fMaxAddr);
432 inline Bool_t GoodStartSymbol(
unsigned char symb)
434 return (((symb >=
'a') && (symb <=
'z')) || ((symb >=
'A') && (symb <=
'Z')) || (symb ==
'_') ||
435 ((symb >= 0xc0) && (symb <= 0xd6)) || ((symb >= 0xd8) && (symb <= 0xf6)) || (symb > 0xf8));
441 Int_t LocateIdentifier()
443 unsigned char symb = (
unsigned char)*fCurrent;
445 Bool_t ok = GoodStartSymbol(symb);
449 char *curr = fCurrent;
453 if (curr >= fMaxAddr)
454 if (!ExpandStream(curr))
456 symb = (
unsigned char)*curr;
457 ok = GoodStartSymbol(symb) || ((symb >=
'0') && (symb <=
'9')) || (symb ==
':') || (symb ==
'-') ||
458 (symb ==
'.') || (symb == 0xb7);
460 return curr - fCurrent;
461 }
while (curr < fMaxAddr);
468 Int_t LocateContent()
470 char *curr = fCurrent;
471 while (curr < fMaxAddr) {
474 return curr - fCurrent;
476 if (curr >= fMaxAddr)
477 if (!ExpandStream(curr))
486 Int_t LocateValue(
unsigned curr_offset,
bool withequalsign =
true)
488 char *curr = fCurrent + curr_offset;
489 if (curr >= fMaxAddr)
490 if (!ExpandStream(curr))
496 if (curr >= fMaxAddr)
497 if (!ExpandStream(curr))
500 if ((*curr !=
'\"') && (*curr !=
'\''))
505 if (curr >= fMaxAddr)
506 if (!ExpandStream(curr))
509 return curr - (fCurrent + curr_offset) + 1;
510 }
while (curr < fMaxAddr);
518 TXMLEngine::TXMLEngine()
520 fSkipComments = kFALSE;
526 TXMLEngine::~TXMLEngine()
533 Bool_t TXMLEngine::HasAttr(XMLNodePointer_t xmlnode,
const char *name)
535 if ((xmlnode == 0) || (name == 0))
537 SXmlAttr_t *attr = ((SXmlNode_t *)xmlnode)->fAttr;
539 if (strcmp(SXmlAttr_t::Name(attr), name) == 0)
549 const char *TXMLEngine::GetAttr(XMLNodePointer_t xmlnode,
const char *name)
553 SXmlAttr_t *attr = ((SXmlNode_t *)xmlnode)->fAttr;
555 if (strcmp(SXmlAttr_t::Name(attr), name) == 0)
556 return SXmlAttr_t::Name(attr) + strlen(name) + 1;
565 Int_t TXMLEngine::GetIntAttr(XMLNodePointer_t xmlnode,
const char *name)
570 const char *attr = GetAttr(xmlnode, name);
572 sscanf(attr,
"%d", &res);
580 XMLAttrPointer_t TXMLEngine::NewAttr(XMLNodePointer_t xmlnode, XMLNsPointer_t,
const char *name,
const char *value)
585 int namelen(name != 0 ? strlen(name) : 0);
586 int valuelen(value != 0 ? strlen(value) : 0);
587 SXmlAttr_t *attr = (SXmlAttr_t *)AllocateAttr(namelen, valuelen, xmlnode);
589 char *attrname = SXmlAttr_t::Name(attr);
591 strncpy(attrname, name, namelen + 1);
594 attrname += (namelen + 1);
596 strncpy(attrname, value, valuelen + 1);
600 return (XMLAttrPointer_t)attr;
606 XMLAttrPointer_t TXMLEngine::NewIntAttr(XMLNodePointer_t xmlnode,
const char *name, Int_t value)
609 sprintf(sbuf,
"%d", value);
610 return NewAttr(xmlnode, 0, name, sbuf);
616 void TXMLEngine::FreeAttr(XMLNodePointer_t xmlnode,
const char *name)
620 SXmlAttr_t *attr = ((SXmlNode_t *)xmlnode)->fAttr;
621 SXmlAttr_t *prev = 0;
623 if (strcmp(SXmlAttr_t::Name(attr), name) == 0) {
625 prev->fNext = attr->fNext;
627 ((SXmlNode_t *)xmlnode)->fAttr = attr->fNext;
641 void TXMLEngine::FreeAllAttr(XMLNodePointer_t xmlnode)
646 SXmlNode_t *node = (SXmlNode_t *)xmlnode;
647 SXmlAttr_t *attr = node->fAttr;
649 SXmlAttr_t *next = attr->fNext;
659 XMLAttrPointer_t TXMLEngine::GetFirstAttr(XMLNodePointer_t xmlnode)
663 SXmlNode_t *node = (SXmlNode_t *)xmlnode;
665 SXmlAttr_t *attr = node->fAttr;
666 if ((attr != 0) && (node->fNs == attr))
669 return (XMLAttrPointer_t)attr;
675 XMLAttrPointer_t TXMLEngine::GetNextAttr(XMLAttrPointer_t xmlattr)
680 return (XMLAttrPointer_t)((SXmlAttr_t *)xmlattr)->fNext;
686 const char *TXMLEngine::GetAttrName(XMLAttrPointer_t xmlattr)
691 return SXmlAttr_t::Name(xmlattr);
697 const char *TXMLEngine::GetAttrValue(XMLAttrPointer_t xmlattr)
702 const char *attrname = SXmlAttr_t::Name(xmlattr);
703 return attrname + strlen(attrname) + 1;
709 XMLNodePointer_t TXMLEngine::NewChild(XMLNodePointer_t parent, XMLNsPointer_t ns,
const char *name,
const char *content)
711 int namelen(name != 0 ? strlen(name) : 0);
713 SXmlNode_t *node = (SXmlNode_t *)AllocateNode(namelen, parent);
716 strncpy(SXmlNode_t::Name(node), name, namelen + 1);
718 *SXmlNode_t::Name(node) = 0;
720 node->fNs = (SXmlAttr_t *)ns;
721 int contlen = (content != 0) ? strlen(content) : 0;
723 SXmlNode_t *contnode = (SXmlNode_t *)AllocateNode(contlen, node);
724 contnode->fType = kXML_CONTENT;
725 strncpy(SXmlNode_t::Name(contnode), content, contlen + 1);
728 return (XMLNodePointer_t)node;
735 XMLNsPointer_t TXMLEngine::NewNS(XMLNodePointer_t xmlnode,
const char *reference,
const char *name)
737 SXmlNode_t *node = (SXmlNode_t *)xmlnode;
739 name = SXmlNode_t::Name(node);
740 int namelen = strlen(name);
741 char *nsname =
new char[namelen + 7];
742 snprintf(nsname, namelen + 7,
"xmlns:%s", name);
744 SXmlAttr_t *first = node->fAttr;
747 SXmlAttr_t *nsattr = (SXmlAttr_t *)NewAttr(xmlnode, 0, nsname, reference);
749 node->fAttr = nsattr;
750 nsattr->fNext = first;
754 return (XMLNsPointer_t)nsattr;
760 XMLNsPointer_t TXMLEngine::GetNS(XMLNodePointer_t xmlnode)
764 SXmlNode_t *node = (SXmlNode_t *)xmlnode;
766 return (XMLNsPointer_t)node->fNs;
772 const char *TXMLEngine::GetNSName(XMLNsPointer_t ns)
774 const char *nsname = GetAttrName((XMLAttrPointer_t)ns);
776 if ((nsname != 0) && (strncmp(nsname,
"xmlns:", 6) == 0))
785 const char *TXMLEngine::GetNSReference(XMLNsPointer_t ns)
787 return GetAttrValue((XMLAttrPointer_t)ns);
793 void TXMLEngine::AddChild(XMLNodePointer_t parent, XMLNodePointer_t child)
795 if ((parent == 0) || (child == 0))
797 SXmlNode_t *pnode = (SXmlNode_t *)parent;
798 SXmlNode_t *cnode = (SXmlNode_t *)child;
803 cnode->fParent = pnode;
804 if (pnode->fLastChild == 0) {
805 pnode->fChild = cnode;
806 pnode->fLastChild = cnode;
810 pnode->fLastChild->fNext = cnode;
811 pnode->fLastChild = cnode;
818 void TXMLEngine::AddChildFirst(XMLNodePointer_t parent, XMLNodePointer_t child)
820 if ((parent == 0) || (child == 0))
822 SXmlNode_t *pnode = (SXmlNode_t *)parent;
823 SXmlNode_t *cnode = (SXmlNode_t *)child;
828 cnode->fParent = pnode;
830 cnode->fNext = pnode->fChild;
831 pnode->fChild = cnode;
833 if (pnode->fLastChild == 0)
834 pnode->fLastChild = cnode;
840 void TXMLEngine::AddChildAfter(XMLNodePointer_t parent, XMLNodePointer_t child, XMLNodePointer_t afternode)
842 if (afternode == 0) {
843 AddChild(parent, child);
847 SXmlNode_t *pnode = (SXmlNode_t *)parent;
848 SXmlNode_t *cnode = (SXmlNode_t *)child;
849 SXmlNode_t *anode = (SXmlNode_t *)afternode;
851 if (anode->fParent != pnode) {
852 Error(
"InsertChildAfter",
"Specified afternode is not in childs list of parent node");
853 AddChild(parent, child);
860 cnode->fParent = pnode;
862 cnode->fNext = anode->fNext;
863 anode->fNext = cnode;
865 if (pnode->fLastChild == anode)
866 pnode->fLastChild = cnode;
872 Bool_t TXMLEngine::AddComment(XMLNodePointer_t xmlnode,
const char *comment)
874 if ((xmlnode == 0) || (comment == 0))
877 int commentlen = strlen(comment);
879 SXmlNode_t *node = (SXmlNode_t *)AllocateNode(commentlen, xmlnode);
880 node->fType = kXML_COMMENT;
881 strncpy(SXmlNode_t::Name(node), comment, commentlen + 1);
889 Bool_t TXMLEngine::AddDocComment(XMLDocPointer_t xmldoc,
const char *comment)
894 XMLNodePointer_t rootnode = DocGetRootElement(xmldoc);
895 UnlinkNode(rootnode);
897 Bool_t res = AddComment(((SXmlDoc_t *)xmldoc)->fRootNode, comment);
899 AddChild((XMLNodePointer_t)((SXmlDoc_t *)xmldoc)->fRootNode, rootnode);
909 Bool_t TXMLEngine::AddRawLine(XMLNodePointer_t xmlnode,
const char *line)
911 if ((xmlnode == 0) || (line == 0))
914 int linelen = strlen(line);
915 SXmlNode_t *node = (SXmlNode_t *)AllocateNode(linelen, xmlnode);
916 node->fType = kXML_RAWLINE;
917 strncpy(SXmlNode_t::Name(node), line, linelen + 1);
926 Bool_t TXMLEngine::AddDocRawLine(XMLDocPointer_t xmldoc,
const char *line)
928 XMLNodePointer_t rootnode = DocGetRootElement(xmldoc);
929 UnlinkNode(rootnode);
931 Bool_t res = AddRawLine(((SXmlDoc_t *)xmldoc)->fRootNode, line);
933 AddChild((XMLNodePointer_t)((SXmlDoc_t *)xmldoc)->fRootNode, rootnode);
947 Bool_t TXMLEngine::AddStyleSheet(XMLNodePointer_t xmlnode,
const char *href,
const char *type,
const char *title,
948 int alternate,
const char *media,
const char *charset)
950 if ((xmlnode == 0) || (href == 0) || (type == 0))
953 const char *nodename =
"xml-stylesheet";
954 int nodenamelen = strlen(nodename);
956 SXmlNode_t *node = (SXmlNode_t *)AllocateNode(nodenamelen, xmlnode);
957 node->fType = kXML_PI_NODE;
958 strncpy(SXmlNode_t::Name(node), nodename, nodenamelen + 1);
961 NewAttr(node, 0,
"alternate", (alternate > 0) ?
"yes" :
"no");
964 NewAttr(node, 0,
"title", title);
966 NewAttr(node, 0,
"href", href);
967 NewAttr(node, 0,
"type", type);
970 NewAttr(node, 0,
"media", media);
972 NewAttr(node, 0,
"charset", charset);
980 Bool_t TXMLEngine::AddDocStyleSheet(XMLDocPointer_t xmldoc,
const char *href,
const char *type,
const char *title,
981 int alternate,
const char *media,
const char *charset)
986 XMLNodePointer_t rootnode = DocGetRootElement(xmldoc);
987 UnlinkNode(rootnode);
989 Bool_t res = AddStyleSheet(((SXmlDoc_t *)xmldoc)->fRootNode, href, type, title, alternate, media, charset);
991 AddChild((XMLNodePointer_t)((SXmlDoc_t *)xmldoc)->fRootNode, rootnode);
999 void TXMLEngine::UnlinkNode(XMLNodePointer_t xmlnode)
1004 SXmlNode_t *node = (SXmlNode_t *)xmlnode;
1005 SXmlNode_t *parent = node->fParent;
1010 if (parent->fChild == node) {
1011 parent->fChild = node->fNext;
1012 if (parent->fLastChild == node)
1013 parent->fLastChild = node->fNext;
1015 SXmlNode_t *ch = parent->fChild;
1016 while (ch->fNext != node)
1018 ch->fNext = node->fNext;
1019 if (parent->fLastChild == node)
1020 parent->fLastChild = ch;
1031 void TXMLEngine::FreeNode(XMLNodePointer_t xmlnode)
1035 SXmlNode_t *node = (SXmlNode_t *)xmlnode;
1037 SXmlNode_t *child = node->fChild;
1038 while (child != 0) {
1039 SXmlNode_t *next = child->fNext;
1040 FreeNode((XMLNodePointer_t)child);
1044 SXmlAttr_t *attr = node->fAttr;
1046 SXmlAttr_t *next = attr->fNext;
1060 void TXMLEngine::UnlinkFreeNode(XMLNodePointer_t xmlnode)
1062 UnlinkNode(xmlnode);
1069 const char *TXMLEngine::GetNodeName(XMLNodePointer_t xmlnode)
1071 return xmlnode == 0 ? 0 : SXmlNode_t::Name(xmlnode);
1077 const char *TXMLEngine::GetNodeContent(XMLNodePointer_t xmlnode)
1081 SXmlNode_t *node = (SXmlNode_t *)xmlnode;
1082 if (node->fChild == 0)
1085 if (node->fChild->fType != kXML_CONTENT)
1088 return SXmlNode_t::Name(node->fChild);
1095 void TXMLEngine::SetNodeContent(XMLNodePointer_t xmlnode,
const char *content, Int_t len)
1099 SXmlNode_t *node = (SXmlNode_t *)xmlnode;
1100 if ((node->fChild != 0) && (node->fChild->fType == kXML_CONTENT))
1101 UnlinkFreeNode((XMLNodePointer_t)node->fChild);
1106 len = strlen(content);
1108 SXmlNode_t *contnode = (SXmlNode_t *)AllocateNode(len, 0);
1109 char *nameptr = SXmlNode_t::Name(contnode);
1110 contnode->fType = kXML_CONTENT;
1111 strncpy(nameptr, content, len);
1115 AddChildFirst(xmlnode, (XMLNodePointer_t)contnode);
1122 void TXMLEngine::AddNodeContent(XMLNodePointer_t xmlnode,
const char *content, Int_t len)
1124 if ((xmlnode == 0) || (content == 0))
1127 len = strlen(content);
1129 SXmlNode_t *contnode = (SXmlNode_t *)AllocateNode(len, xmlnode);
1130 char *nameptr = SXmlNode_t::Name(contnode);
1131 contnode->fType = kXML_CONTENT;
1132 strncpy(nameptr, content, len);
1140 XMLNodePointer_t TXMLEngine::GetChild(XMLNodePointer_t xmlnode, Bool_t realnode)
1142 XMLNodePointer_t res = xmlnode == 0 ? 0 : ((SXmlNode_t *)xmlnode)->fChild;
1144 if (realnode && (res != 0) && (((SXmlNode_t *)res)->fType != kXML_NODE))
1145 ShiftToNext(res, kTRUE);
1152 XMLNodePointer_t TXMLEngine::GetParent(XMLNodePointer_t xmlnode)
1154 return xmlnode == 0 ? 0 : (XMLNodePointer_t)((SXmlNode_t *)xmlnode)->fParent;
1161 XMLNodePointer_t TXMLEngine::GetNext(XMLNodePointer_t xmlnode, Bool_t realnode)
1164 xmlnode = xmlnode == 0 ? 0 : (XMLNodePointer_t)((SXmlNode_t *)xmlnode)->fNext;
1165 if ((xmlnode == 0) || !realnode)
1167 }
while (((SXmlNode_t *)xmlnode)->fType != kXML_NODE);
1176 void TXMLEngine::ShiftToNext(XMLNodePointer_t &xmlnode, Bool_t realnode)
1179 xmlnode = xmlnode == 0 ? 0 : (XMLNodePointer_t)((SXmlNode_t *)xmlnode)->fNext;
1180 if ((xmlnode == 0) || !realnode)
1182 }
while (((SXmlNode_t *)xmlnode)->fType != kXML_NODE);
1188 Bool_t TXMLEngine::IsXmlNode(XMLNodePointer_t xmlnode)
1190 return xmlnode == 0 ? kFALSE : (((SXmlNode_t *)xmlnode)->fType == kXML_NODE);
1196 Bool_t TXMLEngine::IsEmptyNode(XMLNodePointer_t xmlnode)
1198 return xmlnode == 0 ? kTRUE : (((SXmlNode_t *)xmlnode)->fType != kXML_NODE);
1204 Bool_t TXMLEngine::IsContentNode(XMLNodePointer_t xmlnode)
1206 return xmlnode == 0 ? kFALSE : (((SXmlNode_t *)xmlnode)->fType == kXML_CONTENT);
1212 Bool_t TXMLEngine::IsCommentNode(XMLNodePointer_t xmlnode)
1214 return xmlnode == 0 ? kFALSE : (((SXmlNode_t *)xmlnode)->fType == kXML_COMMENT);
1220 void TXMLEngine::SkipEmpty(XMLNodePointer_t &xmlnode)
1222 if (IsEmptyNode(xmlnode))
1223 ShiftToNext(xmlnode);
1229 void TXMLEngine::CleanNode(XMLNodePointer_t xmlnode)
1233 SXmlNode_t *node = (SXmlNode_t *)xmlnode;
1235 SXmlNode_t *child = node->fChild;
1236 while (child != 0) {
1237 SXmlNode_t *next = child->fNext;
1238 FreeNode((XMLNodePointer_t)child);
1243 node->fLastChild = 0;
1249 XMLDocPointer_t TXMLEngine::NewDoc(
const char *version)
1251 SXmlDoc_t *doc =
new SXmlDoc_t;
1252 doc->fRootNode = (SXmlNode_t *)NewChild(0, 0,
"??DummyTopNode??", 0);
1255 XMLNodePointer_t vernode = NewChild((XMLNodePointer_t)doc->fRootNode, 0,
"xml");
1256 ((SXmlNode_t *)vernode)->fType = kXML_PI_NODE;
1257 NewAttr(vernode, 0,
"version", version);
1262 return (XMLDocPointer_t)doc;
1268 void TXMLEngine::AssignDtd(XMLDocPointer_t xmldoc,
const char *dtdname,
const char *rootname)
1272 SXmlDoc_t *doc = (SXmlDoc_t *)xmldoc;
1273 delete[] doc->fDtdName;
1274 doc->fDtdName = Makestr(dtdname);
1275 delete[] doc->fDtdRoot;
1276 doc->fDtdRoot = Makestr(rootname);
1282 void TXMLEngine::FreeDoc(XMLDocPointer_t xmldoc)
1286 SXmlDoc_t *doc = (SXmlDoc_t *)xmldoc;
1287 FreeNode((XMLNodePointer_t)doc->fRootNode);
1288 delete[] doc->fDtdName;
1289 delete[] doc->fDtdRoot;
1300 void TXMLEngine::SaveDoc(XMLDocPointer_t xmldoc,
const char *filename, Int_t layout)
1305 SXmlDoc_t *doc = (SXmlDoc_t *)xmldoc;
1307 TXMLOutputStream out(filename, 100000);
1309 XMLNodePointer_t child = GetChild((XMLNodePointer_t)doc->fRootNode, kFALSE);
1312 SaveNode(child, &out, layout, 0);
1313 ShiftToNext(child, kFALSE);
1314 }
while (child != 0);
1320 void TXMLEngine::DocSetRootElement(XMLDocPointer_t xmldoc, XMLNodePointer_t xmlnode)
1325 FreeNode(DocGetRootElement(xmldoc));
1327 AddChild((XMLNodePointer_t)((SXmlDoc_t *)xmldoc)->fRootNode, xmlnode);
1333 XMLNodePointer_t TXMLEngine::DocGetRootElement(XMLDocPointer_t xmldoc)
1338 XMLNodePointer_t xmlnode = (XMLNodePointer_t)((SXmlDoc_t *)xmldoc)->fRootNode;
1342 return GetChild(xmlnode, kTRUE);
1350 XMLDocPointer_t TXMLEngine::ParseFile(
const char *filename, Int_t maxbuf)
1352 if ((filename == 0) || (strlen(filename) == 0))
1354 if (maxbuf < 100000)
1356 TXMLInputStream inp(
true, filename, maxbuf);
1357 return ParseStream(&inp);
1363 XMLDocPointer_t TXMLEngine::ParseString(
const char *xmlstring)
1365 if ((xmlstring == 0) || (strlen(xmlstring) == 0))
1367 TXMLInputStream inp(
false, xmlstring, 100000);
1368 return ParseStream(&inp);
1374 XMLDocPointer_t TXMLEngine::ParseStream(TXMLInputStream *inp)
1379 XMLDocPointer_t xmldoc = NewDoc(0);
1381 Bool_t success =
false;
1386 ReadNode(((SXmlDoc_t *)xmldoc)->fRootNode, inp, resvalue);
1393 if (!inp->EndOfStream())
1396 if (inp->EndOfStream()) {
1403 DisplayError(resvalue, inp->CurrentLine());
1414 Bool_t TXMLEngine::ValidateVersion(XMLDocPointer_t xmldoc,
const char *version)
1419 XMLNodePointer_t vernode = GetChild((XMLNodePointer_t)((SXmlDoc_t *)xmldoc)->fRootNode, kFALSE);
1423 if (((SXmlNode_t *)vernode)->fType != kXML_PI_NODE)
1425 if (strcmp(GetNodeName(vernode),
"xml") != 0)
1428 const char *value = GetAttr(vernode,
"version");
1434 return strcmp(version, value) == 0;
1444 void TXMLEngine::SaveSingleNode(XMLNodePointer_t xmlnode, TString *res, Int_t layout)
1446 if ((res == 0) || (xmlnode == 0))
1449 TXMLOutputStream out(res, 10000);
1451 SaveNode(xmlnode, &out, layout, 0);
1457 XMLNodePointer_t TXMLEngine::ReadSingleNode(
const char *src)
1462 TXMLInputStream inp(
false, src, 10000);
1466 XMLNodePointer_t xmlnode = ReadNode(0, &inp, resvalue);
1468 if (resvalue <= 0) {
1469 DisplayError(resvalue, inp.CurrentLine());
1480 char *TXMLEngine::Makestr(
const char *str)
1484 int len = strlen(str);
1487 char *res =
new char[len + 1];
1488 strncpy(res, str, len + 1);
1495 char *TXMLEngine::Makenstr(
const char *str,
int len)
1497 if ((str == 0) || (len == 0))
1499 char *res =
new char[len + 1];
1500 strncpy(res, str, len);
1508 XMLNodePointer_t TXMLEngine::AllocateNode(
int namelen, XMLNodePointer_t parent)
1512 SXmlNode_t *node = (SXmlNode_t *)malloc(
sizeof(SXmlNode_t) + namelen + 1);
1514 node->fType = kXML_NODE;
1519 node->fLastChild = 0;
1523 AddChild(parent, (XMLNodePointer_t)node);
1525 return (XMLNodePointer_t)node;
1531 XMLAttrPointer_t TXMLEngine::AllocateAttr(
int namelen,
int valuelen, XMLNodePointer_t xmlnode)
1535 SXmlAttr_t *attr = (SXmlAttr_t *)malloc(
sizeof(SXmlAttr_t) + namelen + 1 + valuelen + 1);
1537 SXmlNode_t *node = (SXmlNode_t *)xmlnode;
1541 if (node->fAttr == 0)
1544 SXmlAttr_t *d = node->fAttr;
1545 while (d->fNext != 0)
1550 return (XMLAttrPointer_t)attr;
1556 XMLNsPointer_t TXMLEngine::FindNs(XMLNodePointer_t xmlnode,
const char *name)
1558 SXmlNode_t *node = (SXmlNode_t *)xmlnode;
1560 if (node->fNs != 0) {
1561 const char *nsname = SXmlAttr_t::Name(node->fNs) + 6;
1562 if (strcmp(nsname, name) == 0)
1565 node = node->fParent;
1573 void TXMLEngine::TruncateNsExtension(XMLNodePointer_t xmlnode)
1575 SXmlNode_t *node = (SXmlNode_t *)xmlnode;
1578 char *colon = strchr(SXmlNode_t::Name(node),
':');
1582 char *copyname = SXmlNode_t::Name(node);
1585 *(copyname++) = *(++colon);
1592 void TXMLEngine::UnpackSpecialCharacters(
char *target,
const char *source,
int srclen)
1594 while (srclen > 0) {
1595 if (*source ==
'&') {
1596 if ((srclen > 3) && (*(source + 1) ==
'l') && (*(source + 2) ==
't') && (*(source + 3) ==
';')) {
1600 }
else if ((srclen > 3) && (*(source + 1) ==
'g') && (*(source + 2) ==
't') && (*(source + 3) ==
';')) {
1604 }
else if ((srclen > 4) && (*(source + 1) ==
'a') && (*(source + 2) ==
'm') && (*(source + 3) ==
'p') &&
1605 (*(source + 4) ==
';')) {
1609 }
else if ((srclen > 5) && (*(source + 1) ==
'q') && (*(source + 2) ==
'u') && (*(source + 3) ==
'o') &&
1610 (*(source + 4) ==
't') && (*(source + 5) ==
';')) {
1614 }
else if ((srclen > 5) && (*(source + 1) ==
'a') && (*(source + 2) ==
'p') && (*(source + 3) ==
'o') &&
1615 (*(source + 4) ==
's') && (*(source + 5) ==
';')) {
1620 *target++ = *source++;
1624 *target++ = *source++;
1636 void TXMLEngine::OutputValue(
char *value, TXMLOutputStream *out)
1643 while ((find = strpbrk(last,
"<&>\"")) != 0) {
1651 else if (symb ==
'>')
1653 else if (symb ==
'&')
1654 out->Write(
"&");
1655 else if (symb ==
'\'')
1656 out->Write(
"'");
1658 out->Write(
""");
1667 void TXMLEngine::SaveNode(XMLNodePointer_t xmlnode, TXMLOutputStream *out, Int_t layout, Int_t level)
1671 SXmlNode_t *node = (SXmlNode_t *)xmlnode;
1673 Bool_t issingleline = (node->fChild == 0);
1676 out->Put(
' ', level);
1678 if (node->fType == kXML_COMMENT) {
1680 out->Write(SXmlNode_t::Name(node));
1685 }
else if (node->fType == kXML_RAWLINE) {
1686 out->Write(SXmlNode_t::Name(node));
1690 }
else if (node->fType == kXML_CONTENT) {
1691 out->Write(SXmlNode_t::Name(node));
1698 if (node->fType == kXML_PI_NODE)
1702 if ((node->fNs != 0) && (node->fNs != node->fAttr)) {
1703 out->Write(SXmlAttr_t::Name(node->fNs) + 6);
1706 out->Write(SXmlNode_t::Name(node));
1708 SXmlAttr_t *attr = node->fAttr;
1711 char *attrname = SXmlAttr_t::Name(attr);
1712 out->Write(attrname);
1714 attrname += strlen(attrname) + 1;
1715 OutputValue(attrname, out);
1722 if (node->fType == kXML_PI_NODE)
1733 SXmlNode_t *child = node->fChild;
1735 if ((child != 0) && (child->fType == kXML_CONTENT) && (child->fNext == 0)) {
1737 out->Write(SXmlNode_t::Name(child));
1741 while (child != 0) {
1742 SaveNode((XMLNodePointer_t)child, out, layout, level + 2);
1743 child = child->fNext;
1747 out->Put(
' ', level);
1752 if ((node->fNs != 0) && (node->fNs != node->fAttr)) {
1753 out->Write(SXmlAttr_t::Name(node->fNs) + 6);
1756 out->Write(SXmlNode_t::Name(node));
1769 XMLNodePointer_t TXMLEngine::ReadNode(XMLNodePointer_t xmlparent, TXMLInputStream *inp, Int_t &resvalue)
1775 if (!inp->SkipSpaces()) {
1779 SXmlNode_t *parent = (SXmlNode_t *)xmlparent;
1781 SXmlNode_t *node = 0;
1784 while (inp->CheckFor(
"<!--")) {
1785 Int_t commentlen = inp->SearchFor(
"-->");
1786 if (commentlen <= 0) {
1791 if (!fSkipComments) {
1792 node = (SXmlNode_t *)AllocateNode(commentlen, xmlparent);
1793 char *nameptr = SXmlNode_t::Name(node);
1794 node->fType = kXML_COMMENT;
1795 strncpy(nameptr, inp->fCurrent, commentlen);
1796 nameptr += commentlen;
1800 if (!inp->ShiftCurrent(commentlen + 3)) {
1804 if (!inp->SkipSpaces() && !inp->EndOfStream()) {
1813 if (*inp->fCurrent !=
'<') {
1820 int contlen = inp->LocateContent();
1824 SXmlNode_t *contnode = (SXmlNode_t *)AllocateNode(contlen, xmlparent);
1825 contnode->fType = kXML_CONTENT;
1826 char *contptr = SXmlNode_t::Name(contnode);
1827 UnpackSpecialCharacters(contptr, inp->fCurrent, contlen);
1828 if (!inp->ShiftCurrent(contlen))
1831 if (inp->NumEntities() <= 0) {
1838 const char *beg(0), *lastentity(0), *curr(contptr);
1840 while (*curr != 0) {
1841 if ((beg == 0) && (*curr ==
'&'))
1843 if ((beg == 0) || (*curr !=
';')) {
1848 TXMLEntity *entity = inp->FindEntity(beg + 1, curr - beg - 1);
1852 if (lastentity == 0) {
1853 lastentity = contptr;
1854 UnlinkNode(contnode);
1857 if (lastentity != beg)
1858 AddNodeContent(xmlparent, lastentity, beg - lastentity);
1860 if (entity->IsSystem()) {
1861 XMLDocPointer_t entitydoc = ParseFile(entity->GetTitle());
1862 if (entitydoc == 0) {
1867 XMLNodePointer_t topnode = DocGetRootElement(entitydoc);
1869 while (topnode != 0) {
1870 XMLNodePointer_t currnode = topnode;
1871 ShiftToNext(topnode,
false);
1872 UnlinkNode(currnode);
1873 AddChild(xmlparent, currnode);
1876 AddNodeContent(xmlparent, entity->GetTitle());
1886 if (lastentity != 0) {
1888 if (strlen(lastentity) > 0)
1889 AddNodeContent(xmlparent, lastentity);
1899 if (!inp->ShiftCurrent())
1903 if (*inp->fCurrent ==
'/') {
1905 if (!inp->ShiftCurrent())
1907 if (!inp->SkipSpaces())
1909 Int_t len = inp->LocateIdentifier();
1920 if (strncmp(SXmlNode_t::Name(parent), inp->fCurrent, len) != 0) {
1925 if (!inp->ShiftCurrent(len))
1928 if (!inp->SkipSpaces())
1930 if (*inp->fCurrent !=
'>')
1932 if (!inp->ShiftCurrent())
1935 if (parent->fNs != 0)
1936 TruncateNsExtension((XMLNodePointer_t)parent);
1938 inp->SkipSpaces(kTRUE);
1943 if (*inp->fCurrent ==
'!') {
1945 if (!inp->ShiftCurrent())
1947 if (!inp->CheckFor(
"DOCTYPE")) {
1951 if (!inp->SkipSpaces()) {
1957 Int_t len = inp->LocateIdentifier();
1962 if (!inp->ShiftCurrent(len)) {
1966 if (!inp->SkipSpaces()) {
1972 if (inp->CheckFor(
"[")) {
1973 if (!inp->SkipSpaces())
1976 if (inp->CheckFor(
"<!ENTITY")) {
1978 if (!inp->SkipSpaces()) {
1982 Int_t namelen = inp->LocateIdentifier();
1987 TString entity_name(inp->fCurrent, namelen);
1988 if (!inp->ShiftCurrent(namelen)) {
1992 if (!inp->SkipSpaces()) {
1996 Bool_t is_system = kFALSE;
1997 if (inp->CheckFor(
"SYSTEM")) {
1998 if (!inp->SkipSpaces()) {
2005 Int_t valuelen = inp->LocateValue(0,
false);
2011 TString entity_value(inp->fCurrent + 1, valuelen - 2);
2013 if (!inp->ShiftCurrent(valuelen)) {
2018 if (*inp->fCurrent !=
'>') {
2022 if (!inp->ShiftCurrent()) {
2028 inp->AddEntity(
new TXMLEntity(entity_name, entity_value, is_system));
2032 if (inp->CheckFor(
"<!ELEMENT")) {
2034 if (!inp->SkipSpaces()) {
2038 Int_t namelen = inp->LocateIdentifier();
2044 if (!inp->ShiftCurrent(namelen)) {
2048 if (!inp->SkipSpaces()) {
2053 if (!inp->CheckFor(
"(")) {
2057 if (inp->SearchFor(
")") <= 0) {
2063 if (*inp->fCurrent !=
'>') {
2067 if (!inp->ShiftCurrent()) {
2079 if (!inp->CheckFor(
"]")) {
2085 if (!inp->CheckFor(
">")) {
2094 EXmlNodeType nodetype = kXML_NODE;
2095 Bool_t canhaschildren =
true;
2096 char endsymbol =
'/';
2099 if (*inp->fCurrent ==
'?') {
2100 if (!inp->ShiftCurrent())
2102 nodetype = kXML_PI_NODE;
2103 canhaschildren =
false;
2107 if (!inp->SkipSpaces())
2109 Int_t len = inp->LocateIdentifier();
2112 node = (SXmlNode_t *)AllocateNode(len, xmlparent);
2113 char *nameptr = SXmlNode_t::Name(node);
2114 node->fType = nodetype;
2116 strncpy(nameptr, inp->fCurrent, len);
2120 char *colon = strchr(SXmlNode_t::Name(node),
':');
2121 if ((colon != 0) && (parent != 0)) {
2123 node->fNs = (SXmlAttr_t *)FindNs(xmlparent, SXmlNode_t::Name(node));
2127 if (!inp->ShiftCurrent(len))
2131 if (!inp->SkipSpaces())
2134 char nextsymb = *inp->fCurrent;
2136 if (nextsymb == endsymbol) {
2137 if (!inp->ShiftCurrent())
2139 if (*inp->fCurrent ==
'>') {
2140 if (!inp->ShiftCurrent())
2144 TruncateNsExtension((XMLNodePointer_t)node);
2146 inp->SkipSpaces(kTRUE);
2151 }
else if (nextsymb ==
'>') {
2152 if (!canhaschildren) {
2157 if (!inp->ShiftCurrent())
2161 ReadNode(node, inp, resvalue);
2162 }
while (resvalue == 2);
2164 if (resvalue == 1) {
2170 Int_t attrlen = inp->LocateIdentifier();
2176 int valuelen = inp->LocateValue(attrlen,
true);
2182 SXmlAttr_t *attr = (SXmlAttr_t *)AllocateAttr(attrlen, valuelen - 3, (XMLNodePointer_t)node);
2184 char *attrname = SXmlAttr_t::Name(attr);
2185 strncpy(attrname, inp->fCurrent, attrlen);
2186 attrname += attrlen;
2189 UnpackSpecialCharacters(attrname, inp->fCurrent + attrlen + 2, valuelen - 3);
2191 if (!inp->ShiftCurrent(attrlen + valuelen))
2194 attrname = SXmlAttr_t::Name(attr);
2196 if ((strlen(attrname) > 6) && (strstr(attrname,
"xmlns:") == attrname)) {
2197 if (strcmp(SXmlNode_t::Name(node), attrname + 6) != 0) {
2201 if (node->fNs != 0) {
2216 void TXMLEngine::DisplayError(Int_t error, Int_t linenumber)
2219 case -14: Error(
"ParseFile",
"Error include external XML file at line %d", linenumber);
break;
2220 case -13: Error(
"ParseFile",
"Error processing DTD part of XML file at line %d", linenumber);
break;
2221 case -12: Error(
"ParseFile",
"DOCTYPE missing after <! at line %d", linenumber);
break;
2223 Error(
"ParseFile",
"Node cannot be closed with > symbol at line %d, for instance <?xml ... ?> node", linenumber);
2226 Error(
"ParseFile",
"Error in xml comments definition at line %d, must be <!-- comments -->", linenumber);
2228 case -9: Error(
"ParseFile",
"Multiple namespace definitions not allowed, line %d", linenumber);
break;
2229 case -8: Error(
"ParseFile",
"Invalid namespace specification, line %d", linenumber);
break;
2230 case -7: Error(
"ParseFile",
"Invalid attribute value, line %d", linenumber);
break;
2231 case -6: Error(
"ParseFile",
"Invalid identifier for node attribute, line %d", linenumber);
break;
2232 case -5: Error(
"ParseFile",
"Mismatch between open and close nodes, line %d", linenumber);
break;
2233 case -4: Error(
"ParseFile",
"Unexpected close node, line %d", linenumber);
break;
2234 case -3: Error(
"ParseFile",
"Valid identifier for close node is missing, line %d", linenumber);
break;
2235 case -2: Error(
"ParseFile",
"No multiple content entries allowed, line %d", linenumber);
break;
2236 case -1: Error(
"ParseFile",
"Unexpected end of xml file");
break;
2237 default: Error(
"ParseFile",
"XML syntax error at line %d", linenumber);
break;