10a48773fSEric van Gyzen /* 20a48773fSEric van Gyzen __ __ _ 30a48773fSEric van Gyzen ___\ \/ /_ __ __ _| |_ 40a48773fSEric van Gyzen / _ \\ /| '_ \ / _` | __| 50a48773fSEric van Gyzen | __// \| |_) | (_| | |_ 60a48773fSEric van Gyzen \___/_/\_\ .__/ \__,_|\__| 70a48773fSEric van Gyzen |_| XML parser 80a48773fSEric van Gyzen 90a48773fSEric van Gyzen Copyright (c) 1997-2000 Thai Open Source Software Center Ltd 100a48773fSEric van Gyzen Copyright (c) 2000-2017 Expat development team 110a48773fSEric van Gyzen Licensed under the MIT license: 120a48773fSEric van Gyzen 130a48773fSEric van Gyzen Permission is hereby granted, free of charge, to any person obtaining 140a48773fSEric van Gyzen a copy of this software and associated documentation files (the 150a48773fSEric van Gyzen "Software"), to deal in the Software without restriction, including 160a48773fSEric van Gyzen without limitation the rights to use, copy, modify, merge, publish, 170a48773fSEric van Gyzen distribute, sublicense, and/or sell copies of the Software, and to permit 180a48773fSEric van Gyzen persons to whom the Software is furnished to do so, subject to the 190a48773fSEric van Gyzen following conditions: 200a48773fSEric van Gyzen 210a48773fSEric van Gyzen The above copyright notice and this permission notice shall be included 220a48773fSEric van Gyzen in all copies or substantial portions of the Software. 230a48773fSEric van Gyzen 240a48773fSEric van Gyzen THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 250a48773fSEric van Gyzen EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 260a48773fSEric van Gyzen MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN 270a48773fSEric van Gyzen NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 280a48773fSEric van Gyzen DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 290a48773fSEric van Gyzen OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 300a48773fSEric van Gyzen USE OR OTHER DEALINGS IN THE SOFTWARE. 315bb6a25fSPoul-Henning Kamp */ 325bb6a25fSPoul-Henning Kamp 335bb6a25fSPoul-Henning Kamp #include <sys/types.h> 345bb6a25fSPoul-Henning Kamp #include <sys/mman.h> 355bb6a25fSPoul-Henning Kamp #include <sys/stat.h> 365bb6a25fSPoul-Henning Kamp #include <fcntl.h> 375bb6a25fSPoul-Henning Kamp #include <errno.h> 385bb6a25fSPoul-Henning Kamp #include <string.h> 395bb6a25fSPoul-Henning Kamp #include <stdio.h> 405bb6a25fSPoul-Henning Kamp #include <unistd.h> 415bb6a25fSPoul-Henning Kamp 425bb6a25fSPoul-Henning Kamp #ifndef MAP_FILE 435bb6a25fSPoul-Henning Kamp # define MAP_FILE 0 445bb6a25fSPoul-Henning Kamp #endif 455bb6a25fSPoul-Henning Kamp 460a48773fSEric van Gyzen #include "xmltchar.h" 475bb6a25fSPoul-Henning Kamp #include "filemap.h" 485bb6a25fSPoul-Henning Kamp 490a48773fSEric van Gyzen #ifdef XML_UNICODE_WCHAR_T 500a48773fSEric van Gyzen # define XML_FMT_STR "ls" 510a48773fSEric van Gyzen #else 520a48773fSEric van Gyzen # define XML_FMT_STR "s" 530a48773fSEric van Gyzen #endif 540a48773fSEric van Gyzen 555bb6a25fSPoul-Henning Kamp int 560a48773fSEric van Gyzen filemap(const tchar *name, 570a48773fSEric van Gyzen void (*processor)(const void *, size_t, const tchar *, void *arg), 58*6b2c1e49SXin LI void *arg) { 595bb6a25fSPoul-Henning Kamp int fd; 605bb6a25fSPoul-Henning Kamp size_t nbytes; 615bb6a25fSPoul-Henning Kamp struct stat sb; 625bb6a25fSPoul-Henning Kamp void *p; 635bb6a25fSPoul-Henning Kamp 640a48773fSEric van Gyzen fd = topen(name, O_RDONLY); 655bb6a25fSPoul-Henning Kamp if (fd < 0) { 660a48773fSEric van Gyzen tperror(name); 675bb6a25fSPoul-Henning Kamp return 0; 685bb6a25fSPoul-Henning Kamp } 695bb6a25fSPoul-Henning Kamp if (fstat(fd, &sb) < 0) { 700a48773fSEric van Gyzen tperror(name); 715bb6a25fSPoul-Henning Kamp close(fd); 725bb6a25fSPoul-Henning Kamp return 0; 735bb6a25fSPoul-Henning Kamp } 745bb6a25fSPoul-Henning Kamp if (! S_ISREG(sb.st_mode)) { 755bb6a25fSPoul-Henning Kamp close(fd); 760a48773fSEric van Gyzen fprintf(stderr, "%" XML_FMT_STR ": not a regular file\n", name); 775bb6a25fSPoul-Henning Kamp return 0; 785bb6a25fSPoul-Henning Kamp } 790a48773fSEric van Gyzen if (sb.st_size > XML_MAX_CHUNK_LEN) { 800a48773fSEric van Gyzen close(fd); 810a48773fSEric van Gyzen return 2; /* Cannot be passed to XML_Parse in one go */ 820a48773fSEric van Gyzen } 835bb6a25fSPoul-Henning Kamp 845bb6a25fSPoul-Henning Kamp nbytes = sb.st_size; 85220ed979SColeman Kane /* mmap fails for zero length files */ 86220ed979SColeman Kane if (nbytes == 0) { 87220ed979SColeman Kane static const char c = '\0'; 88220ed979SColeman Kane processor(&c, 0, name, arg); 89220ed979SColeman Kane close(fd); 90220ed979SColeman Kane return 1; 91220ed979SColeman Kane } 92*6b2c1e49SXin LI p = (void *)mmap((void *)0, (size_t)nbytes, PROT_READ, MAP_FILE | MAP_PRIVATE, 93*6b2c1e49SXin LI fd, (off_t)0); 945bb6a25fSPoul-Henning Kamp if (p == (void *)-1) { 950a48773fSEric van Gyzen tperror(name); 965bb6a25fSPoul-Henning Kamp close(fd); 975bb6a25fSPoul-Henning Kamp return 0; 985bb6a25fSPoul-Henning Kamp } 995bb6a25fSPoul-Henning Kamp processor(p, nbytes, name, arg); 100be8aff81SXin LI munmap((void *)p, nbytes); 1015bb6a25fSPoul-Henning Kamp close(fd); 1025bb6a25fSPoul-Henning Kamp return 1; 1035bb6a25fSPoul-Henning Kamp } 104