1 /* Copyright (c) 2007, 2008 by Adalin B.V.
2 * Copyright (c) 2007, 2008 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
38 static SIMPLE_UNMMAP un;
41 * map 'filename' and return a pointer to it.
43 void *simple_mmap(int, unsigned int, SIMPLE_UNMMAP *);
44 void simple_unmmap(SIMPLE_UNMMAP *);
46 #define mmap(a,b,c,d,e,f) simple_mmap((e), (b), &un)
47 #define munmap(a,b) simple_unmmap(&un)
50 # include <sys/mman.h>
55 #include <sys/types.h>
72 static char *__xmlCopyNode(char *, size_t, const char *);
73 static char *__xmlGetNode(const char *, size_t *, char **, size_t *, int *);
74 static char *__xmlGetNodePath(const char *, size_t *, char **, size_t *);
75 static char *__xmlSkipComment(const char *, size_t);
76 static char *__xmlSkipInfo(const char *, size_t);
78 static void *__xml_memmem(const void *, size_t, const void *, size_t);
79 static void *__xml_memncasecmp(void *, size_t *, void **, size_t *);
80 static void *__xml_memchr(const void *, int, size_t);
82 #define PRINT(a, b, c) { \
87 printf("(%i) '", len); \
88 for (q=0; q<len; q++) printf("%c", ((char *)(a))[q]); \
90 } else printf("Length (%u) seems too large at line %i\n",len, __LINE__); \
91 } else printf("NULL pointer at line %i\n", __LINE__); \
97 struct _xml_id *id = 0;
101 int fd = open(fn, O_RDONLY);
104 id = malloc(sizeof(struct _xml_id));
111 id->nlen = (size_t)fd;
112 id->len = statbuf.st_size;
113 id->start = mmap(0, id->len, PROT_READ, MAP_PRIVATE, fd, 0L);
127 struct _xml_id *xid = (struct _xml_id *)id;
128 assert(xid->name == 0);
130 munmap(xid->start, xid->len);
131 close((int)xid->nlen);
138 xmlCopyNode(void *id, char *path)
140 struct _xml_id *xsid = 0;
144 struct _xml_id *xid = (struct _xml_id *)id;
145 char *ptr, *node, *p;
151 ptr = __xmlGetNodePath(xid->start, &len, &node, &slen);
154 xsid = malloc(sizeof(struct _xml_id) + len);
157 p = (char *)xsid + sizeof(struct _xml_id);
164 memcpy(xsid->start, ptr, len);
173 xmlGetNode(void *id, char *path)
175 struct _xml_id *xsid = 0;
179 struct _xml_id *xid = (struct _xml_id *)id;
186 ptr = __xmlGetNodePath(xid->start, &len, &node, &slen);
189 xsid = malloc(sizeof(struct _xml_id));
204 xmlGetNodeName(void *id)
206 struct _xml_id *xid = (struct _xml_id *)id;
209 ret = malloc(xid->nlen+1);
212 memcpy(ret, xid->name, xid->nlen);
213 *(ret + xid->nlen) = 0;
220 xmlCopyNodeName(void *id, const char *buf, size_t len)
222 struct _xml_id *xid = (struct _xml_id *)id;
228 if (slen > xid->nlen) slen = xid->nlen;
229 memcpy((char *)buf, xid->name, slen);
234 xmlGetNodeNum(const void *rid, void *id, char *element, int num)
236 struct _xml_id *xrid = (struct _xml_id *)rid;
241 struct _xml_id *xid = (struct _xml_id *)id;
246 slen = strlen(element);
248 ptr = __xmlGetNode(xrid->start, &len, &node, &slen, &num);
263 xmlCompareString(const void *id, const char *s)
265 struct _xml_id *xid = (struct _xml_id *)id;
268 if (xid && xid->len && s && (strlen(s) > 0))
276 while ((ps<pe) && isspace(*ps)) ps++;
277 while ((pe>ps) && isspace(*pe)) pe--;
280 ret = strncasecmp(ps, s, pe-ps);
287 xmlCompareNodeString(const void *id, const char *path, const char *s)
289 struct _xml_id *xid = (struct _xml_id *)id;
292 if (xid && xid->len && path && s && (strlen(s) > 0))
294 char *node, *str, *ps, *pe;
300 str = __xmlGetNodePath(xid->start, &len, &node, &slen);
307 while ((ps<pe) && isspace(*ps)) ps++;
308 while ((pe>ps) && isspace(*pe)) pe--;
311 ret = strncasecmp(pe, s, pe-ps);
319 xmlGetNodeString(void *id, const char *path)
321 struct _xml_id *xid = (struct _xml_id *)id;
324 if (xid && xid->len && path)
326 str = __xmlCopyNode(xid->start, xid->len, path);
329 char *ps, *pe, *pend;
337 while ((ps<pe) && isspace(*ps)) ps++;
338 while ((pe>ps) && isspace(*pe)) pe--;
342 if (slen && (ps>str)) memmove(str, ps, slen);
343 else if (!slen) *str = 0;
351 xmlGetString(void *id)
353 struct _xml_id *xid = (struct _xml_id *)id;
358 char *ps, *pe, *pend;
366 while ((ps<pe) && isspace(*ps)) ps++;
367 while ((pe>ps) && isspace(*pe)) pe--;
371 str = malloc(nlen+1);
374 memcpy(str, ps, nlen);
384 xmlCopyString(void *id, char *buf, size_t len)
386 struct _xml_id *xid = (struct _xml_id *)id;
389 if (xid && xid->len && buf && len)
391 char *ps, *pe, *pend;
400 while ((ps<pe) && isspace(*ps)) ps++;
401 while ((pe>ps) && isspace(*pe)) pe--;
403 if (nlen > slen) nlen = slen;
407 memcpy(buf, ps, nlen);
416 xmlCopyNodeString(void *id, const char *path, char *buffer, size_t buflen)
418 struct _xml_id *xid = (struct _xml_id *)id;
421 if (xid && xid->len && path && buffer && buflen)
430 str = __xmlGetNodePath(xid->start, &len, &node, &slen);
438 while ((ps<pe) && isspace(*ps)) ps++;
439 while ((pe>ps) && isspace(*pe)) pe--;
442 if (len >= buflen) len = buflen-1;
444 memcpy(buffer, ps, len);
454 xmlGetNodeInt(void *id, const char *path)
456 struct _xml_id *xid = (struct _xml_id *)id;
459 if (path && xid && xid->len)
467 str = __xmlGetNodePath(xid->start, &len, &node, &slen);
471 li = strtol(str, &end, 10);
481 struct _xml_id *xid = (struct _xml_id *)id;
486 char *end = xid->start + xid->len;
487 li = strtol(xid->start, &end, 10);
494 xmlGetNodeDouble(void *id, const char *path)
496 struct _xml_id *xid = (struct _xml_id *)id;
499 if (path && xid && xid->len)
507 str = __xmlGetNodePath(xid->start, &len, &node, &slen);
511 d = strtod(str, &end);
519 xmlGetDouble(void *id)
521 struct _xml_id *xid = (struct _xml_id *)id;
526 char *end = xid->start + xid->len;
527 d = strtod(xid->start, &end);
535 xmlGetNumNodes(void *id, const char *path)
537 struct _xml_id *xid = (struct _xml_id *)id;
540 if (xid && xid->len && path)
542 char *nodename, *pathname;
546 nodename = (char *)path;
547 if (*path == '/') nodename++;
548 slen = strlen(nodename);
550 pathname = strchr(nodename, '/');
557 slen -= pathname-nodename;
559 p = __xmlGetNodePath(xid->start, &len, &node, &slen);
563 p = (char *)xid->start;
569 char *node = nodename;
570 __xmlGetNode(p, &len, &node, &slen, &num);
580 struct _xml_id *xmid = 0;
584 xmid = malloc(sizeof(struct _xml_id));
587 memcpy(xmid, id, sizeof(struct _xml_id));
595 /* -------------------------------------------------------------------------- */
598 __xmlCopyNode(char *start, size_t len, const char *path)
600 char *node, *p, *ret = 0;
606 p = __xmlGetNodePath(start, &rlen, &node, &slen);
609 ret = calloc(1, rlen+1);
610 memcpy(ret, p, rlen);
617 __xmlGetNodePath(const char *start, size_t *len, char **name, size_t *plen)
628 if ((*len == 0) || (*plen == 0) || (*plen > *len))
631 node = (char *)*name;
632 if (*node == '/') node++;
640 path = strchr(node, '/');
642 if (!path) plen = slen;
643 else plen = path++ - node;
646 ret = __xmlGetNode(start, len, &node, &plen, &num);
649 plen = slen - (path - *name);
650 ret = __xmlGetNodePath(ret, len, &path, &plen);
660 __xmlGetNode(const char *start, size_t *len, char **name, size_t *rlen, int *nodenum)
662 char *new, *cur, *ne, *ret = 0;
663 size_t restlen, elementlen;
672 assert (nodenum != 0);
674 if ((*len == 0) || (*rlen == 0) || (*rlen > *len))
683 while ((new = memchr(cur, '<', restlen)) != 0)
685 if (*(new+1) == '/') /* cascading closing tag found */
697 new = __xmlSkipComment(cur, restlen);
703 else if (*cur == '?')
705 new = __xmlSkipInfo(cur, restlen);
713 element = (char *)*name;
715 new = __xml_memncasecmp(cur, &restlen, &element, &elementlen);
718 if (found == num ) ret = new+1;
722 new = cur+elementlen;
723 if (new >= ne) return 0;
724 element = (char *)*name;
728 /* restlen -= new-cur; not necessary because of __xml_memncasecmp */
730 new = memchr(cur, '<', restlen);
735 if (*(cur+1) != '/') /* new node found */
738 size_t slen = restlen;
742 new = __xmlGetNode(cur, &slen, &node, &nlen, &pos);
745 if (slen == restlen) return 0;
746 else new = cur + slen;
752 new = memchr(cur, '<', restlen);
759 if (*(cur+1) == '/') /* closing tag found */
761 if (!strncasecmp(new+2, element, elementlen))
763 if (found == num) *len = new-ret;
768 new = memchr(cur, '>', restlen);
784 __xmlSkipComment(const char *start, size_t len)
791 if (memcmp(cur, "!--", 3) == 0)
793 if (len < 6) return 0;
800 new = memchr(cur, '-', len);
804 if ((len > 3) && (memcmp(new, "-->", 3) == 0))
814 while (new && (len > 2));
821 __xmlSkipInfo(const char *start, size_t len)
830 if (len < 3) return 0;
834 new = memchr(cur, '?', len);
835 if (!new || *(new+1) != '>') return 0;
845 __xml_memmem(const void *haystack, size_t haystacklen,
846 const void *needle, size_t needlelen)
850 if (haystack && needle && (needlelen > 0) && (haystacklen >= needlelen))
854 hs = (char *)haystack;
859 ptr = memchr(hs, *ns, haystacklen);
862 haystacklen -= (ptr - hs);
864 if (haystacklen < needlelen) break;
865 if (memcmp(ptr, needle, needlelen) == 0)
875 while (haystacklen > needlelen);
882 #define NOCASECMP(a,b) ( ((a)^(b)) & 0xdf )
884 __xml_memncasecmp(void *haystack, size_t *haystacklen,
885 void **needle, size_t *needlelen)
888 char *hs = (char *)haystack;
890 if (haystack && needle && needlelen && (*needlelen > 0)
891 && (*haystacklen >= *needlelen))
896 ns = (char *)*needle;
898 /* search for everything */
899 if ((*ns == '*') && (*needlelen == 1))
901 char *he = hs + *haystacklen;
903 while ((hs < he) && (*hs != ' ') && (*hs != '>')) hs++;
904 *needle = (void *)haystack;
905 *needlelen = hs - (char *)haystack;
907 while ((hs < he) && (*hs != '>')) hs++;
912 size_t nlen = *needlelen;
913 char *he = hs + *haystacklen;
915 for (i=0; i<nlen; i++)
917 if (NOCASECMP(*hs,*ns) && (*ns != '?')) break;
918 if ((*hs == ' ') || (*hs == '>')) break;
925 while((hs < he) && (*hs != ' ') && (*hs != '>')) hs++;
926 *needle = (void *)haystack;
927 *needlelen = hs - (char *)haystack;
931 *needle = (void *)haystack;
932 *needlelen = hs - (char *)haystack;
933 while ((hs < he) && (*hs != '>')) hs++;
938 *haystacklen -= hs - (char *)haystack;
946 * https://mollyrocket.com/forums/viewtopic.php?p=2529
950 simple_mmap(int fd, unsigned int length, SIMPLE_UNMMAP *un)
956 f = (HANDLE)_get_osfhandle(fd);
959 m = CreateFileMapping(f, NULL, PAGE_READONLY, 0, 0, NULL);
962 p = MapViewOfFile(m, FILE_MAP_READ, 0,0,0);
969 if (n) *n = GetFileSize(f, NULL);
981 simple_unmmap(SIMPLE_UNMMAP *un)
983 UnmapViewOfFile(un->p);