File Coverage

loadfile.inc
Criterion Covered Total %
statement 12 12 100.0
branch 1 2 50.0
condition n/a
subroutine n/a
pod n/a
total 13 14 92.8


line stmt bran cond sub pod time code
1             /* -*- c -*-
2             * File: loadfile.h
3             * Author: Igor Vlasenko
4             * Created: Thu Sep 8 17:16:48 2005
5             *
6             * $Id$
7             */
8              
9             #ifdef HAVE_CONFIG_H
10             #include "config.h"
11             #endif
12              
13             #ifdef USE_MMAP
14              
15             #ifdef WIN32
16             /*
17             * the win32 code of Viacheslav Sheveliov
18             * viy: should work for win64 too.
19             */
20              
21             #include
22             #include
23              
24             static PSTRING mmap_load_file(const char *filepath) {
25             PSTRING memarea = { NULL, NULL };
26             HANDLE hFile, hMapObject = NULL;
27              
28             hFile = CreateFile(
29             TEXT(filepath),
30             GENERIC_READ,
31             FILE_SHARE_READ,
32             NULL,
33             OPEN_EXISTING,
34             FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,
35             NULL
36             );
37              
38             if (hFile != INVALID_HANDLE_VALUE) {
39             hMapObject = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
40              
41             if (hMapObject) {
42             // Get a pointer to the file-mapped shared memory.
43             LPCTSTR lpvMem = (LPTSTR) MapViewOfFile(hMapObject, FILE_MAP_READ, 0, 0, 0);
44              
45             if (lpvMem) {
46             // Everything OK!
47              
48             memarea.begin = (char *) lpvMem;
49             memarea.endnext = memarea.begin + GetFileSize(hFile, NULL);
50             // After MapViewOfFile we don't need file handles no more.
51             // Undocumented, but it works! (In read-only mode?)
52             CloseHandle(hMapObject);
53             CloseHandle(hFile);
54              
55             return memarea;
56              
57             }
58             }
59             }
60              
61             // Something goes wrong
62              
63             {
64             // Save last error code, before any system call
65             DWORD dwLastError = GetLastError();
66              
67             // Report error, if file size != 0
68             // Mapping of zero-length file cause CreateFileMapping to fail.
69             // So skip error messages in this case.
70             if (hFile == INVALID_HANDLE_VALUE && GetFileSize(hFile, NULL) != 0)
71             fprintf(stderr, "Could not open file '%s'. (system error#%ld)\n", filepath, dwLastError);
72              
73             }
74             // Close all opened handles
75             if (hMapObject) CloseHandle(hMapObject);
76             if (hFile != INVALID_HANDLE_VALUE) CloseHandle(hFile);
77              
78             return memarea;
79             }
80              
81             /* we use function, not define, because someday we may need its address */
82             static int mmap_unload_file(PSTRING memarea) { return UnmapViewOfFile((void*) memarea.begin) ? 0 : -1; };
83             /* define mmap_unload_file(map) (UnmapViewOfFile((LPCVOID) map.begin) ? 0 : -1) */
84              
85             #else /* unix, sweet unix :) */
86             #if defined(HAVE_SYS_MMAN_H) && defined(HAVE_SYS_STAT_H)
87              
88             /* # define NULL 0 */
89             #include
90             #include
91             #include /* open */
92             #include /* close */
93              
94             static
95             PSTRING
96 301           mmap_load_file (const char* filepath) {
97             int fd;
98             struct stat st;
99             size_t size_in_bytes;
100 301           PSTRING memarea={NULL,NULL};
101 301           fd = open(filepath, O_RDONLY);
102 301 50         if (fd == -1) return memarea; /* {NULL,NULL} */
103 301           fstat(fd, &st);
104 301           size_in_bytes = st.st_size;
105             /* mmap size_in_bytes+1 to avoid crash with empty file */
106 301           memarea.begin = (char *) mmap(0, size_in_bytes+1, PROT_READ, MAP_SHARED, fd, 0);
107 301           close(fd);
108 301           memarea.endnext=memarea.begin+size_in_bytes;
109 301           return memarea;
110             }
111              
112             static
113             int
114 301           mmap_unload_file (PSTRING memarea) {
115             /* destroying */
116 301           return munmap((void *)memarea.begin, memarea.endnext-memarea.begin);
117             }
118              
119             #endif /* UNIX */
120             #endif /* WIN32 */
121              
122             #else
123             /*
124             * system seems to have no mmap ;
125             * we use standard C buffered read
126             */
127             #include
128             static
129             PSTRING
130             mmap_load_file (const char* filepath) {
131             FILE *stream;
132             size_t size_in_bytes=0;
133             size_t realsize;
134             size_t chunksize=4096;
135             size_t memsize=chunksize;
136             PSTRING memarea={NULL,NULL};
137             char* writepoint;
138             /* text mode for HTML::Template compatibility */
139             stream = fopen(filepath, "r");
140             if (stream == NULL) return memarea; /* {NULL,NULL} */
141             /* mmap size_in_bytes+1 to avoid crash with empty file */
142             memarea.begin=(const char*) malloc(memsize+1);
143             writepoint=(char*)memarea.begin;
144              
145             while (1) {
146             realsize=fread(writepoint, 1, chunksize, stream);
147             size_in_bytes+=realsize;
148             if (realsize==chunksize) {
149             writepoint+=chunksize;
150             if (size_in_bytes+chunksize>memsize) {
151             memsize*=2;
152             memarea.begin=(char*) realloc((char*)memarea.begin, memsize+1);
153             writepoint=((char*)memarea.begin)+size_in_bytes;
154             }
155             } else {
156             fclose(stream);
157             memarea.endnext=memarea.begin+size_in_bytes;
158             return memarea;
159             }
160             }
161             }
162              
163             static
164             int
165             mmap_unload_file (PSTRING memarea) {
166             /* destroying */
167             free((char*)memarea.begin);
168             return 0;
169             }
170              
171             #endif /* USE_MMAP */