/*******************************************************************************
 *  INTEL CONFIDENTIAL
 *  Copyright 2007 Intel Corporation All Rights Reserved.
 *
 *  The source code contained or described herein and all documents related to
 *  the source code ("Material") are owned by Intel Corporation or its suppliers
 *  or licensors. Title to the Material remains with Intel Corporation or its
 *  suppliers and licensors. The Material may contain trade secrets and
 *  proprietary and confidential information of Intel Corporation and its
 *  suppliers and licensors, and is protected by worldwide copyright and trade
 *  secret laws and treaty provisions. No part of the Material may be used,
 *  copied, reproduced, modified, published, uploaded, posted, transmitted,
 *  distributed, or disclosed in any way without Intel's prior express written
 *  permission. 
 *  
 *  No license under any patent, copyright, trade secret or other intellectual
 *  property right is granted to or conferred upon you by disclosure or delivery
 *  of the Materials, either expressly, by implication, inducement, estoppel or
 *  otherwise. Any license under such intellectual property rights must be
 *  express and approved by Intel in writing.
 *
 *  Unless otherwise agreed by Intel in writing, you may not remove or alter
 *  this notice or any other notice embedded in Materials by Intel or Intel's
 *  suppliers or licensors in any way.
 ******************************************************************************/

/******************************************************************************
 *
 * Description:
 *   This file contains the Linux implementation of the functions to map and
 *   unmap files onto/from memory.
 *
 ******************************************************************************/

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

typedef struct
{
    int     fd;
    void*   startAddress;
    size_t  size;
} MEMMAP_CONTROL;

/******************************************************************************
 * Name: MapFileOntoMemory
 *
 * Description:
 *   Maps a file onto memory.
 ******************************************************************************/
MEMMAP_HANDLE MapFileOntoMemory(
    const char* pFileName
    )
{
    MEMMAP_CONTROL* pControl;
    struct stat     fileStats;

    /* Create the structure to keep information about the mapping             */
    pControl = (MEMMAP_CONTROL *) malloc(sizeof(MEMMAP_CONTROL));
    if (NULL == pControl)
    {
        pControl = INVALID_MEMMAP_HANDLE;
        goto EXIT;
    }

    /* To map a file onto memory in Win32, the following steps are taken:
       1.  Open the file.
       2.  Map the file onto memory.                                          */
    pControl->fd = open(pFileName, O_RDONLY);
    if (-1 == pControl->fd)
    {
        goto FREE_MEMORY;
    }

    if (fstat(pControl->fd, &fileStats) == -1)
    {
        goto CLOSE_FILE;
    }

    pControl->size = fileStats.st_size;

    pControl->startAddress = mmap(
        0,
        pControl->size,
        PROT_READ,
        MAP_PRIVATE,
        pControl->fd,
        0);
    if ((void *) -1 == pControl->startAddress)
    {
        goto CLOSE_FILE;
    }

    goto EXIT;

CLOSE_FILE:
    close(pControl->fd);

FREE_MEMORY:
    free(pControl);
    pControl = INVALID_MEMMAP_HANDLE;

EXIT:
    return (MEMMAP_HANDLE) pControl;
}

/******************************************************************************
 * Name: GetFileMappingStartAddress
 *
 * Description:
 *   Returns the starting address for the file mapping.
 ******************************************************************************/
void* GetFileMappingStartAddress(
    MEMMAP_HANDLE   handle
    )
{
    return ((MEMMAP_CONTROL *) handle)->startAddress;
}

/******************************************************************************
 * Name: GetFileMappingSize
 *
 * Description:
 *   Returns the size, in bytes, for the file mapping.
 ******************************************************************************/
INT32U GetFileMappingSize(
    MEMMAP_HANDLE   handle
    )
{
    return ((MEMMAP_CONTROL *) handle)->size;
}

/******************************************************************************
 * Name: UnmapFileFromMemory
 *
 * Description:
 *   Unmaps a file from memory.
 ******************************************************************************/
void UnmapFileFromMemory(
    MEMMAP_HANDLE   handle
    )
{
    MEMMAP_CONTROL* pControl = (MEMMAP_CONTROL *) handle;

    /* Unmap the file and close all handles                                   */
    
    close(pControl->fd);
}
