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>
71 static char *__xmlCopyNode(char *, size_t, const char *);
72 static char *__xmlGetNode(char *, size_t, const char *, size_t *);
73 static void *__xml_memmem(const void *, size_t, const void *, size_t);
74 static void *__xml_memncasecmp(void *, size_t, void **, size_t *);
76 #define PRINT(a, b, c) { \
77 size_t q, len=(((b)>(c)) ? (c) : (b)); \
79 printf("(%i) '", len); \
80 for (q=0; q<len; q++) printf("%c", (a)[q]); \
82 } else printf("NULL pointer at line %i\n", __LINE__); \
88 struct _xml_id *id = 0;
92 int fd = open(fn, O_RDONLY);
95 id = malloc(sizeof(struct _xml_id));
103 id->len = statbuf.st_size;
104 id->start = mmap(0, id->len, PROT_READ, MAP_PRIVATE, fd, 0L);
117 struct _xml_id *xid = (struct _xml_id *)id;
118 munmap(xid->start, xid->len);
126 xmlCopyNode(void *id, char *path)
128 struct _xml_id *xsid = 0;
132 struct _xml_id *xid = (struct _xml_id *)id;
137 ptr = __xmlGetNode(xid->start, xid->len, path, &rlen);
140 xsid = malloc(sizeof(struct _xml_id) + rlen);
143 p = (char *)xsid + sizeof(struct _xml_id);
149 memcpy(xsid->start, ptr, rlen);
158 xmlGetNode(void *id, char *path)
160 struct _xml_id *xsid = 0;
164 struct _xml_id *xid = (struct _xml_id *)id;
169 ptr = __xmlGetNode(xid->start, xid->len, path, &rlen);
172 xsid = malloc(sizeof(struct _xml_id));
183 xmlGetNextElement(const void *pid, void *id, char *path)
185 struct _xml_id *xpid = (struct _xml_id *)pid;
190 struct _xml_id *xid = (struct _xml_id *)id;
194 if (xid->len < xpid->len) xid->start += xid->len;
195 nlen = xpid->len - (xid->start - xpid->start);
198 ptr = __xmlGetNode(xid->start, nlen, path, &rlen);
213 xmlCompareString(const void *id, const char *s)
215 struct _xml_id *xid = (struct _xml_id *)id;
218 if (xid && xid->len && s && (strlen(s) > 0))
226 while ((ps<pe) && isspace(*ps)) ps++;
227 while ((pe>ps) && isspace(*pe)) pe--;
230 ret = strncasecmp(ps, s, pe-ps);
237 xmlCompareNodeString(const void *id, const char *path, const char *s)
239 struct _xml_id *xid = (struct _xml_id *)id;
242 if (xid && xid->len && path && s && (strlen(s) > 0))
248 str = __xmlGetNode(xid->start, xid->len, path, &rlen);
254 while ((ps<pe) && isspace(*ps)) ps++;
255 while ((pe>ps) && isspace(*pe)) pe--;
258 if (str) ret = strncasecmp(pe, s, pe-ps);
265 xmlGetNodeString(void *id, const char *path)
267 struct _xml_id *xid = (struct _xml_id *)id;
270 if (xid && xid->len && path)
272 str = __xmlCopyNode(xid->start, xid->len, path);
275 char *ps, *pe, *pend;
283 while ((ps<pe) && isspace(*ps)) ps++;
284 while ((pe>ps) && isspace(*pe)) pe--;
288 if (slen && (ps>str)) memmove(str, ps, slen);
289 else if (!slen) *str = 0;
297 xmlGetString(void *id)
299 struct _xml_id *xid = (struct _xml_id *)id;
304 str = malloc(xid->len+1);
307 char *ps, *pe, *pend;
311 memcpy(str, xid->start, slen);
318 while ((ps<pe) && isspace(*ps)) ps++;
319 while ((pe>ps) && isspace(*pe)) pe--;
321 if (pe<pend) *++pe = 0;
323 if ((ps>str) && slen) memmove(str, ps, slen+1);
324 else if (!slen) *str = 0;
332 xmlCopyString(void *id, const char *path, char *buffer, unsigned int buflen)
334 struct _xml_id *xid = (struct _xml_id *)id;
335 unsigned int rlen = 0;
337 if (xid && xid->len && path && buffer && buflen)
343 str = __xmlGetNode(xid->start, xid->len, path, &rlen);
351 while ((ps<pe) && isspace(*ps)) ps++;
352 while ((pe>ps) && isspace(*pe)) pe--;
355 if (rlen >= buflen) rlen = buflen-1;
357 memcpy(buffer, ps, rlen);
367 xmlGetNodeInt(void *id, const char *path)
369 struct _xml_id *xid = (struct _xml_id *)id;
372 if (path && xid && xid->len)
378 str = __xmlGetNode(xid->start, xid->len, path, &rlen);
379 if (str) li = strtol(str, (char **)NULL, 10);
388 struct _xml_id *xid = (struct _xml_id *)id;
392 li = strtol(xid->start, (char **)NULL, 10);
398 xmlGetNodeDouble(void *id, const char *path)
400 struct _xml_id *xid = (struct _xml_id *)id;
403 if (path && xid && xid->len)
409 str = __xmlGetNode(xid->start, xid->len, path, &rlen);
411 if (str) d = strtod(str, (char **)NULL);
418 xmlGetDouble(void *id)
420 struct _xml_id *xid = (struct _xml_id *)id;
424 d = strtod(xid->start, (char **)NULL);
431 xmlGetNumElements(void *id, const char *path)
433 struct _xml_id *xid = (struct _xml_id *)id;
436 if (xid && xid->len && path)
442 pathname = (char *)path;
443 if (*path == '/') pathname++;
445 nname = strrchr(pathname, '/');
448 clen = nname-pathname;
449 p = __xmlGetNode(xid->start, xid->len, pathname, &clen);
453 nname = (char *)pathname;
454 p = (char *)xid->start;
460 unsigned int slen = strlen(nname);
461 p = __xmlGetNode(p, clen, nname, &slen);
473 struct _xml_id *xmid = 0;
477 xmid = malloc(sizeof(struct _xml_id));
480 memcpy(xmid, id, sizeof(struct _xml_id));
488 /* -------------------------------------------------------------------------- */
491 __xmlCopyNode(char *start, size_t len, const char *path)
497 p = __xmlGetNode(start, len, path, &rlen);
500 ret = calloc(1, rlen+1);
501 memcpy(ret, p, rlen);
508 __xmlGetNode(char *start, size_t len, const char *path, size_t *rlen)
512 if (len && rlen && *rlen)
514 size_t elem_len, newpath_len;
515 char *newpath, *element;
519 element = (char *)path;
522 element++; /* skip the leading '/' character */
526 newpath = strchr(element, '/');
530 elem_len = newpath_len;
534 elem_len = newpath++ - element;
535 newpath_len -= (newpath - element);
548 p = memchr(cur, '<', len);
553 if (p >= (cur+len)) return 0;
559 if (memcmp(cur, "!--", 3) == 0)
561 if (len < 6) return 0;
568 p = memchr(cur, '-', len);
572 if ((len > 3) && (memcmp(cur, "-->", 3) == 0))
582 while (p && (len > 2));
584 if (!p || (len < 2)) return 0;
586 else if (*cur == '?')
588 if (len < 3) return 0;
592 p = memchr(cur, '?', len);
593 if (!p || *(p+1) != '>') return 0;
603 cur = __xml_memncasecmp(p, len, &newelem, &newlen);
619 while ((*cur++ != '>') && (cur<(p+len)));
627 if ((p = __xml_memmem(cur, len, "</", 2)) != 0)
631 len -= (p + 2) - cur;
633 r = __xml_memncasecmp(cur, len, &newelem, &newlen);
634 if (r && *r == '>') break;
648 ret = __xmlGetNode(cur, len, newpath, rlen);
658 #define NOCASECMP(a,b) ( ((a)^(b)) & 0xdf )
661 __xml_memmem(const void *haystack, size_t haystacklen,
662 const void *needle, size_t needlelen)
666 if (haystack && needle && (needlelen > 0) && (haystacklen >= needlelen))
670 hs = (char *)haystack;
675 ptr = memchr(hs, *ns, haystacklen);
678 haystacklen -= (ptr - hs);
680 if (haystacklen < needlelen) break;
681 if (memcmp(ptr, needle, needlelen) == 0)
691 while (haystacklen > needlelen);
698 __xml_memncasecmp(void *haystack, size_t haystacklen,
699 void **needle, size_t *needlelen)
703 if (haystack && needle && needlelen && (*needlelen > 0)
704 && (haystacklen >= *needlelen))
709 ns = (char *)*needle;
710 hs = (char *)haystack;
712 /* search for everything */
713 if ((*ns == '*') && (*needlelen == 1))
715 char *he = hs + haystacklen;
717 while ((hs < he) && (*hs != ' ') && (*hs != '>')) hs++;
718 *needle = (void *)haystack;
719 *needlelen = hs - (char *)haystack;
724 size_t nlen = *needlelen;
726 for (i=0; i<nlen; i++)
728 if (NOCASECMP(*hs,*ns) && (*ns != '?'))
734 if (i == nlen) rptr = hs;
743 * https://mollyrocket.com/forums/viewtopic.php?p=2529
747 simple_mmap(int fd, unsigned int length, SIMPLE_UNMMAP *un)
753 f = (HANDLE)_get_osfhandle(fd);
756 m = CreateFileMapping(f, NULL, PAGE_READONLY, 0, 0, NULL);
759 p = MapViewOfFile(m, FILE_MAP_READ, 0,0,0);
766 if (n) *n = GetFileSize(f, NULL);
778 simple_unmmap(SIMPLE_UNMMAP *un)
780 UnmapViewOfFile(un->p);