1 /* -*- c-basic-offset: 4; indent-tabs-mode: nil -*- */
2 /* ====================================================================
3 * Copyright (c) 2005 Carnegie Mellon University. All rights
4 * reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 *
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
16 * distribution.
17 *
18 * This work was supported in part by funding from the Defense Advanced
19 * Research Projects Agency and the National Science Foundation of the
20 * United States of America, and the CMU Sphinx Speech Consortium.
21 *
22 * THIS SOFTWARE IS PROVIDED BY CARNEGIE MELLON UNIVERSITY ``AS IS'' AND
23 * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
24 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
25 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY
26 * NOR ITS EMPLOYEES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
28 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
32 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 *
34 * ====================================================================
35 *
36 */
37 /*********************************************************************
38 *
39 * File: mmio.c
40 *
41 * Description: mmap() wrappers for Unix/Windows
42 *
43 * Author: David Huggins-Daines <dhuggins@cs.cmu.edu>
44 *
45 *********************************************************************/
46
47 #include <string.h>
48 #include <stdlib.h>
49
50
51 #ifdef GNUWINCE
52 # include <sys/wcebase.h>
53 # include <sys/wcetypes.h>
54 # include <sys/wcememory.h>
55 # include <sys/wcefile.h>
56 #elif defined(__SYMBIAN32__) /* SYMBIAN32 must be before WIN32 since Symbian SDK defines WIN32 as well */
57 # include <unistd.h>
58 # include <fcntl.h>
59 # include <sys/stat.h>
60 # include <sys/mman.h>
61 #elif defined(_WIN32)
62 # include <windows.h>
63 #else
64 # include <unistd.h>
65 # include <fcntl.h>
66 # include <sys/stat.h>
67 # include <sys/file.h>
68 # include <sys/mman.h>
69 #endif
70
71 #include "sphinxbase/prim_type.h"
72 #include "sphinxbase/err.h"
73 #include "sphinxbase/mmio.h"
74 #include "sphinxbase/ckd_alloc.h"
75
76 #if defined(_WIN32_WCE) || defined(GNUWINCE)
77 struct mmio_file_s {
78 int dummy;
79 };
80
81 mmio_file_t *
mmio_file_read(const char * filename)82 mmio_file_read(const char *filename)
83 {
84 HANDLE ffm, fd;
85 WCHAR *wfilename;
86 void *rv;
87 int len;
88
89 len = mbstowcs(NULL, filename, 0) + 1;
90 wfilename = malloc(len * sizeof(WCHAR));
91 mbstowcs(wfilename, filename, len);
92
93 if ((ffm =
94 CreateFileForMappingW(wfilename, GENERIC_READ, FILE_SHARE_READ,
95 NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,
96 NULL)) == INVALID_HANDLE_VALUE) {
97 E_ERROR("Failed to create mapping for the file '%s': %08x\n", filename,
98 GetLastError());
99 return NULL;
100 }
101 if ((fd =
102 CreateFileMappingW(ffm, NULL, PAGE_READONLY, 0, 0, NULL)) == NULL) {
103 E_ERROR("Failed to CreateFileMapping: %08x\n", GetLastError());
104 CloseHandle(ffm);
105 return NULL;
106 }
107 rv = MapViewOfFile(fd, FILE_MAP_READ, 0, 0, 0);
108 free(wfilename);
109 CloseHandle(ffm);
110 CloseHandle(fd);
111
112 return (mmio_file_t *) rv;
113 }
114
115 void
mmio_file_unmap(mmio_file_t * mf)116 mmio_file_unmap(mmio_file_t *mf)
117 {
118 if (!UnmapViewOfFile((void *)mf)) {
119 E_ERROR("Failed to UnmapViewOfFile: %08x\n", GetLastError());
120 }
121 }
122
123 void *
mmio_file_ptr(mmio_file_t * mf)124 mmio_file_ptr(mmio_file_t *mf)
125 {
126 return (void *)mf;
127 }
128
129 #elif defined(_WIN32) && !defined(_WIN32_WP) /* !WINCE */
130 struct mmio_file_s {
131 int dummy;
132 };
133
134 mmio_file_t *
mmio_file_read(const char * filename)135 mmio_file_read(const char *filename)
136 {
137 HANDLE ffm, fd;
138 void *rv;
139
140 if ((ffm = CreateFile(filename, GENERIC_READ, FILE_SHARE_READ,
141 NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,
142 NULL)) == INVALID_HANDLE_VALUE) {
143 E_ERROR("Failed to create file '%s': %08x\n",
144 filename, GetLastError());
145 return NULL;
146 }
147 if ((fd = CreateFileMapping(ffm, NULL,
148 PAGE_READONLY, 0, 0, NULL)) == NULL) {
149 E_ERROR("Failed to CreateFileMapping: %08x\n", GetLastError());
150 CloseHandle(ffm);
151 }
152 rv = MapViewOfFile(fd, FILE_MAP_READ, 0, 0, 0);
153 CloseHandle(ffm);
154 CloseHandle(fd);
155
156 return (mmio_file_t *)rv;
157 }
158
159 void
mmio_file_unmap(mmio_file_t * mf)160 mmio_file_unmap(mmio_file_t *mf)
161 {
162 if (!UnmapViewOfFile((void *)mf)) {
163 E_ERROR("Failed to UnmapViewOfFile: %08x\n", GetLastError());
164 }
165 }
166
167 void *
mmio_file_ptr(mmio_file_t * mf)168 mmio_file_ptr(mmio_file_t *mf)
169 {
170 return (void *)mf;
171 }
172
173 #else /* !WIN32, !WINCE */
174 #if defined(__ADSPBLACKFIN__) || defined(_WIN32_WP)
175 /* This is true for both uClinux and VisualDSP++,
176 but actually we need a better way to detect it. */
177 struct mmio_file_s {
178 int dummy;
179 };
180
181 mmio_file_t *
mmio_file_read(const char * filename)182 mmio_file_read(const char *filename)
183 {
184 E_ERROR("mmio is not implemented on this platform!");
185 return NULL;
186 }
187
188 void
mmio_file_unmap(mmio_file_t * mf)189 mmio_file_unmap(mmio_file_t *mf)
190 {
191 E_ERROR("mmio is not implemented on this platform!");
192 }
193
194 void *
mmio_file_ptr(mmio_file_t * mf)195 mmio_file_ptr(mmio_file_t *mf)
196 {
197 E_ERROR("mmio is not implemented on this platform!");
198 return NULL;
199 }
200 #else /* !__ADSPBLACKFIN__ */
201 struct mmio_file_s {
202 void *ptr;
203 size_t mapsize;
204 };
205
206 mmio_file_t *
mmio_file_read(const char * filename)207 mmio_file_read(const char *filename)
208 {
209 mmio_file_t *mf;
210 struct stat buf;
211 void *ptr;
212 int fd;
213 size_t pagesize;
214
215 if ((fd = open(filename, O_RDONLY)) == -1) {
216 E_ERROR_SYSTEM("Failed to open %s", filename);
217 return NULL;
218 }
219 if (fstat(fd, &buf) == -1) {
220 E_ERROR_SYSTEM("Failed to stat %s", filename);
221 close(fd);
222 return NULL;
223 }
224 ptr = mmap(NULL, buf.st_size, PROT_READ, MAP_SHARED, fd, 0);
225 if (ptr == (void *)-1) {
226 E_ERROR_SYSTEM("Failed to mmap %lld bytes", (unsigned long long)buf.st_size);
227 close(fd);
228 return NULL;
229 }
230 close(fd);
231 mf = ckd_calloc(1, sizeof(*mf));
232 mf->ptr = ptr;
233 /* Align map size to next page. */
234 pagesize = sysconf(_SC_PAGESIZE);
235 mf->mapsize = (buf.st_size + pagesize - 1) / pagesize * pagesize;
236
237 return mf;
238 }
239
240 void
mmio_file_unmap(mmio_file_t * mf)241 mmio_file_unmap(mmio_file_t *mf)
242 {
243 if (mf == NULL)
244 return;
245 if (munmap(mf->ptr, mf->mapsize) < 0) {
246 E_ERROR_SYSTEM("Failed to unmap %ld bytes at %p", mf->mapsize, mf->ptr);
247 }
248 ckd_free(mf);
249 }
250
251 void *
mmio_file_ptr(mmio_file_t * mf)252 mmio_file_ptr(mmio_file_t *mf)
253 {
254 return mf->ptr;
255 }
256 #endif /* !__ADSPBLACKFIN__ */
257 #endif /* !(WINCE || WIN32) */
258