/*
******************************************************************************
*
-* Copyright (C) 1999-2004, International Business Machines
+* Copyright (C) 1999-2010, International Business Machines
* Corporation and others. All Rights Reserved.
*
******************************************************************************/
/*----------------------------------------------------------------------------
- *
+ *
* Memory mapped file wrappers for use by the ICU Data Implementation
* All of the platform-specific implementation for mapping data files
* is here. The rest of the ICU Data implementation uses only the
* wrapper functions.
*
*----------------------------------------------------------------------------*/
-#include "unicode/putil.h"
-
+#include "unicode/putil.h"
#include "udatamem.h"
#include "umapfile.h"
-
/* memory-mapping base definitions ------------------------------------------ */
-
-#define MAP_WIN32 1
-#define MAP_POSIX 2
-#define MAP_FILE_STREAM 3
-#define MAP_390DLL 4
-
-#ifdef WIN32
+#if MAP_IMPLEMENTATION==MAP_WIN32
# define WIN32_LEAN_AND_MEAN
# define VC_EXTRALEAN
# define NOUSER
# define NOIME
# define NOMCX
# include <windows.h>
+# include "cmemory.h"
typedef HANDLE MemoryMap;
# define IS_MAP(map) ((map)!=NULL)
-
-# define MAP_IMPLEMENTATION MAP_WIN32
-
-/* ### Todo: properly auto detect mmap(). Until then, just add your platform here. */
-#elif U_HAVE_MMAP || defined(U_AIX) || defined(U_HPUX) || defined(OS390) || defined(PTX)
+#elif MAP_IMPLEMENTATION==MAP_POSIX || MAP_IMPLEMENTATION==MAP_390DLL
typedef size_t MemoryMap;
# define IS_MAP(map) ((map)!=0)
- /* Needed by OSF to get the correct mmap version */
-# ifndef _XOPEN_SOURCE_EXTENDED
-# define _XOPEN_SOURCE_EXTENDED
-# endif
-
# include <unistd.h>
# include <sys/mman.h>
# include <sys/stat.h>
# define MAP_FAILED ((void*)-1)
# endif
-# if defined(OS390) && defined (OS390_STUBDATA)
+# if MAP_IMPLEMENTATION==MAP_390DLL
/* No memory mapping for 390 batch mode. Fake it using dll loading. */
# include <dll.h>
# include "cstring.h"
# include "unicode/udata.h"
# define LIB_PREFIX "lib"
# define LIB_SUFFIX ".dll"
-# define MAP_IMPLEMENTATION MAP_390DLL
-
-/* This is inconvienient until we figure out what to do with U_ICUDATA_NAME in utypes.h */
+ /* This is inconvienient until we figure out what to do with U_ICUDATA_NAME in utypes.h */
# define U_ICUDATA_ENTRY_NAME "icudt" U_ICU_VERSION_SHORT U_LIB_SUFFIX_C_NAME_STRING "_dat"
# else
-# define MAP_IMPLEMENTATION MAP_POSIX
+# if defined(U_DARWIN)
+# include <TargetConditionals.h>
+# endif
# endif
-
-#else /* unknown platform, no memory map implementation: use FileStream/uprv_malloc() instead */
-
-# include "filestrm.h"
+#elif MAP_IMPLEMENTATION==MAP_STDIO
+# include <stdio.h>
# include "cmemory.h"
typedef void *MemoryMap;
# define IS_MAP(map) ((map)!=NULL)
-
-# define MAP_IMPLEMENTATION MAP_FILE_STREAM
-
#endif
-
-
-
/*----------------------------------------------------------------------------*
* *
* Memory Mapped File support. Platform dependent implementation of *
* functions used by the rest of the implementation.*
* *
*----------------------------------------------------------------------------*/
-#if MAP_IMPLEMENTATION==MAP_WIN32
- UBool
+#if MAP_IMPLEMENTATION==MAP_NONE
+ U_CFUNC UBool
+ uprv_mapFile(UDataMemory *pData, const char *path) {
+ UDataMemory_init(pData); /* Clear the output struct. */
+ return FALSE; /* no file access */
+ }
+
+ U_CFUNC void uprv_unmapFile(UDataMemory *pData) {
+ /* nothing to do */
+ }
+#elif MAP_IMPLEMENTATION==MAP_WIN32
+ U_CFUNC UBool
uprv_mapFile(
UDataMemory *pData, /* Fill in with info on the result doing the mapping. */
/* Output only; any original contents are cleared. */
{
HANDLE map;
HANDLE file;
+ SECURITY_ATTRIBUTES mappingAttributes;
+ SECURITY_ATTRIBUTES *mappingAttributesPtr = NULL;
+ SECURITY_DESCRIPTOR securityDesc;
UDataMemory_init(pData); /* Clear the output struct. */
/* open the input file */
- file=CreateFile(path, GENERIC_READ, FILE_SHARE_READ, NULL,
+ file=CreateFileA(path, GENERIC_READ, FILE_SHARE_READ, NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL|FILE_FLAG_RANDOM_ACCESS, NULL);
if(file==INVALID_HANDLE_VALUE) {
return FALSE;
}
+ /* Declare and initialize a security descriptor.
+ This is required for multiuser systems on Windows 2000 SP4 and beyond */
+ if (InitializeSecurityDescriptor(&securityDesc, SECURITY_DESCRIPTOR_REVISION)) {
+ /* give the security descriptor a Null Dacl done using the "TRUE, (PACL)NULL" here */
+ if (SetSecurityDescriptorDacl(&securityDesc, TRUE, (PACL)NULL, FALSE)) {
+ /* Make the security attributes point to the security descriptor */
+ uprv_memset(&mappingAttributes, 0, sizeof(mappingAttributes));
+ mappingAttributes.nLength = sizeof(mappingAttributes);
+ mappingAttributes.lpSecurityDescriptor = &securityDesc;
+ mappingAttributes.bInheritHandle = FALSE; /* object uninheritable */
+ mappingAttributesPtr = &mappingAttributes;
+ }
+ }
+ /* else creating security descriptors can fail when we are on Windows 98,
+ and mappingAttributesPtr == NULL for that case. */
+
/* create an unnamed Windows file-mapping object for the specified file */
- map=CreateFileMapping(file, NULL, PAGE_READONLY, 0, 0, NULL);
+ map=CreateFileMapping(file, mappingAttributesPtr, PAGE_READONLY, 0, 0, NULL);
CloseHandle(file);
if(map==NULL) {
return FALSE;
return TRUE;
}
-
- void
+ U_CFUNC void
uprv_unmapFile(UDataMemory *pData) {
if(pData!=NULL && pData->map!=NULL) {
UnmapViewOfFile(pData->pHeader);
#elif MAP_IMPLEMENTATION==MAP_POSIX
- UBool
+ U_CFUNC UBool
uprv_mapFile(UDataMemory *pData, const char *path) {
int fd;
int length;
pData->map = (char *)data + length;
pData->pHeader=(const DataHeader *)data;
pData->mapAddr = data;
+#if defined(U_DARWIN) && TARGET_OS_IPHONE
+ posix_madvise(data, length, POSIX_MADV_RANDOM);
+#endif
return TRUE;
}
-
-
- void
+ U_CFUNC void
uprv_unmapFile(UDataMemory *pData) {
if(pData!=NULL && pData->map!=NULL) {
size_t dataLen = (char *)pData->map - (char *)pData->mapAddr;
-#elif MAP_IMPLEMENTATION==MAP_FILE_STREAM
- UBool
+#elif MAP_IMPLEMENTATION==MAP_STDIO
+ /* copy of the filestrm.c/T_FileStream_size() implementation */
+ static int32_t
+ umap_fsize(FILE *f) {
+ int32_t savedPos = ftell(f);
+ int32_t size = 0;
+
+ /*Changes by Bertrand A. D. doesn't affect the current position
+ goes to the end of the file before ftell*/
+ fseek(f, 0, SEEK_END);
+ size = (int32_t)ftell(f);
+ fseek(f, savedPos, SEEK_SET);
+ return size;
+ }
+
+ U_CFUNC UBool
uprv_mapFile(UDataMemory *pData, const char *path) {
- FileStream *file;
+ FILE *file;
int32_t fileLength;
void *p;
UDataMemory_init(pData); /* Clear the output struct. */
/* open the input file */
- file=T_FileStream_open(path, "rb");
+ file=fopen(path, "rb");
if(file==NULL) {
return FALSE;
}
/* get the file length */
- fileLength=T_FileStream_size(file);
- if(T_FileStream_error(file) || fileLength<=20) {
- T_FileStream_close(file);
+ fileLength=umap_fsize(file);
+ if(ferror(file) || fileLength<=20) {
+ fclose(file);
return FALSE;
}
/* allocate the memory to hold the file data */
p=uprv_malloc(fileLength);
if(p==NULL) {
- T_FileStream_close(file);
+ fclose(file);
return FALSE;
}
/* read the file */
- if(fileLength!=T_FileStream_read(file, p, fileLength)) {
+ if(fileLength!=fread(p, 1, fileLength, file)) {
uprv_free(p);
- T_FileStream_close(file);
+ fclose(file);
return FALSE;
}
- T_FileStream_close(file);
+ fclose(file);
pData->map=p;
pData->pHeader=(const DataHeader *)p;
pData->mapAddr=p;
return TRUE;
}
- void
+ U_CFUNC void
uprv_unmapFile(UDataMemory *pData) {
if(pData!=NULL && pData->map!=NULL) {
uprv_free(pData->map);
# define DATA_TYPE "dat"
- UBool uprv_mapFile(UDataMemory *pData, const char *path) {
+ U_CFUNC UBool uprv_mapFile(UDataMemory *pData, const char *path) {
const char *inBasename;
char *basename;
char pathBuffer[1024];
}
}
-
-
- void uprv_unmapFile(UDataMemory *pData) {
+ U_CFUNC void uprv_unmapFile(UDataMemory *pData) {
if(pData!=NULL && pData->map!=NULL) {
uprv_free(pData->map);
pData->map = NULL;
#else
# error MAP_IMPLEMENTATION is set incorrectly
#endif
-
-