SphinxBase  0.6
mmio.c
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 #ifdef GNUWINCE
51 # include <sys/wcebase.h>
52 # include <sys/wcetypes.h>
53 # include <sys/wcememory.h>
54 # include <sys/wcefile.h>
55 #elif defined(__SYMBIAN32__) /* SYMBIAN32 must be before WIN32 since Symbian SDK defines WIN32 as well */
56 # include <unistd.h>
57 # include <fcntl.h>
58 # include <sys/stat.h>
59 # include <sys/mman.h>
60 #elif defined(_WIN32)
61 # include <windows.h>
62 #else
63 # include <unistd.h>
64 # include <fcntl.h>
65 # include <sys/stat.h>
66 # include <sys/file.h>
67 # include <sys/mman.h>
68 #endif
69 
70 #include "sphinxbase/prim_type.h"
71 #include "sphinxbase/err.h"
72 #include "sphinxbase/mmio.h"
73 #include "sphinxbase/ckd_alloc.h"
74 
76 #if defined(_WIN32_WCE) || defined(GNUWINCE)
77 struct mmio_file_s {
78  int dummy;
79 };
80 
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
117 {
118  if (!UnmapViewOfFile((void *)mf)) {
119  E_ERROR("Failed to UnmapViewOfFile: %08x\n", GetLastError());
120  }
121 }
122 
123 void *
125 {
126  return (void *)mf;
127 }
128 
129 #elif defined(WIN32) /* !WINCE */
130 struct mmio_file_s {
131  int dummy;
132 };
133 
134 mmio_file_t *
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
161 {
162  if (!UnmapViewOfFile((void *)mf)) {
163  E_ERROR("Failed to UnmapViewOfFile: %08x\n", GetLastError());
164  }
165 }
166 
167 void *
169 {
170  return (void *)mf;
171 }
172 
173 #else /* !WIN32, !WINCE */
174 #if defined(__ADSPBLACKFIN__) /* This is true for both uClinux and VisualDSP++,
175  but actually we need a better way to detect it. */
176 struct mmio_file_s {
177  int dummy;
178 };
179 
180 mmio_file_t *
181 mmio_file_read(const char *filename)
182 {
183  E_FATAL("mmio is not implemented on this platform!");
184  return NULL;
185 }
186 
187 void
189 {
190  E_FATAL("mmio is not implemented on this platform!");
191 }
192 
193 void *
195 {
196  E_FATAL("mmio is not implemented on this platform!");
197  return NULL;
198 }
199 #else /* !__ADSPBLACKFIN__ */
200 struct mmio_file_s {
201  void *ptr;
202  size_t mapsize;
203 };
204 
205 mmio_file_t *
206 mmio_file_read(const char *filename)
207 {
208  mmio_file_t *mf;
209  struct stat buf;
210  void *ptr;
211  int fd;
212  size_t pagesize;
213 
214  if ((fd = open(filename, O_RDONLY)) == -1) {
215  E_ERROR_SYSTEM("Failed to open %s", filename);
216  return NULL;
217  }
218  if (fstat(fd, &buf) == -1) {
219  E_ERROR_SYSTEM("Failed to stat %s", filename);
220  close(fd);
221  return NULL;
222  }
223  ptr = mmap(NULL, buf.st_size, PROT_READ, MAP_SHARED, fd, 0);
224  if (ptr == (void *)-1) {
225  E_ERROR_SYSTEM("Failed to mmap %lld bytes", (unsigned long long)buf.st_size);
226  close(fd);
227  return NULL;
228  }
229  close(fd);
230  mf = ckd_calloc(1, sizeof(*mf));
231  mf->ptr = ptr;
232  /* Align map size to next page. */
233  pagesize = getpagesize();
234  mf->mapsize = (buf.st_size + pagesize - 1) / pagesize * pagesize;
235 
236  return mf;
237 }
238 
239 void
241 {
242  if (mf == NULL)
243  return;
244  if (munmap(mf->ptr, mf->mapsize) < 0) {
245  E_ERROR_SYSTEM("Failed to unmap %ld bytes at %p", mf->mapsize, mf->ptr);
246  }
247  ckd_free(mf);
248 }
249 
250 void *
252 {
253  return mf->ptr;
254 }
255 #endif /* !__ADSPBLACKFIN__ */
256 #endif /* !(WINCE || WIN32) */
#define ckd_calloc(n, sz)
Macros to simplify the use of above functions.
Definition: ckd_alloc.h:248
Silvio Moioli: slightly updated.
Definition: mmio.c:200
Sphinx's memory allocation/deallocation routines.
SPHINXBASE_EXPORT void mmio_file_unmap(mmio_file_t *mf)
Unmap a file, releasing memory associated with it.
Definition: mmio.c:240
Basic type definitions used in Sphinx.
SPHINXBASE_EXPORT void ckd_free(void *ptr)
Test and free a 1-D array.
Definition: ckd_alloc.c:241
SPHINXBASE_EXPORT void * mmio_file_ptr(mmio_file_t *mf)
Get a pointer to the memory mapped for a file.
Definition: mmio.c:251
Implementation of logging routines.
#define E_FATAL
Exit with non-zero status after error message.
Definition: err.h:127
#define E_ERROR
Print error message to standard error stream.
Definition: err.h:169
#define E_ERROR_SYSTEM
Print error text; Call perror("");.
Definition: err.h:142
SPHINXBASE_EXPORT mmio_file_t * mmio_file_read(const char *filename)
Memory-map a file for reading.
Definition: mmio.c:206
Memory-mapped I/O wrappers for files.