// (C) Copyright Craig Henderson 2002 'boost/memmap.hpp' from sandbox
// (C) Copyright Jonathan Turkanis 2004.
// (C) Copyright Jonathan Graehl 2004.
// (C) Copyright Jorge Lodos 2008.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt.)

// Define BOOST_IOSTREAMS_SOURCE so that <boost/iostreams/detail/config.hpp>
// knows that we are building the library (possibly exporting code), rather
// than using it (possibly importing code).
#define BOOST_IOSTREAMS_SOURCE

#include <cassert>
#include <boost/iostreams/detail/config/rtl.hpp>
#include <boost/iostreams/detail/config/windows_posix.hpp>
#include <boost/iostreams/detail/file_handle.hpp>
#include <boost/iostreams/detail/system_failure.hpp>
#include <boost/iostreams/device/mapped_file.hpp>
#include <boost/throw_exception.hpp>

#ifdef BOOST_IOSTREAMS_WINDOWS
# define WIN32_LEAN_AND_MEAN  // Exclude rarely-used stuff from Windows headers
# include <windows.h>
#else
# include <errno.h>
# include <fcntl.h>
# include <sys/mman.h>      // mmap, munmap.
# include <sys/stat.h>
# include <sys/types.h>     // struct stat.
# include <unistd.h>        // sysconf.
#endif

namespace boost { namespace iostreams {

namespace detail {

// Class containing the platform-sepecific implementation
// Invariant: The members params_, data_, size_, handle_ (and mapped_handle_ 
// on Windows) either
//    - all have default values (or INVALID_HANDLE_VALUE for
//      Windows handles), or
//    - all have values reflecting a successful mapping.
// In the first case, error_ may be true, reflecting a recent unsuccessful
// open or close attempt; in the second case, error_ is always false.
class mapped_file_impl {
public:
    typedef mapped_file_source::size_type   size_type;
    typedef mapped_file_source::param_type  param_type;
    typedef mapped_file_source::mapmode     mapmode;
    BOOST_STATIC_CONSTANT(
        size_type, max_length =  mapped_file_source::max_length);
    mapped_file_impl();
    ~mapped_file_impl();
    void open(param_type p);
    bool is_open() const { return data_ != 0; }
    void close();
    bool error() const { return error_; }
    mapmode flags() const { return params_.flags; }
    std::size_t size() const { return size_; }
    char* data() const { return data_; }
    void resize(stream_offset new_size);
    static int alignment();
private:
    void open_file(param_type p);
    void try_map_file(param_type p);
    void map_file(param_type& p);
    bool unmap_file();
    void clear(bool error);
    void cleanup_and_throw(const char* msg);
    param_type     params_;
    char*          data_;
    stream_offset  size_;
    file_handle    handle_;
#ifdef BOOST_IOSTREAMS_WINDOWS
    file_handle    mapped_handle_;
#endif
    bool           error_;
};

mapped_file_impl::mapped_file_impl() { clear(false); }

mapped_file_impl::~mapped_file_impl() 
{ try { close(); } catch (...) { } }

void mapped_file_impl::open(param_type p)
{
    if (is_open())
        boost::throw_exception(BOOST_IOSTREAMS_FAILURE("file already open"));
    p.normalize();
    open_file(p);
    map_file(p);  // May modify p.hint
    params_ = p;
}

void mapped_file_impl::close()
{
    if (data_ == 0)
        return;
    bool error = false;
    error = !unmap_file() || error;
    error = 
        #ifdef BOOST_IOSTREAMS_WINDOWS
            !::CloseHandle(handle_) 
        #else
            ::close(handle_) != 0 
        #endif
            || error;
    clear(error);
    if (error)
        throw_system_failure("failed closing mapped file");
}

void mapped_file_impl::resize(stream_offset new_size)
{
    if (!is_open())
        boost::throw_exception(BOOST_IOSTREAMS_FAILURE("file is closed"));
    if (flags() & mapped_file::priv)
        boost::throw_exception(
            BOOST_IOSTREAMS_FAILURE("can't resize private mapped file")
        );
    if (!(flags() & mapped_file::readwrite))
        boost::throw_exception(
            BOOST_IOSTREAMS_FAILURE("can't resize readonly mapped file")
        );
    if (params_.offset >= new_size)
        boost::throw_exception(
            BOOST_IOSTREAMS_FAILURE("can't resize below mapped offset")
        );
    if (!unmap_file())
        cleanup_and_throw("failed unmapping file");
#ifdef BOOST_IOSTREAMS_WINDOWS
    stream_offset offset = ::SetFilePointer(handle_, 0, NULL, FILE_CURRENT);
    if (offset == INVALID_SET_FILE_POINTER && ::GetLastError() != NO_ERROR)
         cleanup_and_throw("failed querying file pointer");
    LONG sizehigh = (new_size >> (sizeof(LONG) * 8));
    LONG sizelow = (new_size & 0xffffffff);
    DWORD result = ::SetFilePointer(handle_, sizelow, &sizehigh, FILE_BEGIN);
    if ((result == INVALID_SET_FILE_POINTER && ::GetLastError() != NO_ERROR)
        || !::SetEndOfFile(handle_))
        cleanup_and_throw("failed resizing mapped file");
    sizehigh = (offset >> (sizeof(LONG) * 8));
    sizelow = (offset & 0xffffffff);
    ::SetFilePointer(handle_, sizelow, &sizehigh, FILE_BEGIN);
#else
    if (BOOST_IOSTREAMS_FD_TRUNCATE(handle_, new_size) == -1)
        cleanup_and_throw("failed resizing mapped file");
#endif
    size_ = new_size;
    param_type p(params_);
    map_file(p);  // May modify p.hint
    params_ = p;
}

int mapped_file_impl::alignment()
{
#ifdef BOOST_IOSTREAMS_WINDOWS
    SYSTEM_INFO info;
    ::GetSystemInfo(&info);
    return static_cast<int>(info.dwAllocationGranularity);
#else
    return static_cast<int>(sysconf(_SC_PAGESIZE));
#endif
}

void mapped_file_impl::open_file(param_type p)
{
    bool readonly = p.flags != mapped_file::readwrite;
#ifdef BOOST_IOSTREAMS_WINDOWS

    // Open file
    DWORD dwDesiredAccess =
        readonly ?
            GENERIC_READ :
            (GENERIC_READ | GENERIC_WRITE);
    DWORD dwCreationDisposition = (p.new_file_size != 0 && !readonly) ? 
        CREATE_ALWAYS : 
        OPEN_EXISTING;
    DWORD dwFlagsandAttributes =
        readonly ?
            FILE_ATTRIBUTE_READONLY :
            FILE_ATTRIBUTE_TEMPORARY;
    handle_ = p.path.is_wide() ?
        ::CreateFileW( 
            p.path.c_wstr(),
            dwDesiredAccess,
            FILE_SHARE_READ,
            NULL,
            dwCreationDisposition,
            dwFlagsandAttributes,
            NULL ) :
        ::CreateFileA( 
            p.path.c_str(),
            dwDesiredAccess,
            FILE_SHARE_READ,
            NULL,
            dwCreationDisposition,
            dwFlagsandAttributes,
            NULL );
    if (handle_ == INVALID_HANDLE_VALUE)
        cleanup_and_throw("failed opening file");

    // Set file size
    if (p.new_file_size != 0 && !readonly) {
        LONG sizehigh = (p.new_file_size >> (sizeof(LONG) * 8));
        LONG sizelow = (p.new_file_size & 0xffffffff);
        DWORD result = ::SetFilePointer(handle_, sizelow, &sizehigh, FILE_BEGIN);
        if ((result == INVALID_SET_FILE_POINTER && ::GetLastError() != NO_ERROR)
            || !::SetEndOfFile(handle_))
            cleanup_and_throw("failed setting file size");
    }

    // Determine file size. Dynamically locate GetFileSizeEx for compatibility
    // with old Platform SDK (thanks to Pavel Vozenilik).
    typedef BOOL (WINAPI *func)(HANDLE, PLARGE_INTEGER);
    HMODULE hmod = ::GetModuleHandleA("kernel32.dll");
    func get_size =
        reinterpret_cast<func>(::GetProcAddress(hmod, "GetFileSizeEx"));
    if (get_size) {
        LARGE_INTEGER info;
        if (get_size(handle_, &info)) {
            boost::intmax_t size =
                ( (static_cast<boost::intmax_t>(info.HighPart) << 32) |
                  info.LowPart );
            size_ =
                static_cast<std::size_t>(
                    p.length != max_length ?
                        std::min<boost::intmax_t>(p.length, size) :
                        size
                );
        } else {
            cleanup_and_throw("failed querying file size");
            return;
        }
    } else {
        DWORD hi;
        DWORD low;
        if ( (low = ::GetFileSize(handle_, &hi))
                 !=
             INVALID_FILE_SIZE )
        {
            boost::intmax_t size =
                (static_cast<boost::intmax_t>(hi) << 32) | low;
            size_ =
                static_cast<std::size_t>(
                    p.length != max_length ?
                        std::min<boost::intmax_t>(p.length, size) :
                        size
                );
        } else {
            cleanup_and_throw("failed querying file size");
            return;
        }
    }
#else // #ifdef BOOST_IOSTREAMS_WINDOWS

    // Open file
    int flags = (readonly ? O_RDONLY : O_RDWR);
    if (p.new_file_size != 0 && !readonly)
        flags |= (O_CREAT | O_TRUNC);
    #ifdef _LARGEFILE64_SOURCE
        flags |= O_LARGEFILE;
    #endif
    errno = 0;
    handle_ = ::open(p.path.c_str(), flags, S_IRWXU);
    if (errno != 0)
        cleanup_and_throw("failed opening file");

    //--------------Set file size---------------------------------------------//

    if (p.new_file_size != 0 && !readonly)
        if (BOOST_IOSTREAMS_FD_TRUNCATE(handle_, p.new_file_size) == -1)
            cleanup_and_throw("failed setting file size");

    //--------------Determine file size---------------------------------------//

    bool success = true;
    if (p.length != max_length) {
        size_ = p.length;
    } else {
        struct BOOST_IOSTREAMS_FD_STAT info;
        success = ::BOOST_IOSTREAMS_FD_FSTAT(handle_, &info) != -1;
        size_ = info.st_size;
    }
    if (!success)
        cleanup_and_throw("failed querying file size");
#endif // #ifdef BOOST_IOSTREAMS_WINDOWS
}

void mapped_file_impl::try_map_file(param_type p)
{
    bool priv = p.flags == mapped_file::priv;
    bool readonly = p.flags == mapped_file::readonly;
#ifdef BOOST_IOSTREAMS_WINDOWS

    // Create mapping
    DWORD protect = priv ? 
        PAGE_WRITECOPY : 
        readonly ? 
            PAGE_READONLY : 
            PAGE_READWRITE;
    mapped_handle_ = 
        ::CreateFileMappingA( 
            handle_, 
            NULL,
            protect,
            0, 
            0, 
            NULL );
    if (mapped_handle_ == NULL)
        cleanup_and_throw("failed create mapping");

    // Access data
    DWORD access = priv ? 
        FILE_MAP_COPY : 
        readonly ? 
            FILE_MAP_READ : 
            FILE_MAP_WRITE;
    void* data =
        ::MapViewOfFileEx( 
            mapped_handle_,
            access,
            (DWORD) (p.offset >> 32),
            (DWORD) (p.offset & 0xffffffff),
            size_ != max_length ? size_ : 0, 
            (LPVOID) p.hint );
    if (!data)
        cleanup_and_throw("failed mapping view");
#else
    void* data = 
        ::BOOST_IOSTREAMS_FD_MMAP( 
            const_cast<char*>(p.hint), 
            size_,
            readonly ? PROT_READ : (PROT_READ | PROT_WRITE),
            priv ? MAP_PRIVATE : MAP_SHARED,
            handle_, 
            p.offset );
    if (data == MAP_FAILED)
        cleanup_and_throw("failed mapping file");
#endif
    data_ = static_cast<char*>(data);
}

void mapped_file_impl::map_file(param_type& p)
{
    try {
        try_map_file(p);
    } catch (const std::exception& e) {
        if (p.hint) {
            p.hint = 0;
            try_map_file(p);
        } else {
            boost::throw_exception(e);
        }
    }
}

bool mapped_file_impl::unmap_file()
{
#ifdef BOOST_IOSTREAMS_WINDOWS
    bool error = false;
    error = !::UnmapViewOfFile(data_) || error;
    error = !::CloseHandle(mapped_handle_) || error;
    mapped_handle_ = NULL;
    return !error;
#else
    return ::munmap(data_, size_) == 0;
#endif
}

void mapped_file_impl::clear(bool error)
{
    params_ = param_type();
    data_ = 0;
    size_ = 0;
#ifdef BOOST_IOSTREAMS_WINDOWS
    handle_ = INVALID_HANDLE_VALUE;
    mapped_handle_ = NULL;
#else
    handle_ = 0;
#endif
    error_ = error;
}

// Called when an error is encountered during the execution of open_file or
// map_file
void mapped_file_impl::cleanup_and_throw(const char* msg)
{
#ifdef BOOST_IOSTREAMS_WINDOWS
    DWORD error = GetLastError();
    if (mapped_handle_ != NULL)
        ::CloseHandle(mapped_handle_);
    if (handle_ != INVALID_HANDLE_VALUE)
        ::CloseHandle(handle_);
    SetLastError(error);
#else
    int error = errno;
    if (handle_ != 0)
        ::close(handle_);
    errno = error;
#endif
    clear(true);
    boost::iostreams::detail::throw_system_failure(msg);
}

//------------------Implementation of mapped_file_params_base-----------------//

void mapped_file_params_base::normalize()
{
    if (mode && flags)
        boost::throw_exception(BOOST_IOSTREAMS_FAILURE(
            "at most one of 'mode' and 'flags' may be specified"
        ));
    if (flags) {
        switch (flags) {
        case mapped_file::readonly:
        case mapped_file::readwrite:
        case mapped_file::priv:
            break;
        default:
            boost::throw_exception(BOOST_IOSTREAMS_FAILURE("invalid flags"));
        }
    } else {
        flags = (mode & BOOST_IOS::out) ? 
            mapped_file::readwrite :
            mapped_file::readonly;
        mode = BOOST_IOS::openmode();
    }
    if (offset < 0)
        boost::throw_exception(BOOST_IOSTREAMS_FAILURE("invalid offset"));
    if (new_file_size < 0)
        boost::throw_exception(
            BOOST_IOSTREAMS_FAILURE("invalid new file size")
        );
}

} // End namespace detail.

//------------------Implementation of mapped_file_source----------------------//

mapped_file_source::mapped_file_source() 
    : pimpl_(new impl_type)
    { }

mapped_file_source::mapped_file_source(const mapped_file_source& other)
    : pimpl_(other.pimpl_)
    { }

bool mapped_file_source::is_open() const
{ return pimpl_->is_open(); }

void mapped_file_source::close() { pimpl_->close(); }

// safe_bool is explicitly qualified below to please msvc 7.1
mapped_file_source::operator mapped_file_source::safe_bool() const
{ return pimpl_->error() ? &safe_bool_helper::x : 0; }

bool mapped_file_source::operator!() const
{ return pimpl_->error(); }

mapped_file_source::mapmode mapped_file_source::flags() const 
{ return pimpl_->flags(); }

mapped_file_source::size_type mapped_file_source::size() const
{ return pimpl_->size(); }

const char* mapped_file_source::data() const { return pimpl_->data(); }

const char* mapped_file_source::begin() const { return data(); }

const char* mapped_file_source::end() const { return data() + size(); }
int mapped_file_source::alignment()
{ return detail::mapped_file_impl::alignment(); }

void mapped_file_source::init() { pimpl_.reset(new impl_type); }

void mapped_file_source::open_impl(const param_type& p)
{ pimpl_->open(p); }

//------------------Implementation of mapped_file-----------------------------//

mapped_file::mapped_file(const mapped_file& other)
    : delegate_(other.delegate_)
    { }

void mapped_file::resize(stream_offset new_size)
{ delegate_.pimpl_->resize(new_size); }

//------------------Implementation of mapped_file_sink------------------------//

mapped_file_sink::mapped_file_sink(const mapped_file_sink& other)
    : mapped_file(static_cast<const mapped_file&>(other))
    { }

//----------------------------------------------------------------------------//

} } // End namespaces iostreams, boost.
