SphinxBase 0.6
|
00001 /* -*- c-basic-offset: 4; indent-tabs-mode: nil -*- */ 00002 /* ==================================================================== 00003 * Copyright (c) 2005 Carnegie Mellon University. All rights 00004 * reserved. 00005 * 00006 * Redistribution and use in source and binary forms, with or without 00007 * modification, are permitted provided that the following conditions 00008 * are met: 00009 * 00010 * 1. Redistributions of source code must retain the above copyright 00011 * notice, this list of conditions and the following disclaimer. 00012 * 00013 * 2. Redistributions in binary form must reproduce the above copyright 00014 * notice, this list of conditions and the following disclaimer in 00015 * the documentation and/or other materials provided with the 00016 * distribution. 00017 * 00018 * This work was supported in part by funding from the Defense Advanced 00019 * Research Projects Agency and the National Science Foundation of the 00020 * United States of America, and the CMU Sphinx Speech Consortium. 00021 * 00022 * THIS SOFTWARE IS PROVIDED BY CARNEGIE MELLON UNIVERSITY ``AS IS'' AND 00023 * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 00024 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 00025 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY 00026 * NOR ITS EMPLOYEES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 00027 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 00028 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 00029 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 00030 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00031 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 00032 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00033 * 00034 * ==================================================================== 00035 * 00036 */ 00037 /********************************************************************* 00038 * 00039 * File: mmio.c 00040 * 00041 * Description: mmap() wrappers for Unix/Windows 00042 * 00043 * Author: David Huggins-Daines <dhuggins@cs.cmu.edu> 00044 * 00045 *********************************************************************/ 00046 00047 #include <string.h> 00048 #include <stdlib.h> 00049 00050 #ifdef GNUWINCE 00051 # include <sys/wcebase.h> 00052 # include <sys/wcetypes.h> 00053 # include <sys/wcememory.h> 00054 # include <sys/wcefile.h> 00055 #elif defined(__SYMBIAN32__) /* SYMBIAN32 must be before WIN32 since Symbian SDK defines WIN32 as well */ 00056 # include <unistd.h> 00057 # include <fcntl.h> 00058 # include <sys/stat.h> 00059 # include <sys/mman.h> 00060 #elif defined(_WIN32) 00061 # include <windows.h> 00062 #else 00063 # include <unistd.h> 00064 # include <fcntl.h> 00065 # include <sys/stat.h> 00066 # include <sys/file.h> 00067 # include <sys/mman.h> 00068 #endif 00069 00070 #include "sphinxbase/prim_type.h" 00071 #include "sphinxbase/err.h" 00072 #include "sphinxbase/mmio.h" 00073 #include "sphinxbase/ckd_alloc.h" 00074 00076 #if defined(_WIN32_WCE) || defined(GNUWINCE) 00077 struct mmio_file_s { 00078 int dummy; 00079 }; 00080 00081 mmio_file_t * 00082 mmio_file_read(const char *filename) 00083 { 00084 HANDLE ffm, fd; 00085 WCHAR *wfilename; 00086 void *rv; 00087 int len; 00088 00089 len = mbstowcs(NULL, filename, 0) + 1; 00090 wfilename = malloc(len * sizeof(WCHAR)); 00091 mbstowcs(wfilename, filename, len); 00092 00093 if ((ffm = 00094 CreateFileForMappingW(wfilename, GENERIC_READ, FILE_SHARE_READ, 00095 NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 00096 NULL)) == INVALID_HANDLE_VALUE) { 00097 E_ERROR("Failed to CreateFileForMapping(%s): %08x\n", filename, 00098 GetLastError()); 00099 return NULL; 00100 } 00101 if ((fd = 00102 CreateFileMappingW(ffm, NULL, PAGE_READONLY, 0, 0, NULL)) == NULL) { 00103 E_ERROR("Failed to CreateFileMapping: %08x\n", GetLastError()); 00104 CloseHandle(ffm); 00105 return NULL; 00106 } 00107 rv = MapViewOfFile(fd, FILE_MAP_READ, 0, 0, 0); 00108 free(wfilename); 00109 CloseHandle(ffm); 00110 CloseHandle(fd); 00111 00112 return (mmio_file_t *) rv; 00113 } 00114 00115 void 00116 mmio_file_unmap(mmio_file_t *mf) 00117 { 00118 if (!UnmapViewOfFile((void *)mf)) { 00119 E_ERROR("Failed to UnmapViewOfFile: %08x\n", GetLastError()); 00120 } 00121 } 00122 00123 void * 00124 mmio_file_ptr(mmio_file_t *mf) 00125 { 00126 return (void *)mf; 00127 } 00128 00129 #elif defined(WIN32) /* !WINCE */ 00130 struct mmio_file_s { 00131 int dummy; 00132 }; 00133 00134 mmio_file_t * 00135 mmio_file_read(const char *filename) 00136 { 00137 HANDLE ffm, fd; 00138 void *rv; 00139 00140 if ((ffm = CreateFile(filename, GENERIC_READ, FILE_SHARE_READ, 00141 NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 00142 NULL)) == INVALID_HANDLE_VALUE) { 00143 E_ERROR("Failed to CreateFile(%s): %08x\n", 00144 filename, GetLastError()); 00145 return NULL; 00146 } 00147 if ((fd = CreateFileMapping(ffm, NULL, 00148 PAGE_READONLY, 0, 0, NULL)) == NULL) { 00149 E_ERROR("Failed to CreateFileMapping: %08x\n", GetLastError()); 00150 CloseHandle(ffm); 00151 } 00152 rv = MapViewOfFile(fd, FILE_MAP_READ, 0, 0, 0); 00153 CloseHandle(ffm); 00154 CloseHandle(fd); 00155 00156 return (mmio_file_t *)rv; 00157 } 00158 00159 void 00160 mmio_file_unmap(mmio_file_t *mf) 00161 { 00162 if (!UnmapViewOfFile((void *)mf)) { 00163 E_ERROR("Failed to UnmapViewOfFile: %08x\n", GetLastError()); 00164 } 00165 } 00166 00167 void * 00168 mmio_file_ptr(mmio_file_t *mf) 00169 { 00170 return (void *)mf; 00171 } 00172 00173 #else /* !WIN32, !WINCE */ 00174 #if defined(__ADSPBLACKFIN__) /* This is true for both uClinux and VisualDSP++, 00175 but actually we need a better way to detect it. */ 00176 struct mmio_file_s { 00177 int dummy; 00178 }; 00179 00180 mmio_file_t * 00181 mmio_file_read(const char *filename) 00182 { 00183 E_FATAL("mmio is not implemented on this platform!"); 00184 return NULL; 00185 } 00186 00187 void 00188 mmio_file_unmap(mmio_file_t *mf) 00189 { 00190 E_FATAL("mmio is not implemented on this platform!"); 00191 } 00192 00193 void * 00194 mmio_file_ptr(mmio_file_t *mf) 00195 { 00196 E_FATAL("mmio is not implemented on this platform!"); 00197 return NULL; 00198 } 00199 #else /* !__ADSPBLACKFIN__ */ 00200 struct mmio_file_s { 00201 void *ptr; 00202 size_t mapsize; 00203 }; 00204 00205 mmio_file_t * 00206 mmio_file_read(const char *filename) 00207 { 00208 mmio_file_t *mf; 00209 struct stat buf; 00210 void *ptr; 00211 int fd; 00212 size_t pagesize; 00213 00214 if ((fd = open(filename, O_RDONLY)) == -1) { 00215 E_ERROR_SYSTEM("Failed to open %s", filename); 00216 return NULL; 00217 } 00218 if (fstat(fd, &buf) == -1) { 00219 E_ERROR_SYSTEM("Failed to stat %s", filename); 00220 return NULL; 00221 } 00222 ptr = mmap(NULL, buf.st_size, PROT_READ, MAP_SHARED, fd, 0); 00223 if (ptr == (void *)-1) { 00224 E_ERROR_SYSTEM("Failed to mmap %lld bytes", (unsigned long long)buf.st_size); 00225 return NULL; 00226 } 00227 close(fd); 00228 mf = ckd_calloc(1, sizeof(*mf)); 00229 mf->ptr = ptr; 00230 /* Align map size to next page. */ 00231 pagesize = getpagesize(); 00232 mf->mapsize = (buf.st_size + pagesize - 1) / pagesize * pagesize; 00233 00234 return mf; 00235 } 00236 00237 void 00238 mmio_file_unmap(mmio_file_t *mf) 00239 { 00240 if (mf == NULL) 00241 return; 00242 if (munmap(mf->ptr, mf->mapsize) < 0) { 00243 E_ERROR_SYSTEM("Failed to unmap %ld bytes at %p", mf->mapsize, mf->ptr); 00244 } 00245 ckd_free(mf); 00246 } 00247 00248 void * 00249 mmio_file_ptr(mmio_file_t *mf) 00250 { 00251 return mf->ptr; 00252 } 00253 #endif /* !__ADSPBLACKFIN__ */ 00254 #endif /* !(WINCE || WIN32) */