30 static inline char*
Name(
void* arg) {
return (
char*)arg +
sizeof(
SXmlAttr_t); }
50 static inline char*
Name(
void* arg) {
return (
char*)arg +
sizeof(
SXmlNode_t); }
73 fOut =
new std::ofstream(filename);
87 fBuf = (
char*) malloc(bufsize);
119 int len = strlen(str);
122 fOut->write(str,len);
131 void Put(
char symb,
int cnt=1)
136 for(
int n=0;n<cnt;n++)
139 for(
int n=0;n<cnt;n++)
170 fInp =
new std::ifstream(filename);
176 fInpStrLen = filename==0 ? 0 : strlen(filename);
209 #if defined(__GNUC__) && (__GNUC__ >= 7)
210 #pragma GCC diagnostic push
211 #pragma GCC diagnostic ignored "-Wstringop-overflow"
218 fInp->get(buf, maxsize, 0);
219 maxsize = strlen(buf);
222 if (maxsize > 0) strncpy(buf,
fInpStr, maxsize);
229 #if defined(__GNUC__) && (__GNUC__ >= 7)
230 #pragma GCC diagnostic pop
239 if (newbuf==0)
return false;
244 curr = newbuf + (curr -
fBuf);
248 if (len==0)
return false;
274 for(
int n=0;n<sz;n++) {
292 if ((symb>26) && (symb!=
' '))
return true;
296 if (tillendl && (symb==10))
return true;
304 int len = strlen(str);
309 if (*str++ != *curr++)
return false;
317 int len = strlen(str);
324 const char *chk0 = curr;
325 const char *chk = str;
328 if (*chk++ != *chk0++) { find =
false;
break; }
339 bool ok = (((symb>=
'a') && (symb<=
'z')) ||
340 ((symb>=
'A') && (symb<=
'Z')) ||
351 ok = ((symb>=
'a') && (symb<=
'z')) ||
352 ((symb>=
'A') && (symb<=
'Z')) ||
353 ((symb>=
'0') && (symb<=
'9')) ||
354 (symb==
':') || (symb==
'_') || (symb==
'-') || (symb==
'.');
365 if (symb==
'<')
return curr -
fCurrent;
378 if (*curr!=
'=')
return 0;
382 if (*curr!=
'"')
return 0;
387 if (*curr==
'"')
return curr-start+1;
401 if ((xmlnode==0) || (name==0))
return false;
404 if (strcmp(SXmlAttr_t::Name(attr),name)==0)
return true;
415 if (xmlnode==0)
return 0;
418 if (strcmp(SXmlAttr_t::Name(attr),name)==0)
419 return SXmlAttr_t::Name(attr) + strlen(name) + 1;
430 if (xmlnode==0)
return 0;
432 const char* attr =
GetAttr(xmlnode, name);
433 if (attr) sscanf(attr,
"%d", &res);
439 const char* name,
const char* value)
444 if (xmlnode==0)
return 0;
446 int namelen(name != 0 ? strlen(name) : 0);
447 int valuelen(value != 0 ? strlen(value) : 0);
450 char* attrname = SXmlAttr_t::Name(attr);
452 strncpy(attrname, name, namelen+1);
455 attrname += (namelen + 1);
457 strncpy(attrname, value, valuelen+1);
472 sprintf(sbuf,
"%d",value);
473 return NewAttr(xmlnode, 0, name, sbuf);
481 if (xmlnode==0)
return;
485 if (strcmp(SXmlAttr_t::Name(attr),name)==0) {
504 if (xmlnode==0)
return;
522 if (xmlnode==0)
return 0;
526 if ((attr!=0) && (node->
fNs==attr)) attr = attr->
fNext;
536 if (xmlattr==0)
return 0;
546 if (xmlattr==0)
return 0;
548 return SXmlAttr_t::Name(xmlattr);
557 if (xmlattr==0)
return 0;
559 const char* attrname = SXmlAttr_t::Name(xmlattr);
560 return attrname + strlen(attrname) + 1;
565 const char* name,
const char* content)
569 int namelen(name!=0 ? strlen(name) : 0);
574 strncpy(SXmlNode_t::Name(node), name, namelen+1);
576 *SXmlNode_t::Name(node) = 0;
580 int contlen = strlen(content);
583 char* cptr = SXmlNode_t::Name(contnode);
587 strncpy(cptr, content, contlen+1);
601 if (name==0) name = SXmlNode_t::Name(node);
602 int namelen = strlen(name);
603 char* nsname =
new char[namelen+7];
604 snprintf(nsname, namelen+7,
"xmlns:%s", name);
611 node->
fAttr = nsattr;
612 nsattr->
fNext = first;
624 if (xmlnode==0)
return 0;
637 if ((nsname!=0) && (strncmp(nsname,
"xmlns:",6)==0)) nsname+=6;
656 if ((parent==0) || (child==0))
return;
676 if ((parent==0) || (child==0))
return;
693 if ((xmlnode==0) || (comment==0))
return false;
695 int commentlen = strlen(comment);
699 strncpy(SXmlNode_t::Name(node), comment, commentlen+1);
709 if (xmldoc==0)
return false;
728 if ((xmlnode==0) || (line==0))
return false;
730 int linelen = strlen(line);
733 strncpy(SXmlNode_t::Name(node), line, linelen+1);
773 if ((xmlnode==0) || (href==0) || (type==0))
return false;
775 const char* nodename =
"xml-stylesheet";
776 int nodenamelen = strlen(nodename);
780 strncpy(SXmlNode_t::Name(node), nodename, nodenamelen+1);
783 NewAttr(node, 0,
"alternate", (alternate>0) ?
"yes" :
"no");
785 if (title!=0)
NewAttr(node, 0,
"title", title);
787 NewAttr(node, 0,
"href", href);
788 NewAttr(node, 0,
"type", type);
790 if (media!=0)
NewAttr(node, 0,
"media", media);
791 if (charset!=0)
NewAttr(node, 0,
"charset", charset);
808 if (xmldoc==0)
return false;
814 href,type,title,alternate,media,charset);
826 if (xmlnode==0)
return;
831 if (parent==0)
return;
833 if (parent->
fChild==node) {
852 if (xmlnode==0)
return;
889 return xmlnode==0 ? 0 : SXmlNode_t::Name(xmlnode);
897 if (xmlnode==0)
return 0;
899 if (node->
fChild==0)
return 0;
900 const char* childname = SXmlNode_t::Name(node->
fChild);
901 if ((childname==0) || (*childname != 0))
return 0;
902 return childname + 1;
912 if ((res!=0) && (*SXmlNode_t::Name(res) == 0)) res = res->
fNext;
939 if ((xmlnode==0) || !tonode)
return;
966 if (xmlnode==0)
return;
991 NewAttr(vernode, 0,
"version", version);
1004 if (xmldoc==0)
return;
1017 if (xmldoc==0)
return;
1034 if (xmldoc==0)
return;
1054 if (xmldoc==0)
return;
1066 if (xmldoc==0)
return 0;
1082 if ((filename==0) || (strlen(filename)==0))
return 0;
1084 if (inp.
IsBad()) {
EOUT(
"File %s not found", filename);
return 0; }
1093 if ((xmlstring==0) || (strlen(xmlstring)==0))
return 0;
1103 if (inp == 0)
return 0;
1107 bool success =
false;
1114 if (resvalue!=2)
break;
1139 if (xmldoc==0)
return false;
1142 if (vernode==0)
return false;
1145 if (strcmp(
GetNodeName(vernode),
"xml")!=0)
return false;
1147 const char* value =
GetAttr(vernode,
"version");
1148 if (value==0)
return false;
1149 if (version==0) version =
"1.0";
1151 return strcmp(version,value)==0;
1163 if ((res==0) || (xmlnode==0))
return;
1167 SaveNode(xmlnode, &out, layout, 0);
1175 if (src==0)
return 0;
1197 if (str==0)
return 0;
1198 int len = strlen(str);
1199 if (len==0)
return 0;
1200 char* res =
new char[len+1];
1201 strncpy(res, str, len+1);
1210 if ((str==0) || (len==0))
return 0;
1211 char* res =
new char[len+1];
1212 strncpy(res, str, len);
1225 if (!node)
return nullptr;
1249 if (!attr)
return nullptr;
1274 const char* nsname = SXmlAttr_t::Name(node->
fNs) + 6;
1275 if (strcmp(nsname, name)==0)
return node->
fNs;
1288 if (node==0)
return;
1289 char* colon = strchr(SXmlNode_t::Name(node),
':');
1290 if (colon==0)
return;
1292 char* copyname = SXmlNode_t::Name(node);
1295 *(copyname++) = *(++colon);
1306 if ((srclen>3) && (*(source+1)==
'l') && (*(source+2)==
't') && (*(source+3)==
';')) {
1307 *target++ =
'<'; source+=4; srclen-=4;
1309 if ((srclen>3) && (*(source+1)==
'g') && (*(source+2)==
't') && (*(source+3)==
';')) {
1310 *target++ =
'>'; source+=4; srclen-=4;
1312 if ((srclen>4) && (*(source+1)==
'a') && (*(source+2)==
'm') && (*(source+3)==
'p') && (*(source+4)==
';')) {
1313 *target++ =
'&'; source+=5; srclen-=5;
1315 if ((srclen>5) && (*(source+1)==
'q') && (*(source+2)==
'u') && (*(source+3)==
'o') && (*(source+4)==
't') && (*(source+5)==
';')) {
1316 *target++ =
'\"'; source+=6; srclen-=6;
1318 if ((srclen>5) && (*(source+1)==
'a') && (*(source+2)==
'p') && (*(source+3)==
'o') && (*(source+4)==
's') && (*(source+5)==
';')) {
1319 *target++ =
'\''; source+=6; srclen-=6;
1321 *target++ = *source++; srclen--;
1324 *target++ = *source++;
1338 if (value==0)
return;
1342 while ((find=strpbrk(last,
"<&>\"\'")) !=0 ) {
1348 if (symb==
'<') out->
Write(
"<");
1349 else if (symb==
'>') out->
Write(
">");
1350 else if (symb==
'&') out->
Write(
"&");
1351 else if (symb==
'\'') out->
Write(
"'");
1352 else out->
Write(
""");
1363 if (xmlnode==0)
return;
1367 if (*SXmlNode_t::Name(node) == 0 ) {
1368 out->
Write(SXmlNode_t::Name(node)+1);
1372 bool issingleline = (node->
fChild==0);
1374 if (layout>0) out->
Put(
' ', level);
1378 out->
Write(SXmlNode_t::Name(node));
1380 if (layout>0) out->
Put(
'\n');
1384 out->
Write(SXmlNode_t::Name(node));
1385 if (layout>0) out->
Put(
'\n');
1394 out->
Write(SXmlAttr_t::Name(node->
fNs)+6);
1397 out->
Write(SXmlNode_t::Name(node));
1402 char* attrname = SXmlAttr_t::Name(attr);
1403 out->
Write(attrname);
1405 attrname += strlen(attrname) + 1;
1414 else out->
Write(
"/>");
1415 if (layout>0) out->
Put(
'\n');
1423 if ((content==0) && (layout>0))
1426 if (content!=0) out->
Write(content);
1432 if (layout>0) out->
Put(
'\n');
1435 child = child->fNext;
1439 if ((content==0) && (layout>0)) out->
Put(
' ',level);
1444 out->
Write(SXmlAttr_t::Name(node->
fNs)+6);
1447 out->
Write(SXmlNode_t::Name(node));
1449 if (layout>0) out->
Put(
'\n');
1463 if (inp==0)
return 0;
1464 if (!inp->
SkipSpaces()) { resvalue = -1;
return 0; }
1472 if (commentlen < 0) { resvalue = -10;
return 0; }
1476 char* nameptr = SXmlNode_t::Name(node);
1478 strncpy(nameptr, inp->
fCurrent, commentlen);
1479 nameptr+=commentlen;
1483 if (!inp->
ShiftCurrent(commentlen+3)) { resvalue = -1;
return node; }
1493 if ((parent==0) || (parent->
fChild!=0)) { resvalue = -2;
return 0; }
1495 if (contlen<0)
return 0;
1498 char* contptr = SXmlNode_t::Name(contnode);
1514 if (len<=0) { resvalue = -3;
return 0; }
1516 if (parent==0) { resvalue = -4;
return 0; }
1518 if (strncmp(SXmlNode_t::Name(parent), inp->
fCurrent, len)!=0) {
1538 bool canhaschilds =
true;
1539 char endsymbol =
'/';
1545 canhaschilds =
false;
1551 if (len<=0)
return 0;
1553 char* nameptr = SXmlNode_t::Name(node);
1554 node->
fType = nodetype;
1556 strncpy(nameptr, inp->
fCurrent, len);
1560 char* colon = strchr(SXmlNode_t::Name(node),
':');
1561 if ((colon!=0) && (parent!=0)) {
1574 if (nextsymb==endsymbol) {
1587 if (nextsymb==
'>') {
1588 if (!canhaschilds) { resvalue = -11;
return 0; }
1594 }
while (resvalue==2);
1602 if (attrlen<=0) { resvalue = -6;
return 0; }
1604 char* valuestart = inp->
fCurrent+attrlen;
1607 if (valuelen<3) { resvalue = -7;
return 0; }
1611 char* attrname = SXmlAttr_t::Name(attr);
1612 strncpy(attrname, inp->
fCurrent, attrlen);
1620 attrname = SXmlAttr_t::Name(attr);
1622 if ((strlen(attrname)>6) && (strstr(attrname,
"xmlns:")==attrname)) {
1623 if (strcmp(SXmlNode_t::Name(node), attrname + 6)!=0) {
1644 case -11:
EOUT(
"Node cannot be closed with > symbol at line %d, for instance <?xml ... ?> node", linenumber);
break;
1645 case -10:
EOUT(
"Error in xml comments definition at line %d, must be <!-- comments -->", linenumber);
break;
1646 case -9:
EOUT(
"Multiple name space definitions not allowed, line %d", linenumber);
break;
1647 case -8:
EOUT(
"Invalid namespace specification, line %d", linenumber);
break;
1648 case -7:
EOUT(
"Invalid attribute value, line %d", linenumber);
break;
1649 case -6:
EOUT(
"Invalid identifier for node attribute, line %d", linenumber);
break;
1650 case -5:
EOUT(
"Mismatch between open and close nodes, line %d", linenumber);
break;
1651 case -4:
EOUT(
"Unexpected close node, line %d", linenumber);
break;
1652 case -3:
EOUT(
"Valid identifier for close node is missing, line %d", linenumber);
break;
1653 case -2:
EOUT(
"No multiple content entries allowed, line %d", linenumber);
break;
1654 case -1:
EOUT(
"Unexpected end of xml file");
break;
1655 default:
EOUT(
"XML syntax error at line %d", linenumber);
break;
void Put(char symb, int cnt=1)
XmlOutputStream(const char *filename, int bufsize=20000)
void OutputChar(char symb)
virtual ~XmlOutputStream()
void Write(const char *str)
XmlOutputStream(std::string *outstr, int bufsize=20000)
XMLNsPointer_t FindNs(XMLNodePointer_t xmlnode, const char *nsname)
int GetIntAttr(XMLNodePointer_t node, const char *name)
bool ValidateVersion(XMLDocPointer_t doc, const char *version=nullptr)
void AssignDtd(XMLDocPointer_t xmldoc, const char *dtdname, const char *rootname)
void UnpackSpecialCharacters(char *target, const char *source, int srclen)
XMLDocPointer_t ParseFile(const char *filename, bool showerr=true)
void SaveDoc(XMLDocPointer_t xmldoc, const char *filename, int layout=1)
void FreeAttr(XMLNodePointer_t xmlnode, const char *name)
bool HasAttr(XMLNodePointer_t xmlnode, const char *name)
bool AddDocRawLine(XMLDocPointer_t xmldoc, const char *line)
void AddChildFirst(XMLNodePointer_t parent, XMLNodePointer_t child)
XMLAttrPointer_t GetFirstAttr(XMLNodePointer_t xmlnode)
bool AddRawLine(XMLNodePointer_t parent, const char *line)
XMLNodePointer_t DocGetRootElement(XMLDocPointer_t xmldoc)
void UnlinkFreeNode(XMLNodePointer_t xmlnode)
const char * GetAttrValue(XMLAttrPointer_t xmlattr)
XMLNodePointer_t GetNext(XMLNodePointer_t xmlnode)
XMLNodePointer_t GetParent(XMLNodePointer_t xmlnode)
const char * GetAttr(XMLNodePointer_t xmlnode, const char *name)
void SaveNode(XMLNodePointer_t xmlnode, XmlOutputStream *out, int layout, int level)
void UnlinkNode(XMLNodePointer_t node)
void AddChild(XMLNodePointer_t parent, XMLNodePointer_t child)
void FreeNode(XMLNodePointer_t xmlnode)
XMLAttrPointer_t NewAttr(XMLNodePointer_t xmlnode, XMLNsPointer_t, const char *name, const char *value)
XMLAttrPointer_t NewIntAttr(XMLNodePointer_t xmlnode, const char *name, int value)
XMLDocPointer_t ParseString(const char *xmlstring, bool showerr=true)
bool AddDocStyleSheet(XMLDocPointer_t xmldoc, const char *href, const char *type="text/css", const char *title=nullptr, int alternate=-1, const char *media=nullptr, const char *charset=nullptr)
void CleanNode(XMLNodePointer_t xmlnode)
const char * GetNodeName(XMLNodePointer_t xmlnode)
XMLNodePointer_t GetChild(XMLNodePointer_t xmlnode)
const char * GetNodeContent(XMLNodePointer_t xmlnode)
XMLNsPointer_t NewNS(XMLNodePointer_t xmlnode, const char *reference, const char *name=nullptr)
XMLNodePointer_t NewChild(XMLNodePointer_t parent, XMLNsPointer_t ns, const char *name, const char *content=nullptr)
XMLAttrPointer_t AllocateAttr(int namelen, int valuelen, XMLNodePointer_t xmlnode)
XMLNodePointer_t ReadSingleNode(const char *src)
XMLNodePointer_t ReadNode(XMLNodePointer_t xmlparent, XmlInputStream *inp, int &resvalue)
void FreeDoc(XMLDocPointer_t xmldoc)
const char * GetNSReference(XMLNsPointer_t ns)
void FreeAllAttr(XMLNodePointer_t xmlnode)
XMLNsPointer_t GetNS(XMLNodePointer_t xmlnode)
const char * GetAttrName(XMLAttrPointer_t xmlattr)
char * Makestr(const char *str)
void ShiftToNext(XMLNodePointer_t &xmlnode, bool tonode=true)
bool IsEmptyNode(XMLNodePointer_t xmlnode)
void SaveSingleNode(XMLNodePointer_t xmlnode, std::string *res, int layout=1)
bool AddComment(XMLNodePointer_t parent, const char *comment)
XMLAttrPointer_t GetNextAttr(XMLAttrPointer_t xmlattr)
void DisplayError(int error, int linenumber)
void SkipEmpty(XMLNodePointer_t &xmlnode)
XMLNodePointer_t AllocateNode(int namelen, XMLNodePointer_t parent)
bool AddStyleSheet(XMLNodePointer_t parent, const char *href, const char *type="text/css", const char *title=nullptr, int alternate=-1, const char *media=nullptr, const char *charset=nullptr)
void TruncateNsExtension(XMLNodePointer_t xmlnode)
const char * GetNSName(XMLNsPointer_t ns)
char * Makenstr(const char *start, int len)
XMLDocPointer_t NewDoc(const char *version="1.0")
void OutputValue(char *value, XmlOutputStream *out)
bool AddDocComment(XMLDocPointer_t xmldoc, const char *comment)
void DocSetRootElement(XMLDocPointer_t xmldoc, XMLNodePointer_t xmlnode)
XMLDocPointer_t ParseStream(XmlInputStream *input, bool showerr)
static char * Name(void *arg)
static char * Name(void *arg)