1 /* Copyright (c) 2007-2009 by Adalin B.V.
2 * Copyright (c) 2007-2009 by Erik Hofman
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of (any of) the copyrightholder(s) nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
16 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
17 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
18 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
19 * THE COPYRIGHT HOLDER BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 # define WIN32_LEAN_AND_MEAN
40 # include <sys/mman.h>
47 #include <stdlib.h> /* free, malloc */
50 #include <strings.h> /* strncasecmp */
52 # define strncasecmp strnicmp
56 #include <sys/types.h>
60 #ifndef XML_NONVALIDATING
63 static const char *__xml_error_str[XML_MAX_ERROR];
71 static void __xmlErrorSet(const void *, const char *, unsigned int);
72 # define xmlErrorSet(a, b, c) __xmlErrorSet(a, b, c)
73 #else /* !XML_NONVALIDATING */
74 # define xmlErrorSet(a, b, c)
78 * It is required for both the rood node and the normal xml nodes to both
79 * have 'char *name' defined as the first entry. The code tests whether
80 * name == 0 to detect the root node.
88 #ifndef XML_NONVALIDATING
89 struct _xml_error *info;
102 #ifndef XML_NONVALIDATING
103 struct _root_id *root;
107 static char *__xmlNodeCopy(const char *, size_t *, const char **);
108 static char *__xmlNodeGetPath(const char *, size_t *, char **, size_t *);
109 static char *__xmlNodeGet(const char *, size_t *, char **, size_t *, size_t *);
110 static char *__xmlCommentSkip(const char *, size_t);
111 static char *__xmlInfoProcess(const char *, size_t);
113 static void *__xml_memncasecmp(const char *, size_t *, char **, size_t *);
117 * map 'filename' and return a pointer to it.
119 static void *simple_mmap(int, size_t, SIMPLE_UNMMAP *);
120 static void simple_unmmap(SIMPLE_UNMMAP *);
122 # define mmap(a,b,c,d,e,f) simple_mmap((e), (b), &rid->un)
123 # define munmap(a,b) simple_unmmap(&rid->un)
127 # define PRINT(a, b, c) { \
130 if (b < c) len = b; \
132 printf("(%i) '", len); \
133 for (q=0; q<len; q++) printf("%c", ((char *)(a))[q]); \
135 } else printf("Length (%u) seems too large at line %i\n",len, __LINE__); \
136 } else printf("NULL pointer at line %i\n", __LINE__); \
141 xmlOpen(const char *filename)
143 struct _root_id *rid = 0;
147 int fd = open(filename, O_RDONLY);
150 rid = malloc(sizeof(struct _root_id));
157 mm = mmap(0, statbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0L);
158 if (mm != (void *)-1)
162 rid->len = statbuf.st_size;
164 #ifndef XML_NONVALIDATING
176 xmlInitBuffer(const char *buffer, size_t size)
178 struct _root_id *rid = 0;
180 if (buffer && (size > 0))
182 rid = malloc(sizeof(struct _root_id));
186 rid->start = (char *)buffer;
189 #ifndef XML_NONVALIDATING
201 struct _root_id *rid = (struct _root_id *)id;
204 assert(rid->name == 0);
208 munmap(rid->start, rid->len);
212 if (rid->info) free(rid->info);
218 xmlNodeGet(const void *id, const char *path)
220 struct _xml_id *xid = (struct _xml_id *)id;
221 struct _xml_id *xsid = 0;
231 ptr = __xmlNodeGetPath(xid->start, &len, &node, &slen);
234 xsid = malloc(sizeof(struct _xml_id));
239 xsid->name_len = slen;
241 #ifndef XML_NONVALIDATING
243 xsid->root = xid->root;
245 xsid->root = (struct _root_id *)xid;
250 xmlErrorSet(xid, 0, XML_OUT_OF_MEMORY);
255 xmlErrorSet(xid, node, len);
262 xmlNodeCopy(const void *id, const char *path)
264 struct _xml_id *xid = (struct _xml_id *)id;
265 struct _xml_id *xsid = 0;
266 char *ptr, *node, *p;
272 ptr = __xmlNodeGetPath(xid->start, &len, &node, &slen);
275 xsid = malloc(sizeof(struct _xml_id) + len);
278 p = (char *)xsid + sizeof(struct _xml_id);
282 xsid->name_len = slen;
284 #ifndef XML_NONVALIDATING
286 xsid->root = xid->root;
288 xsid->root = (struct _root_id *)xid;
291 memcpy(xsid->start, ptr, len);
295 xmlErrorSet(xid, 0, XML_OUT_OF_MEMORY);
300 xmlErrorSet(xid, node, len);
307 xmlNodeGetName(const void *id)
309 struct _xml_id *xid = (struct _xml_id *)id;
319 memcpy(ret, xid->name, len);
324 xmlErrorSet(xid, 0, XML_OUT_OF_MEMORY);
331 xmlNodeCopyName(const void *id, char *buf, size_t buflen)
333 struct _xml_id *xid = (struct _xml_id *)id;
339 slen = xid->name_len;
343 xmlErrorSet(xid, 0, XML_TRUNCATE_RESULT);
345 memcpy(buf, xid->name, slen);
352 xmlNodeGetNum(const void *id, const char *path)
354 struct _xml_id *xid = (struct _xml_id *)id;
362 char *nodename, *pathname;
366 nodename = (char *)path;
367 if (*path == '/') nodename++;
368 slen = strlen(nodename);
370 pathname = strchr(nodename, '/');
377 slen -= pathname-nodename;
379 p = __xmlNodeGetPath(xid->start, &len, &node, &slen);
380 if (p == 0 && slen == 0)
382 xmlErrorSet(xid, node, len);
393 char *ret, *node = nodename;
394 ret = __xmlNodeGet(p, &len, &node, &slen, &num);
395 if (ret == 0 && slen == 0)
397 xmlErrorSet(xid, node, len);
407 xmlNodeGetPos(const void *pid, void *id, const char *element, size_t num)
409 struct _xml_id *xpid = (struct _xml_id *)pid;
410 struct _xml_id *xid = (struct _xml_id *)id;
417 assert(element != 0);
420 slen = strlen(element);
421 node = (char *)element;
422 ptr = __xmlNodeGet(xpid->start, &len, &node, &slen, &num);
428 xid->name_len = slen;
433 xmlErrorSet(xpid, node, len);
440 xmlGetString(const void *id)
442 struct _xml_id *xid = (struct _xml_id *)id;
449 char *ps, *pe, *pend;
457 while ((ps<pe) && isspace(*ps)) ps++;
458 while ((pe>ps) && isspace(*pe)) pe--;
462 str = malloc(nlen+1);
465 memcpy(str, ps, nlen);
470 xmlErrorSet(xid, 0, XML_OUT_OF_MEMORY);
479 xmlCopyString(const void *id, char *buffer, size_t buflen)
481 struct _xml_id *xid = (struct _xml_id *)id;
490 char *ps, *pe, *pend;
500 while ((ps<pe) && isspace(*ps)) ps++;
501 while ((pe>ps) && isspace(*pe)) pe--;
503 if (nlen > slen) nlen = slen;
510 xmlErrorSet(xid, 0, XML_TRUNCATE_RESULT);
512 memcpy(buffer, ps, nlen);
522 xmlCompareString(const void *id, const char *s)
524 struct _xml_id *xid = (struct _xml_id *)id;
530 if (xid->len && (strlen(s) > 0))
538 while ((ps<pe) && isspace(*ps)) ps++;
539 while ((pe>ps) && isspace(*pe)) pe--;
542 ret = strncasecmp(ps, s, pe-ps);
549 xmlNodeGetString(const void *id, const char *path)
551 struct _xml_id *xid = (struct _xml_id *)id;
559 size_t len = xid->len;
560 char *node = (char *)path;
562 str = __xmlNodeCopy(xid->start, &len, &path);
565 char *ps, *pe, *pend;
573 while ((ps<pe) && isspace(*ps)) ps++;
574 while ((pe>ps) && isspace(*pe)) pe--;
578 if (slen && (ps>str)) memmove(str, ps, slen);
579 else if (!slen) *str = 0;
583 xmlErrorSet(xid, node, len);
591 xmlNodeCopyString(const void *id, const char *path, char *buffer, size_t buflen)
593 struct _xml_id *xid = (struct _xml_id *)id;
610 str = __xmlNodeGetPath(xid->start, &nlen, &node, &slen);
618 while ((ps<pe) && isspace(*ps)) ps++;
619 while ((pe>ps) && isspace(*pe)) pe--;
625 xmlErrorSet(xid, 0, XML_TRUNCATE_RESULT);
628 memcpy(buffer, ps, nlen);
629 *(buffer + nlen) = '\0';
634 xmlErrorSet(xid, node, nlen);
642 xmlNodeCompareString(const void *id, const char *path, const char *s)
644 struct _xml_id *xid = (struct _xml_id *)id;
651 if (xid->len && (strlen(s) > 0))
653 char *node, *str, *ps, *pe;
659 str = __xmlNodeGetPath(xid->start, &len, &node, &slen);
666 while ((ps<pe) && isspace(*ps)) ps++;
667 while ((pe>ps) && isspace(*pe)) pe--;
670 ret = strncasecmp(ps, s, pe-ps);
674 xmlErrorSet(xid, node, len);
682 xmlGetInt(const void *id)
684 struct _xml_id *xid = (struct _xml_id *)id;
691 char *end = xid->start + xid->len;
692 li = strtol(xid->start, &end, 10);
699 xmlNodeGetInt(const void *id, const char *path)
701 struct _xml_id *xid = (struct _xml_id *)id;
715 str = __xmlNodeGetPath(xid->start, &len, &node, &slen);
719 li = strtol(str, &end, 10);
723 xmlErrorSet(xid, node, len);
731 xmlGetDouble(const void *id)
733 struct _xml_id *xid = (struct _xml_id *)id;
740 char *end = xid->start + xid->len;
741 d = strtod(xid->start, &end);
748 xmlNodeGetDouble(const void *id, const char *path)
750 struct _xml_id *xid = (struct _xml_id *)id;
764 str = __xmlNodeGetPath(xid->start, &len, &node, &slen);
768 d = strtod(str, &end);
772 xmlErrorSet(xid, node, len);
780 xmlMarkId(const void *id)
782 struct _xml_id *xmid = 0;
786 xmid = malloc(sizeof(struct _xml_id));
789 struct _root_id *xrid = (struct _root_id *)id;
793 xmid->start = xrid->start;
794 xmid->len = xrid->len;
796 #ifndef XML_NONVALIDATING
802 memcpy(xmid, id, sizeof(struct _xml_id));
807 xmlErrorSet(id, 0, XML_OUT_OF_MEMORY);
814 xmlAttributeGetDouble(const void *id, const char *name)
816 struct _xml_id *xid = (struct _xml_id *)id;
824 size_t slen = strlen(name);
827 assert(xid->start > xid->name);
829 ps = xid->name + xid->name_len + 1;
833 while ((ps<pe) && isspace(*ps)) ps++;
834 if (((size_t)(pe-ps) > slen) && (strncasecmp(ps, name, slen) == 0))
837 if ((ps<pe) && (*ps == '='))
842 if (*ps == '"' || *ps == '\'') ps++;
845 xmlErrorSet(xid, ps, XML_ATTRIB_NO_OPENING_QUOTE);
850 while ((ps<pe) && (*ps != '"') && (*ps != '\'')) ps++;
853 ret = strtod(start, &ps);
857 xmlErrorSet(xid, ps, XML_ATTRIB_NO_CLOSING_QUOTE);
863 while ((ps<pe) && !isspace(*ps)) ps++;
870 while ((ps<pe) && !isspace(*ps)) ps++;
878 xmlAttributeGetInt(const void *id, const char *name)
880 struct _xml_id *xid = (struct _xml_id *)id;
888 size_t slen = strlen(name);
891 assert(xid->start > xid->name);
893 ps = xid->name + xid->name_len + 1;
897 while ((ps<pe) && isspace(*ps)) ps++;
898 if (((size_t)(pe-ps) > slen) && (strncasecmp(ps, name, slen) == 0))
901 if ((ps<pe) && (*ps == '='))
906 if (*ps == '"' || *ps == '\'') ps++;
909 xmlErrorSet(xid, ps, XML_ATTRIB_NO_OPENING_QUOTE);
914 while ((ps<pe) && (*ps != '"') && (*ps != '\'')) ps++;
917 ret = strtol(start, &ps, 10);
921 xmlErrorSet(xid, ps, XML_ATTRIB_NO_CLOSING_QUOTE);
927 while ((ps<pe) && isspace(*ps)) ps++;
934 while ((ps<pe) && !isspace(*ps)) ps++;
942 xmlAttributeGetString(const void *id, const char *name)
944 struct _xml_id *xid = (struct _xml_id *)id;
952 size_t slen = strlen(name);
955 assert(xid->start > xid->name);
957 ps = xid->name + xid->name_len + 1;
961 while ((ps<pe) && isspace(*ps)) ps++;
962 if (((size_t)(pe-ps) > slen) && (strncasecmp(ps, name, slen) == 0))
965 if ((ps<pe) && (*ps == '='))
970 if (*ps == '"' || *ps == '\'') ps++;
973 xmlErrorSet(xid, ps, XML_ATTRIB_NO_OPENING_QUOTE);
978 while ((ps<pe) && (*ps != '"') && (*ps != '\'')) ps++;
981 ret = malloc(ps-start);
984 memcpy(ret, start, (ps-start));
985 *(ret+(ps-start)) = '\0';
989 xmlErrorSet(xid, 0, XML_OUT_OF_MEMORY);
994 xmlErrorSet(xid, ps, XML_ATTRIB_NO_CLOSING_QUOTE);
1000 while ((ps<pe) && !isspace(*ps)) ps++;
1008 while ((ps<pe) && !isspace(*ps)) ps++;
1016 xmlAttributeCopyString(const void *id, const char *name,
1017 char *buffer, size_t buflen)
1019 struct _xml_id *xid = (struct _xml_id *)id;
1024 assert(buffer != 0);
1029 size_t slen = strlen(name);
1032 assert(xid->start > xid->name);
1035 ps = xid->name + xid->name_len + 1;
1036 pe = xid->start - 1;
1039 while ((ps<pe) && isspace(*ps)) ps++;
1040 if (((size_t)(pe-ps) > slen) && (strncasecmp(ps, name, slen) == 0))
1043 if ((ps<pe) && (*ps == '='))
1048 if (*ps == '"' || *ps == '\'') ps++;
1051 xmlErrorSet(xid, ps, XML_ATTRIB_NO_OPENING_QUOTE);
1056 while ((ps<pe) && (*ps != '"') && (*ps != '\'')) ps++;
1059 size_t restlen = ps-start;
1060 if (restlen >= buflen)
1063 xmlErrorSet(xid, ps, XML_TRUNCATE_RESULT);
1066 memcpy(buffer, start, restlen);
1067 *(buffer+restlen) = 0;
1072 xmlErrorSet(xid, ps, XML_ATTRIB_NO_CLOSING_QUOTE);
1078 while ((ps<pe) && isspace(*ps)) ps++;
1085 while ((ps<pe) && !isspace(*ps)) ps++;
1093 xmlAttributeCompareString(const void *id, const char *name, const char *s)
1095 struct _xml_id *xid = (struct _xml_id *)id;
1102 if (xid->name_len && strlen(s))
1104 size_t slen = strlen(name);
1107 assert(xid->start > xid->name);
1109 ps = xid->name + xid->name_len + 1;
1110 pe = xid->start - 1;
1113 while ((ps<pe) && isspace(*ps)) ps++;
1114 if (((size_t)(pe-ps) > slen) && (strncasecmp(ps, name, slen) == 0))
1117 if ((ps<pe) && (*ps == '='))
1122 if (*ps == '"' || *ps == '\'') ps++;
1125 xmlErrorSet(xid, ps, XML_ATTRIB_NO_OPENING_QUOTE);
1130 while ((ps<pe) && (*ps != '"') && (*ps != '\'')) ps++;
1133 ret = strncasecmp(start, s, ps-start);
1137 xmlErrorSet(xid, ps, XML_ATTRIB_NO_CLOSING_QUOTE);
1143 while ((ps<pe) && !isspace(*ps)) ps++;
1150 while ((ps<pe) && !isspace(*ps)) ps++;
1158 #ifndef XML_NONVALIDATING
1160 xmlErrorGetNo(const void *id, int clear)
1166 struct _xml_id *xid = (struct _xml_id *)id;
1167 struct _root_id *rid;
1169 if (xid->name) rid = xid->root;
1170 else rid = (struct _root_id *)xid;
1176 struct _xml_error *err = rid->info;
1179 if (clear) err->err_no = 0;
1187 xmlErrorGetLineNo(const void *id, int clear)
1193 struct _xml_id *xid = (struct _xml_id *)id;
1194 struct _root_id *rid;
1196 if (xid->name) rid = xid->root;
1197 else rid = (struct _root_id *)xid;
1203 struct _xml_error *err = rid->info;
1204 char *ps = rid->start;
1205 char *pe = err->pos;
1211 new = memchr(ps, '\n', pe-ps);
1217 if (clear) err->err_no = 0;
1225 xmlErrorGetColumnNo(const void *id, int clear)
1231 struct _xml_id *xid = (struct _xml_id *)id;
1232 struct _root_id *rid;
1234 if (xid->name) rid = xid->root;
1235 else rid = (struct _root_id *)xid;
1241 struct _xml_error *err = rid->info;
1242 char *ps = rid->start;
1243 char *pe = err->pos;
1248 new = memchr(ps, '\n', pe-ps);
1249 new = memchr(ps, '\n', pe-ps);
1256 if (clear) err->err_no = 0;
1264 xmlErrorGetString(const void *id, int clear)
1270 struct _xml_id *xid = (struct _xml_id *)id;
1271 struct _root_id *rid;
1273 if (xid->name) rid = xid->root;
1274 else rid = (struct _root_id *)xid;
1280 struct _xml_error *err = rid->info;
1281 if (XML_NO_ERROR <= err->err_no && err->err_no < XML_MAX_ERROR)
1283 ret = (char *)__xml_error_str[err->err_no];
1287 ret = "incorrect error number.";
1290 if (clear) err->err_no = 0;
1298 /* -------------------------------------------------------------------------- */
1300 #ifndef XML_NONVALIDATING
1301 static const char *__xml_error_str[XML_MAX_ERROR] =
1304 "unable to allocate enough memory.",
1305 "unable to open file for reading.",
1306 "buffer too small to hold all data, truncating.",
1307 "incorrect comment section.",
1308 "bad information block.",
1309 "unexpected end of section.",
1310 "incompatible opening tag for element.",
1311 "missing or invalid closing tag for element.",
1312 "missing or invalid opening quote for attribute.",
1313 "missing or invalid closing quote for attribute."
1318 __xmlNodeCopy(const char *start, size_t *len, const char **path)
1320 char *node, *p, *ret = 0;
1324 slen = strlen(*path);
1325 node = (char *)*path;
1326 p = __xmlNodeGetPath(start, &rlen, &node, &slen);
1329 ret = malloc(rlen+1);
1332 memcpy(ret, p, rlen);
1337 xmlErrorSet(0, 0, XML_OUT_OF_MEMORY);
1350 __xmlNodeGetPath(const char *start, size_t *len, char **name, size_t *plen)
1363 if (*plen > *len) return 0;
1366 if (*node == '/') node++;
1373 slen = strlen(node);
1374 path = strchr(node, '/');
1376 if (!path) plen = slen;
1377 else plen = path++ - node;
1380 ret = __xmlNodeGet(start, len, &node, &plen, &num);
1383 plen = slen - (path - *name);
1384 ret = __xmlNodeGetPath(ret, len, &path, &plen);
1397 __xmlNodeGet(const char *start, size_t *len, char **name, size_t *rlen, size_t *nodenum)
1399 char *open_element = *name;
1400 char *element, *start_tag=0;
1401 char *new, *cur, *ne, *ret = 0;
1402 size_t restlen, elementlen;
1403 size_t open_len = *rlen;
1404 size_t return_len = 0;
1414 assert(nodenum != 0);
1419 *name = (char *)start;
1420 *len = XML_UNEXPECTED_EOF;
1427 cur = (char *)start;
1430 /* search for an opening tag */
1431 while ((new = memchr(cur, '<', restlen)) != 0)
1433 size_t len_remaining;
1436 if (*(new+1) == '/') /* end of section */
1446 if (*cur == '!') /* comment */
1448 new = __xmlCommentSkip(cur, restlen);
1453 *len = XML_INVALID_COMMENT;
1460 else if (*cur == '?') /* info block */
1462 new = __xmlInfoProcess(cur, restlen);
1467 *len = XML_INVALID_INFO_BLOCK;
1477 * get element name and a pointer to after the opening tag
1481 len_remaining = restlen;
1482 new = rptr = __xml_memncasecmp(cur, &restlen, &element, &elementlen);
1483 if (rptr) /* requested element was found */
1485 return_len = elementlen;
1489 open_len = elementlen;
1490 start_tag = element;
1494 else /* different element name was foud */
1496 new = cur + (len_remaining - restlen);
1501 *len = XML_UNEXPECTED_EOF;
1507 if (*(new-2) == '/') /* e.g. <test/> */
1514 open_element = start_tag;
1523 * get the next xml tag
1525 /* restlen -= new-cur; not necessary because of __xml_memncasecmp */
1527 new = memchr(cur, '<', restlen);
1532 *len = XML_ELEMENT_NO_CLOSING_TAG;
1539 if (*cur == '!') /* comment */
1541 new = __xmlCommentSkip(cur, restlen);
1546 *len = XML_INVALID_COMMENT;
1553 * look for the closing tag of the cascading block
1555 new = memchr(cur, '<', restlen);
1560 *len = XML_ELEMENT_NO_CLOSING_TAG;
1567 if (*cur != '/') /* cascading tag found */
1570 size_t slen = restlen+1; /* due to cur-1 below*/
1575 * recursively walk the xml tree from here
1577 new = __xmlNodeGet(cur-1, &slen, &node, &nlen, &pos);
1580 if (nlen == 0) /* error upstream */
1588 if (slen == restlen)
1592 *len = XML_UNEXPECTED_EOF;
1600 else restlen -= slen;
1603 * look for the closing tag of the cascading block
1606 new = memchr(cur, '<', restlen);
1611 *len = XML_ELEMENT_NO_CLOSING_TAG;
1619 if (*cur == '/') /* closing tag found */
1621 if (!strncasecmp(new+1, element, elementlen))
1623 if (*(new+elementlen+1) != '>')
1627 *len = XML_ELEMENT_NO_CLOSING_TAG;
1636 open_element = start_tag;
1638 else /* report error */
1642 *len = XML_ELEMENT_NO_OPENING_TAG;
1649 new = memchr(cur, '>', restlen);
1654 *len = XML_ELEMENT_NO_CLOSING_TAG;
1665 *len = XML_ELEMENT_NO_CLOSING_TAG;
1675 *len = XML_NO_ERROR; /* element not found, no real error */
1680 *name = open_element;
1688 __xmlCommentSkip(const char *start, size_t len)
1692 cur = (char *)start;
1695 if (memcmp(cur, "!--", 3) == 0)
1697 if (len < 6) return 0; /* <!-- --> */
1703 new = memchr(cur, '-', len);
1707 if ((len > 3) && (memcmp(new, "-->", 3) == 0))
1717 while (new && (len > 2));
1724 __xmlInfoProcess(const char *start, size_t len)
1728 cur = (char *)start;
1733 if (len < 3) return 0; /* <? ?> */
1737 new = memchr(cur, '?', len);
1738 if (!new || *(new+1) != '>') return 0;
1747 #define NOCASECMP(a,b) ( ((a)^(b)) & 0xdf )
1749 __xml_memncasecmp(const char *haystack, size_t *haystacklen,
1750 char **needle, size_t *needlelen)
1754 if (haystack && needle && needlelen && (*needlelen > 0)
1755 && (*haystacklen >= *needlelen))
1757 char *hs = (char *)haystack;
1763 /* search for everything */
1764 if ((*ns == '*') && (*needlelen == 1))
1766 char *he = hs + *haystacklen;
1768 while ((hs < he) && !isspace(*hs) && (*hs != '>')) hs++;
1769 if (*(hs-1) == '/') hs--;
1771 *needle = (char *)haystack;
1772 *needlelen = hs - haystack;
1774 ns = memchr(hs, '>', he-hs);
1782 size_t nlen = *needlelen;
1783 char *he = hs + *haystacklen;
1785 for (i=0; i<nlen; i++)
1787 if (NOCASECMP(*hs,*ns) && (*ns != '?')) break;
1788 if (isspace(*hs) || (*hs == '/') || (*hs == '>')) break;
1795 *needle = (char *)haystack;
1796 *needlelen = hs - haystack;
1798 ns = memchr(hs, '>', he-hs);
1804 else /* not found */
1806 while((hs < he) && !isspace(*hs) && (*hs != '>')) hs++;
1807 if (*(hs-1) == '/') hs--;
1809 *needle = (char *)haystack;
1810 *needlelen = hs - haystack;
1812 ns = memchr(hs, '>', he-hs);
1818 *haystacklen -= hs - haystack;
1824 #ifndef XML_NONVALIDATING
1826 __xmlErrorSet(const void *id, const char *pos, unsigned int err_no)
1828 struct _xml_id *xid = (struct _xml_id *)id;
1829 struct _root_id *rid;
1833 if (xid->name) rid = xid->root;
1834 else rid = (struct _root_id *)xid;
1839 rid->info = malloc(sizeof(struct _xml_error));
1844 struct _xml_error *err = rid->info;
1846 err->pos = (char *)pos;
1847 err->err_no = err_no;
1854 * https://mollyrocket.com/forums/viewtopic.php?p=2529
1858 simple_mmap(int fd, size_t length, SIMPLE_UNMMAP *un)
1864 f = (HANDLE)_get_osfhandle(fd);
1865 if (!f) return (void *)-1;
1867 m = CreateFileMapping(f, NULL, PAGE_READONLY, 0, 0, NULL);
1868 if (!m) return (void *)-1;
1870 p = MapViewOfFile(m, FILE_MAP_READ, 0,0,0);
1887 simple_unmmap(SIMPLE_UNMMAP *un)
1889 UnmapViewOfFile(un->p);