/*
******************************************************************************
*
*   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 "udatamem.h"
#include "umapfile.h"

/* memory-mapping base definitions ------------------------------------------ */

#if MAP_IMPLEMENTATION==MAP_WIN32
#   define WIN32_LEAN_AND_MEAN
#   define VC_EXTRALEAN
#   define NOUSER
#   define NOSERVICE
#   define NOIME
#   define NOMCX
#   include <windows.h>
#   include "cmemory.h"

    typedef HANDLE MemoryMap;

#   define IS_MAP(map) ((map)!=NULL)
#elif MAP_IMPLEMENTATION==MAP_POSIX || MAP_IMPLEMENTATION==MAP_390DLL
    typedef size_t MemoryMap;

#   define IS_MAP(map) ((map)!=0)

#   include <unistd.h>
#   include <sys/mman.h>
#   include <sys/stat.h>
#   include <fcntl.h>

#   ifndef MAP_FAILED
#       define MAP_FAILED ((void*)-1)
#   endif

#   if MAP_IMPLEMENTATION==MAP_390DLL
        /*   No memory mapping for 390 batch mode.  Fake it using dll loading.  */
#       include <dll.h>
#       include "cstring.h"
#       include "cmemory.h"
#       include "unicode/udata.h"
#       define LIB_PREFIX "lib"
#       define LIB_SUFFIX ".dll"
        /* 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
#       if defined(U_DARWIN)
#           include <TargetConditionals.h>
#       endif
#   endif
#elif MAP_IMPLEMENTATION==MAP_STDIO
#   include <stdio.h>
#   include "cmemory.h"

    typedef void *MemoryMap;

#   define IS_MAP(map) ((map)!=NULL)
#endif

/*----------------------------------------------------------------------------*
 *                                                                            *
 *   Memory Mapped File support.  Platform dependent implementation of        *
 *                           functions used by the rest of the implementation.*
 *                                                                            *
 *----------------------------------------------------------------------------*/
#if MAP_IMPLEMENTATION==MAP_NONE
    UBool
    uprv_mapFile(UDataMemory *pData, const char *path) {
        UDataMemory_init(pData); /* Clear the output struct. */
        return FALSE;            /* no file access */
    }

    void uprv_unmapFile(UDataMemory *pData) {
        /* nothing to do */
    }
#elif MAP_IMPLEMENTATION==MAP_WIN32
    UBool
    uprv_mapFile(
         UDataMemory *pData,    /* Fill in with info on the result doing the mapping. */
                                /*   Output only; any original contents are cleared.  */
         const char *path       /* File path to be opened/mapped                      */
         )
    {
        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=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, mappingAttributesPtr, PAGE_READONLY, 0, 0, NULL);
        CloseHandle(file);
        if(map==NULL) {
            return FALSE;
        }

        /* map a view of the file into our address space */
        pData->pHeader=(const DataHeader *)MapViewOfFile(map, FILE_MAP_READ, 0, 0, 0);
        if(pData->pHeader==NULL) {
            CloseHandle(map);
            return FALSE;
        }
        pData->map=map;
        return TRUE;
    }


    void
    uprv_unmapFile(UDataMemory *pData) {
        if(pData!=NULL && pData->map!=NULL) {
            UnmapViewOfFile(pData->pHeader);
            CloseHandle(pData->map);
            pData->pHeader=NULL;
            pData->map=NULL;
        }
    }



#elif MAP_IMPLEMENTATION==MAP_POSIX
    UBool
    uprv_mapFile(UDataMemory *pData, const char *path) {
        int fd;
        int length;
        struct stat mystat;
        void *data;

        UDataMemory_init(pData); /* Clear the output struct.        */

        /* determine the length of the file */
        if(stat(path, &mystat)!=0 || mystat.st_size<=0) {
            return FALSE;
        }
        length=mystat.st_size;

        /* open the file */
        fd=open(path, O_RDONLY);
        if(fd==-1) {
            return FALSE;
        }

        /* get a view of the mapping */
#ifndef U_HPUX
        data=mmap(0, length, PROT_READ, MAP_SHARED,  fd, 0);
#else
        data=mmap(0, length, PROT_READ, MAP_PRIVATE, fd, 0);
#endif
        close(fd); /* no longer needed */
        if(data==MAP_FAILED) {
            return FALSE;
        }

        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
    uprv_unmapFile(UDataMemory *pData) {
        if(pData!=NULL && pData->map!=NULL) {
            size_t dataLen = (char *)pData->map - (char *)pData->mapAddr;
            if(munmap(pData->mapAddr, dataLen)==-1) {
            }
            pData->pHeader=NULL;
            pData->map=0;
            pData->mapAddr=NULL;
        }
    }



#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;
    }

    UBool
    uprv_mapFile(UDataMemory *pData, const char *path) {
        FILE *file;
        int32_t fileLength;
        void *p;

        UDataMemory_init(pData); /* Clear the output struct.        */
        /* open the input file */
        file=fopen(path, "rb");
        if(file==NULL) {
            return FALSE;
        }

        /* get the file length */
        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) {
            fclose(file);
            return FALSE;
        }

        /* read the file */
        if(fileLength!=fread(p, 1, fileLength, file)) {
            uprv_free(p);
            fclose(file);
            return FALSE;
        }

        fclose(file);
        pData->map=p;
        pData->pHeader=(const DataHeader *)p;
        pData->mapAddr=p;
        return TRUE;
    }

    void
    uprv_unmapFile(UDataMemory *pData) {
        if(pData!=NULL && pData->map!=NULL) {
            uprv_free(pData->map);
            pData->map     = NULL;
            pData->mapAddr = NULL;
            pData->pHeader = NULL;
        }
    }


#elif MAP_IMPLEMENTATION==MAP_390DLL
    /*  390 specific Library Loading.
     *  This is the only platform left that dynamically loads an ICU Data Library.
     *  All other platforms use .data files when dynamic loading is required, but
     *  this turn out to be awkward to support in 390 batch mode.
     *
     *  The idea here is to hide the fact that 390 is using dll loading from the
     *   rest of ICU, and make it look like there is file loading happening.
     *
     */

    static char *strcpy_returnEnd(char *dest, const char *src)
    {
        while((*dest=*src)!=0) {
            ++dest;
            ++src;
        }
        return dest;
    }
    
    /*------------------------------------------------------------------------------
     *                                                                              
     *  computeDirPath   given a user-supplied path of an item to be opened,             
     *                         compute and return 
     *                            - the full directory path to be used 
     *                              when opening the file.
     *                            - Pointer to null at end of above returned path    
     *
     *                       Parameters:
     *                          path:        input path.  Buffer is not altered.
     *                          pathBuffer:  Output buffer.  Any contents are overwritten.
     *
     *                       Returns:
     *                          Pointer to null termination in returned pathBuffer.
     *
     *                    TODO:  This works the way ICU historically has, but the
     *                           whole data fallback search path is so complicated that
     *                           proabably almost no one will ever really understand it,
     *                           the potential for confusion is large.  (It's not just 
     *                           this one function, but the whole scheme.)
     *                            
     *------------------------------------------------------------------------------*/
    static char *uprv_computeDirPath(const char *path, char *pathBuffer)
    {
        char   *finalSlash;       /* Ptr to last dir separator in input path, or null if none. */
        int32_t pathLen;          /* Length of the returned directory path                     */
        
        finalSlash = 0;
        if (path != 0) {
            finalSlash = uprv_strrchr(path, U_FILE_SEP_CHAR);
        }
        
        *pathBuffer = 0;
        if (finalSlash == 0) {
        /* No user-supplied path.  
            * Copy the ICU_DATA path to the path buffer and return that*/
            const char *icuDataDir;
            icuDataDir=u_getDataDirectory();
            if(icuDataDir!=NULL && *icuDataDir!=0) {
                return strcpy_returnEnd(pathBuffer, icuDataDir);
            } else {
                /* there is no icuDataDir either.  Just return the empty pathBuffer. */
                return pathBuffer;
            }
        } 
        
        /* User supplied path did contain a directory portion.
        * Copy it to the output path buffer */
        pathLen = (int32_t)(finalSlash - path + 1);
        uprv_memcpy(pathBuffer, path, pathLen);
        *(pathBuffer+pathLen) = 0;
        return pathBuffer+pathLen;
    }
    

#   define DATA_TYPE "dat"

    UBool uprv_mapFile(UDataMemory *pData, const char *path) {
        const char *inBasename;
        char *basename;
        char pathBuffer[1024];
        const DataHeader *pHeader;
        dllhandle *handle;
        void *val=0;

        inBasename=uprv_strrchr(path, U_FILE_SEP_CHAR);
        if(inBasename==NULL) {
            inBasename = path;
        } else {
            inBasename++;
        }
        basename=uprv_computeDirPath(path, pathBuffer);
        if(uprv_strcmp(inBasename, U_ICUDATA_NAME".dat") != 0) {
            /* must mmap file... for build */
            int fd;
            int length;
            struct stat mystat;
            void *data;
            UDataMemory_init(pData); /* Clear the output struct. */

            /* determine the length of the file */
            if(stat(path, &mystat)!=0 || mystat.st_size<=0) {
                return FALSE;
            }
            length=mystat.st_size;

            /* open the file */
            fd=open(path, O_RDONLY);
            if(fd==-1) {
                return FALSE;
            }

            /* get a view of the mapping */
            data=mmap(0, length, PROT_READ, MAP_PRIVATE, fd, 0);
            close(fd); /* no longer needed */
            if(data==MAP_FAILED) {
                return FALSE;
            }
            pData->map = (char *)data + length;
            pData->pHeader=(const DataHeader *)data;
            pData->mapAddr = data;
            return TRUE;
        }

#       ifdef OS390BATCH
            /* ### hack: we still need to get u_getDataDirectory() fixed
            for OS/390 (batch mode - always return "//"? )
            and this here straightened out with LIB_PREFIX and LIB_SUFFIX (both empty?!)
            This is probably due to the strange file system on OS/390.  It's more like
            a database with short entry names than a typical file system. */
            /* U_ICUDATA_NAME should always have the correct name */
            /* BUT FOR BATCH MODE IT IS AN EXCEPTION BECAUSE */
            /* THE FIRST THREE LETTERS ARE PREASSIGNED TO THE */
            /* PROJECT!!!!! */
            uprv_strcpy(pathBuffer, "IXMI" U_ICU_VERSION_SHORT "DA");
#       else
            /* set up the library name */
            uprv_strcpy(basename, LIB_PREFIX U_LIBICUDATA_NAME U_ICU_VERSION_SHORT LIB_SUFFIX);
#       endif

#       ifdef UDATA_DEBUG
             fprintf(stderr, "dllload: %s ", pathBuffer);
#       endif

        handle=dllload(pathBuffer);

#       ifdef UDATA_DEBUG
               fprintf(stderr, " -> %08X\n", handle );
#       endif

        if(handle != NULL) {
               /* we have a data DLL - what kind of lookup do we need here? */
               /* try to find the Table of Contents */
               UDataMemory_init(pData); /* Clear the output struct.        */
               val=dllqueryvar((dllhandle*)handle, U_ICUDATA_ENTRY_NAME);
               if(val == 0) {
                    /* failed... so keep looking */
                    return FALSE;
               }
#              ifdef UDATA_DEBUG
                    fprintf(stderr, "dllqueryvar(%08X, %s) -> %08X\n", handle, U_ICUDATA_ENTRY_NAME, val);
#              endif

               pData->pHeader=(const DataHeader *)val;
               return TRUE;
         } else {
               return FALSE; /* no handle */
         }
    }



    void uprv_unmapFile(UDataMemory *pData) {
        if(pData!=NULL && pData->map!=NULL) {
            uprv_free(pData->map);
            pData->map     = NULL;
            pData->mapAddr = NULL;
            pData->pHeader = NULL;
        }   
    }

#else
#   error MAP_IMPLEMENTATION is set incorrectly
#endif
