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>
48 #include <stdlib.h> /* free, malloc */
51 #include <sys/types.h>
55 # include <strings.h> /* strncasecmp */
57 # define strncasecmp strnicmp
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));
158 rid->len = statbuf.st_size;
159 rid->start = mmap(0, rid->len, PROT_READ, MAP_PRIVATE, fd, 0L);
161 #ifndef XML_NONVALIDATING
174 struct _root_id *rid = (struct _root_id *)id;
177 assert(rid->name == 0);
179 munmap(rid->start, rid->len);
182 if (rid->info) free(rid->info);
188 xmlNodeGet(const void *id, const char *path)
190 struct _xml_id *xid = (struct _xml_id *)id;
191 struct _xml_id *xsid = 0;
201 ptr = __xmlNodeGetPath(xid->start, &len, &node, &slen);
204 xsid = malloc(sizeof(struct _xml_id));
209 xsid->name_len = slen;
211 #ifndef XML_NONVALIDATING
213 xsid->root = xid->root;
215 xsid->root = (struct _root_id *)xid;
220 xmlErrorSet(xid, 0, XML_OUT_OF_MEMORY);
225 xmlErrorSet(xid, node, len);
232 xmlNodeCopy(const void *id, const char *path)
234 struct _xml_id *xid = (struct _xml_id *)id;
235 struct _xml_id *xsid = 0;
236 char *ptr, *node, *p;
242 ptr = __xmlNodeGetPath(xid->start, &len, &node, &slen);
245 xsid = malloc(sizeof(struct _xml_id) + len);
248 p = (char *)xsid + sizeof(struct _xml_id);
252 xsid->name_len = slen;
254 #ifndef XML_NONVALIDATING
256 xsid->root = xid->root;
258 xsid->root = (struct _root_id *)xid;
261 memcpy(xsid->start, ptr, len);
265 xmlErrorSet(xid, 0, XML_OUT_OF_MEMORY);
270 xmlErrorSet(xid, node, len);
277 xmlNodeGetName(const void *id)
279 struct _xml_id *xid = (struct _xml_id *)id;
289 memcpy(ret, xid->name, len);
294 xmlErrorSet(xid, 0, XML_OUT_OF_MEMORY);
301 xmlNodeCopyName(const void *id, char *buf, size_t buflen)
303 struct _xml_id *xid = (struct _xml_id *)id;
310 if (slen > xid->name_len)
312 slen = xid->name_len;
316 xmlErrorSet(xid, 0, XML_TRUNCATE_RESULT);
318 memcpy(buf, xid->name, slen);
325 xmlNodeGetNum(const void *id, const char *path)
327 struct _xml_id *xid = (struct _xml_id *)id;
335 char *nodename, *pathname;
339 nodename = (char *)path;
340 if (*path == '/') nodename++;
341 slen = strlen(nodename);
343 pathname = strchr(nodename, '/');
350 slen -= pathname-nodename;
352 p = __xmlNodeGetPath(xid->start, &len, &node, &slen);
353 if (p == 0 && slen == 0)
355 xmlErrorSet(xid, node, len);
366 char *ret, *node = nodename;
368 ret = __xmlNodeGet(p, &len, &node, &slen, &num);
369 if (ret == 0 && slen == 0)
371 xmlErrorSet(xid, node, len);
381 xmlNodeGetPos(const void *pid, void *id, const char *element, size_t num)
383 struct _xml_id *xpid = (struct _xml_id *)pid;
384 struct _xml_id *xid = (struct _xml_id *)id;
391 assert(element != 0);
394 slen = strlen(element);
395 node = (char *)element;
396 ptr = __xmlNodeGet(xpid->start, &len, &node, &slen, &num);
402 xid->name_len = slen;
407 xmlErrorSet(xpid, node, len);
414 xmlGetString(const void *id)
416 struct _xml_id *xid = (struct _xml_id *)id;
423 char *ps, *pe, *pend;
431 while ((ps<pe) && isspace(*ps)) ps++;
432 while ((pe>ps) && isspace(*pe)) pe--;
436 str = malloc(nlen+1);
439 memcpy(str, ps, nlen);
444 xmlErrorSet(xid, 0, XML_OUT_OF_MEMORY);
453 xmlCopyString(const void *id, char *buffer, size_t buflen)
455 struct _xml_id *xid = (struct _xml_id *)id;
464 char *ps, *pe, *pend;
474 while ((ps<pe) && isspace(*ps)) ps++;
475 while ((pe>ps) && isspace(*pe)) pe--;
477 if (nlen > slen) nlen = slen;
484 xmlErrorSet(xid, 0, XML_TRUNCATE_RESULT);
486 memcpy(buffer, ps, nlen);
496 xmlCompareString(const void *id, const char *s)
498 struct _xml_id *xid = (struct _xml_id *)id;
504 if (xid->len && (strlen(s) > 0))
512 while ((ps<pe) && isspace(*ps)) ps++;
513 while ((pe>ps) && isspace(*pe)) pe--;
516 ret = strncasecmp(ps, s, pe-ps);
523 xmlNodeGetString(const void *id, const char *path)
525 struct _xml_id *xid = (struct _xml_id *)id;
533 size_t len = xid->len;
534 char *node = (char *)path;
536 str = __xmlNodeCopy(xid->start, &len, &path);
539 char *ps, *pe, *pend;
547 while ((ps<pe) && isspace(*ps)) ps++;
548 while ((pe>ps) && isspace(*pe)) pe--;
552 if (slen && (ps>str)) memmove(str, ps, slen);
553 else if (!slen) *str = 0;
557 xmlErrorSet(xid, node, len);
565 xmlNodeCopyString(const void *id, const char *path, char *buffer, size_t buflen)
567 struct _xml_id *xid = (struct _xml_id *)id;
584 str = __xmlNodeGetPath(xid->start, &nlen, &node, &slen);
592 while ((ps<pe) && isspace(*ps)) ps++;
593 while ((pe>ps) && isspace(*pe)) pe--;
599 xmlErrorSet(xid, 0, XML_TRUNCATE_RESULT);
602 memcpy(buffer, ps, nlen);
603 *(buffer + nlen) = '\0';
608 xmlErrorSet(xid, node, nlen);
616 xmlNodeCompareString(const void *id, const char *path, const char *s)
618 struct _xml_id *xid = (struct _xml_id *)id;
625 if (xid->len && (strlen(s) > 0))
627 char *node, *str, *ps, *pe;
633 str = __xmlNodeGetPath(xid->start, &len, &node, &slen);
640 while ((ps<pe) && isspace(*ps)) ps++;
641 while ((pe>ps) && isspace(*pe)) pe--;
644 ret = strncasecmp(ps, s, pe-ps);
648 xmlErrorSet(xid, node, len);
656 xmlGetInt(const void *id)
658 struct _xml_id *xid = (struct _xml_id *)id;
665 char *end = xid->start + xid->len;
666 li = strtol(xid->start, &end, 10);
673 xmlNodeGetInt(const void *id, const char *path)
675 struct _xml_id *xid = (struct _xml_id *)id;
689 str = __xmlNodeGetPath(xid->start, &len, &node, &slen);
693 li = strtol(str, &end, 10);
697 xmlErrorSet(xid, node, len);
705 xmlGetDouble(const void *id)
707 struct _xml_id *xid = (struct _xml_id *)id;
714 char *end = xid->start + xid->len;
715 d = strtod(xid->start, &end);
722 xmlNodeGetDouble(const void *id, const char *path)
724 struct _xml_id *xid = (struct _xml_id *)id;
738 str = __xmlNodeGetPath(xid->start, &len, &node, &slen);
742 d = strtod(str, &end);
746 xmlErrorSet(xid, node, len);
754 xmlMarkId(const void *id)
756 struct _xml_id *xmid = 0;
760 xmid = malloc(sizeof(struct _xml_id));
763 struct _root_id *xrid = (struct _root_id *)id;
767 xmid->start = xrid->start;
768 xmid->len = xrid->len;
770 #ifndef XML_NONVALIDATING
776 memcpy(xmid, id, sizeof(struct _xml_id));
781 xmlErrorSet(id, 0, XML_OUT_OF_MEMORY);
788 xmlAttributeGetDouble(const void *id, const char *name)
790 struct _xml_id *xid = (struct _xml_id *)id;
796 if (xid->len && xid->name_len)
798 size_t slen = strlen(name);
801 assert(xid->start > xid->name);
803 ps = xid->name + xid->name_len + 1;
807 while ((ps<pe) && isspace(*ps)) ps++;
808 if (((size_t)(pe-ps) > slen) && (strncasecmp(ps, name, slen) == 0))
811 if ((ps<pe) && (*ps == '='))
816 if (*ps == '"' || *ps == '\'') ps++;
819 xmlErrorSet(xid, ps, XML_ATTRIB_NO_OPENING_QUOTE);
824 while ((ps<pe) && (*ps != '"') && (*ps != '\'')) ps++;
827 ret = strtod(start, &ps);
831 xmlErrorSet(xid, ps, XML_ATTRIB_NO_CLOSING_QUOTE);
837 while ((ps<pe) && !isspace(*ps)) ps++;
844 while ((ps<pe) && !isspace(*ps)) ps++;
852 xmlAttributeGetInt(const void *id, const char *name)
854 struct _xml_id *xid = (struct _xml_id *)id;
860 if (xid->len && xid->name_len)
862 size_t slen = strlen(name);
865 assert(xid->start > xid->name);
867 ps = xid->name + xid->name_len + 1;
871 while ((ps<pe) && isspace(*ps)) ps++;
872 if (((size_t)(pe-ps) > slen) && (strncasecmp(ps, name, slen) == 0))
875 if ((ps<pe) && (*ps == '='))
880 if (*ps == '"' || *ps == '\'') ps++;
883 xmlErrorSet(xid, ps, XML_ATTRIB_NO_OPENING_QUOTE);
888 while ((ps<pe) && (*ps != '"') && (*ps != '\'')) ps++;
891 ret = strtol(start, &ps, 10);
895 xmlErrorSet(xid, ps, XML_ATTRIB_NO_CLOSING_QUOTE);
901 while ((ps<pe) && isspace(*ps)) ps++;
908 while ((ps<pe) && !isspace(*ps)) ps++;
916 xmlAttributeGetString(const void *id, const char *name)
918 struct _xml_id *xid = (struct _xml_id *)id;
924 if (xid->len && xid->name_len)
926 size_t slen = strlen(name);
929 assert(xid->start > xid->name);
931 ps = xid->name + xid->name_len + 1;
935 while ((ps<pe) && isspace(*ps)) ps++;
936 if (((size_t)(pe-ps) > slen) && (strncasecmp(ps, name, slen) == 0))
939 if ((ps<pe) && (*ps == '='))
944 if (*ps == '"' || *ps == '\'') ps++;
947 xmlErrorSet(xid, ps, XML_ATTRIB_NO_OPENING_QUOTE);
952 while ((ps<pe) && (*ps != '"') && (*ps != '\'')) ps++;
955 ret = malloc(ps-start);
958 memcpy(ret, start, (ps-start));
959 *(ret+(ps-start)) = '\0';
963 xmlErrorSet(xid, 0, XML_OUT_OF_MEMORY);
968 xmlErrorSet(xid, ps, XML_ATTRIB_NO_CLOSING_QUOTE);
974 while ((ps<pe) && !isspace(*ps)) ps++;
982 while ((ps<pe) && !isspace(*ps)) ps++;
990 xmlAttributeCopyString(const void *id, const char *name,
991 char *buffer, size_t buflen)
993 struct _xml_id *xid = (struct _xml_id *)id;
1001 if (xid->len && xid->name_len)
1003 size_t slen = strlen(name);
1006 assert(xid->start > xid->name);
1009 ps = xid->name + xid->name_len + 1;
1010 pe = xid->start - 1;
1013 while ((ps<pe) && isspace(*ps)) ps++;
1014 if (((size_t)(pe-ps) > slen) && (strncasecmp(ps, name, slen) == 0))
1017 if ((ps<pe) && (*ps == '='))
1022 if (*ps == '"' || *ps == '\'') ps++;
1025 xmlErrorSet(xid, ps, XML_ATTRIB_NO_OPENING_QUOTE);
1030 while ((ps<pe) && (*ps != '"') && (*ps != '\'')) ps++;
1033 size_t restlen = ps-start;
1034 if (restlen >= buflen)
1037 xmlErrorSet(xid, ps, XML_TRUNCATE_RESULT);
1040 memcpy(buffer, start, restlen);
1041 *(buffer+restlen) = 0;
1046 xmlErrorSet(xid, ps, XML_ATTRIB_NO_CLOSING_QUOTE);
1052 while ((ps<pe) && isspace(*ps)) ps++;
1059 while ((ps<pe) && !isspace(*ps)) ps++;
1067 xmlAttributeCompareString(const void *id, const char *name, const char *s)
1069 struct _xml_id *xid = (struct _xml_id *)id;
1076 if (xid->len && xid->name_len && strlen(s))
1078 size_t slen = strlen(name);
1081 assert(xid->start > xid->name);
1083 ps = xid->name + xid->name_len + 1;
1084 pe = xid->start - 1;
1087 while ((ps<pe) && isspace(*ps)) ps++;
1088 if (((size_t)(pe-ps) > slen) && (strncasecmp(ps, name, slen) == 0))
1091 if ((ps<pe) && (*ps == '='))
1096 if (*ps == '"' || *ps == '\'') ps++;
1099 xmlErrorSet(xid, ps, XML_ATTRIB_NO_OPENING_QUOTE);
1104 while ((ps<pe) && (*ps != '"') && (*ps != '\'')) ps++;
1107 ret = strncasecmp(start, s, ps-start);
1111 xmlErrorSet(xid, ps, XML_ATTRIB_NO_CLOSING_QUOTE);
1117 while ((ps<pe) && !isspace(*ps)) ps++;
1124 while ((ps<pe) && !isspace(*ps)) ps++;
1132 #ifndef XML_NONVALIDATING
1134 xmlErrorGetNo(const void *id, int clear)
1140 struct _xml_id *xid = (struct _xml_id *)id;
1141 struct _root_id *rid;
1143 if (xid->name) rid = xid->root;
1144 else rid = (struct _root_id *)xid;
1150 struct _xml_error *err = rid->info;
1153 if (clear) err->err_no = 0;
1161 xmlErrorGetLineNo(const void *id, int clear)
1167 struct _xml_id *xid = (struct _xml_id *)id;
1168 struct _root_id *rid;
1170 if (xid->name) rid = xid->root;
1171 else rid = (struct _root_id *)xid;
1177 struct _xml_error *err = rid->info;
1178 char *ps = rid->start;
1179 char *pe = err->pos;
1185 new = memchr(ps, '\n', pe-ps);
1194 if (clear) err->err_no = 0;
1202 xmlErrorGetString(const void *id, int clear)
1208 struct _xml_id *xid = (struct _xml_id *)id;
1209 struct _root_id *rid;
1211 if (xid->name) rid = xid->root;
1212 else rid = (struct _root_id *)xid;
1218 struct _xml_error *err = rid->info;
1219 if (XML_NO_ERROR <= err->err_no && err->err_no < XML_MAX_ERROR)
1221 ret = (char *)__xml_error_str[err->err_no];
1225 ret = "incorrect error number.";
1228 if (clear) err->err_no = 0;
1236 /* -------------------------------------------------------------------------- */
1238 #ifndef XML_NONVALIDATING
1239 static const char *__xml_error_str[XML_MAX_ERROR] =
1242 "unable to allocate enough memory.",
1243 "unable to open file for reading.",
1244 "buffer too small to hold all data, truncating.",
1245 "incorrect comment section.",
1246 "bad information block.",
1247 "unexpected end of section.",
1248 "incompatible opening tag for element.",
1249 "missing or invalid closing tag for element.",
1250 "missing or invalid opening quote for attribute.",
1251 "missing or invalid closing quote for attribute."
1256 __xmlNodeCopy(const char *start, size_t *len, const char **path)
1258 char *node, *p, *ret = 0;
1262 slen = strlen(*path);
1263 node = (char *)*path;
1264 p = __xmlNodeGetPath(start, &rlen, &node, &slen);
1267 ret = malloc(rlen+1);
1270 memcpy(ret, p, rlen);
1271 *(ret+rlen+1) = '\0';
1275 xmlErrorSet(0, 0, XML_OUT_OF_MEMORY);
1288 __xmlNodeGetPath(const char *start, size_t *len, char **name, size_t *plen)
1300 if ((*len == 0) || (*plen == 0) || (*plen > *len))
1304 if (*node == '/') node++;
1311 slen = strlen(node);
1312 path = strchr(node, '/');
1314 if (!path) plen = slen;
1315 else plen = path++ - node;
1320 ret = __xmlNodeGet(start, len, &node, &plen, &num);
1323 plen = slen - (path - *name);
1324 ret = __xmlNodeGetPath(ret, len, &path, &plen);
1338 __xmlNodeGet(const char *start, size_t *len, char **name, size_t *rlen, size_t *nodenum)
1340 char *new, *cur, *ne, *ret = 0;
1341 char *element, *start_tag=0;
1342 size_t restlen, elementlen;
1353 assert(nodenum != 0);
1359 *len = XML_UNEXPECTED_EOF;
1366 cur = (char *)start;
1369 while ((new = memchr(cur, '<', restlen)) != 0)
1371 if (*(new+1) == '/') /* cascading closing tag found */
1383 new = __xmlCommentSkip(cur, restlen);
1388 *len = XML_INVALID_COMMENT;
1395 else if (*cur == '?')
1397 new = __xmlInfoProcess(cur, restlen);
1402 *len = XML_INVALID_INFO_BLOCK;
1413 new = __xml_memncasecmp(cur, &restlen, &element, &elementlen);
1416 retlen = elementlen;
1420 start_tag = element;
1427 new = cur+elementlen;
1432 *len = XML_UNEXPECTED_EOF;
1438 if (*(new-1) == '/') /* e.g. <test/> */
1447 if ((restlen < 1) || (*new != '>'))
1451 *len = XML_ELEMENT_NO_CLOSING_TAG;
1455 restlen -= new+1-cur;
1460 /* restlen -= new-cur; not necessary because of __xml_memncasecmp */
1462 new = memchr(cur, '<', restlen);
1467 *len = XML_ELEMENT_NO_CLOSING_TAG;
1473 if (*(cur+1) != '/') /* new node found */
1476 size_t slen = restlen;
1480 new = __xmlNodeGet(cur, &slen, &node, &nlen, &pos);
1483 if (slen == restlen)
1487 *len = XML_UNEXPECTED_EOF;
1490 else new = cur + slen;
1496 new = memchr(cur, '<', restlen);
1501 *len = XML_ELEMENT_NO_CLOSING_TAG;
1509 if (*(cur+1) == '/') /* closing tag found */
1511 if (!strncasecmp(new+2, element, elementlen))
1520 else /* report error */
1524 *len = XML_ELEMENT_NO_OPENING_TAG;
1531 new = memchr(cur, '>', restlen);
1536 *len = XML_ELEMENT_NO_CLOSING_TAG;
1551 if ((ret == 0) && (start_tag == 0) && (*rlen > 1))
1556 *len = XML_NO_ERROR; /* element not found */
1568 __xmlCommentSkip(const char *start, size_t len)
1572 cur = (char *)start;
1575 if (memcmp(cur, "!--", 3) == 0)
1577 if (len < 6) return 0; /* <!-- --> */
1583 new = memchr(cur, '-', len);
1587 if ((len > 3) && (memcmp(new, "-->", 3) == 0))
1597 while (new && (len > 2));
1604 __xmlInfoProcess(const char *start, size_t len)
1608 cur = (char *)start;
1613 if (len < 3) return 0; /* <? ?> */
1617 new = memchr(cur, '?', len);
1618 if (!new || *(new+1) != '>') return 0;
1627 #define NOCASECMP(a,b) ( ((a)^(b)) & 0xdf )
1629 __xml_memncasecmp(const char *haystack, size_t *haystacklen,
1630 char **needle, size_t *needlelen)
1634 if (haystack && needle && needlelen && (*needlelen > 0)
1635 && (*haystacklen >= *needlelen))
1637 char *hs = (char *)haystack;
1643 /* search for everything */
1644 if ((*ns == '*') && (*needlelen == 1))
1646 char *he = hs + *haystacklen;
1648 while ((hs < he) && !isspace(*hs) && (*hs != '>')) hs++;
1649 *needle = (char *)haystack;
1650 *needlelen = hs - haystack;
1651 while ((hs < he) && (*hs != '>')) hs++;
1656 size_t nlen = *needlelen;
1657 char *he = hs + *haystacklen;
1659 for (i=0; i<nlen; i++)
1661 if (NOCASECMP(*hs,*ns) && (*ns != '?')) break;
1662 if (isspace(*hs) || (*hs == '>')) break;
1669 while((hs < he) && !isspace(*hs) && (*hs != '>')) hs++;
1670 *needle = (char *)haystack;
1671 *needlelen = hs - haystack;
1675 int found = (isspace(*hs) || (*hs == '>'));
1677 *needle = (char *)haystack;
1678 *needlelen = hs - haystack;
1680 while ((hs < he) && (*hs != '>')) hs++;
1682 if (!found) *needlelen = hs - haystack;
1687 *haystacklen -= hs - haystack;
1693 #ifndef XML_NONVALIDATING
1695 __xmlErrorSet(const void *id, const char *pos, unsigned int err_no)
1697 struct _xml_id *xid = (struct _xml_id *)id;
1698 struct _root_id *rid;
1702 if (xid->name) rid = xid->root;
1703 else rid = (struct _root_id *)xid;
1708 rid->info = malloc(sizeof(struct _xml_error));
1713 struct _xml_error *err = rid->info;
1715 err->pos = (char *)pos;
1716 err->err_no = err_no;
1723 * https://mollyrocket.com/forums/viewtopic.php?p=2529
1727 simple_mmap(int fd, size_t length, SIMPLE_UNMMAP *un)
1733 f = (HANDLE)_get_osfhandle(fd);
1734 if (!f) return NULL;
1736 m = CreateFileMapping(f, NULL, PAGE_READONLY, 0, 0, NULL);
1737 if (!m) return NULL;
1739 p = MapViewOfFile(m, FILE_MAP_READ, 0,0,0);
1756 simple_unmmap(SIMPLE_UNMMAP *un)
1758 UnmapViewOfFile(un->p);