19fd04a41Smaya /*
29fd04a41Smaya __ __ _
39fd04a41Smaya ___\ \/ /_ __ __ _| |_
49fd04a41Smaya / _ \\ /| '_ \ / _` | __|
59fd04a41Smaya | __// \| |_) | (_| | |_
69fd04a41Smaya \___/_/\_\ .__/ \__,_|\__|
79fd04a41Smaya |_| XML parser
89fd04a41Smaya
99fd04a41Smaya Copyright (c) 1997-2000 Thai Open Source Software Center Ltd
10*0315d311Schristos Copyright (c) 2000 Clark Cooper <coopercc@users.sourceforge.net>
11*0315d311Schristos Copyright (c) 2001-2002 Fred L. Drake, Jr. <fdrake@users.sourceforge.net>
12*0315d311Schristos Copyright (c) 2006 Karl Waclawek <karl@waclawek.net>
13*0315d311Schristos Copyright (c) 2016-2017 Sebastian Pipping <sebastian@pipping.org>
14*0315d311Schristos Copyright (c) 2017 Rhodri James <rhodri@wildebeest.org.uk>
159fd04a41Smaya Licensed under the MIT license:
169fd04a41Smaya
179fd04a41Smaya Permission is hereby granted, free of charge, to any person obtaining
189fd04a41Smaya a copy of this software and associated documentation files (the
199fd04a41Smaya "Software"), to deal in the Software without restriction, including
209fd04a41Smaya without limitation the rights to use, copy, modify, merge, publish,
219fd04a41Smaya distribute, sublicense, and/or sell copies of the Software, and to permit
229fd04a41Smaya persons to whom the Software is furnished to do so, subject to the
239fd04a41Smaya following conditions:
249fd04a41Smaya
259fd04a41Smaya The above copyright notice and this permission notice shall be included
269fd04a41Smaya in all copies or substantial portions of the Software.
279fd04a41Smaya
289fd04a41Smaya THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
299fd04a41Smaya EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
309fd04a41Smaya MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
319fd04a41Smaya NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
329fd04a41Smaya DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
339fd04a41Smaya OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
349fd04a41Smaya USE OR OTHER DEALINGS IN THE SOFTWARE.
35d50d1d7fStron */
36d50d1d7fStron
37d50d1d7fStron #include <sys/types.h>
38d50d1d7fStron #include <sys/mman.h>
39d50d1d7fStron #include <sys/stat.h>
40d50d1d7fStron #include <fcntl.h>
41d50d1d7fStron #include <errno.h>
42d50d1d7fStron #include <string.h>
43d50d1d7fStron #include <stdio.h>
44d50d1d7fStron #include <unistd.h>
45d50d1d7fStron
46d50d1d7fStron #ifndef MAP_FILE
47d50d1d7fStron # define MAP_FILE 0
48d50d1d7fStron #endif
49d50d1d7fStron
509fd04a41Smaya #include "xmltchar.h"
51d50d1d7fStron #include "filemap.h"
52d50d1d7fStron
539fd04a41Smaya #ifdef XML_UNICODE_WCHAR_T
549fd04a41Smaya # define XML_FMT_STR "ls"
559fd04a41Smaya #else
569fd04a41Smaya # define XML_FMT_STR "s"
579fd04a41Smaya #endif
589fd04a41Smaya
59d50d1d7fStron int
filemap(const tchar * name,void (* processor)(const void *,size_t,const tchar *,void * arg),void * arg)609fd04a41Smaya filemap(const tchar *name,
619fd04a41Smaya void (*processor)(const void *, size_t, const tchar *, void *arg),
629fd04a41Smaya void *arg) {
63d50d1d7fStron int fd;
64d50d1d7fStron size_t nbytes;
65d50d1d7fStron struct stat sb;
66d50d1d7fStron void *p;
67d50d1d7fStron
689fd04a41Smaya fd = topen(name, O_RDONLY);
69d50d1d7fStron if (fd < 0) {
709fd04a41Smaya tperror(name);
71d50d1d7fStron return 0;
72d50d1d7fStron }
73d50d1d7fStron if (fstat(fd, &sb) < 0) {
749fd04a41Smaya tperror(name);
75d50d1d7fStron close(fd);
76d50d1d7fStron return 0;
77d50d1d7fStron }
78d50d1d7fStron if (! S_ISREG(sb.st_mode)) {
79d50d1d7fStron close(fd);
809fd04a41Smaya fprintf(stderr, "%" XML_FMT_STR ": not a regular file\n", name);
81d50d1d7fStron return 0;
82d50d1d7fStron }
834c74f82dSchristos if (sb.st_size > XML_MAX_CHUNK_LEN) {
844c74f82dSchristos close(fd);
854c74f82dSchristos return 2; /* Cannot be passed to XML_Parse in one go */
864c74f82dSchristos }
87d50d1d7fStron
88d50d1d7fStron nbytes = sb.st_size;
89d50d1d7fStron /* mmap fails for zero length files */
90d50d1d7fStron if (nbytes == 0) {
91d50d1d7fStron static const char c = '\0';
92d50d1d7fStron processor(&c, 0, name, arg);
93d50d1d7fStron close(fd);
94d50d1d7fStron return 1;
95d50d1d7fStron }
969fd04a41Smaya p = (void *)mmap((void *)0, (size_t)nbytes, PROT_READ, MAP_FILE | MAP_PRIVATE,
979fd04a41Smaya fd, (off_t)0);
98d50d1d7fStron if (p == (void *)-1) {
999fd04a41Smaya tperror(name);
100d50d1d7fStron close(fd);
101d50d1d7fStron return 0;
102d50d1d7fStron }
103d50d1d7fStron processor(p, nbytes, name, arg);
1048a91d82aSspz munmap((void *)p, nbytes);
105d50d1d7fStron close(fd);
106d50d1d7fStron return 1;
107d50d1d7fStron }
108