/*=============================================================================
    Copyright (c) 2003 Giovanni Bajo
    Copyright (c) 2003 Martin Wille
    Copyright (c) 2003 Hartmut Kaiser
    http://spirit.sourceforge.net/

    Use, modification and distribution is subject to 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)
=============================================================================*/

#ifndef BOOST_SPIRIT_FILE_ITERATOR_IPP
#define BOOST_SPIRIT_FILE_ITERATOR_IPP

#ifdef BOOST_SPIRIT_FILEITERATOR_WINDOWS
#  include <windows.h>
#endif

#include <cstdio>
#include <boost/shared_ptr.hpp>

#ifdef BOOST_SPIRIT_FILEITERATOR_WINDOWS
#  include <boost/type_traits/remove_pointer.hpp>
#endif

#ifdef BOOST_SPIRIT_FILEITERATOR_POSIX
#  include <sys/types.h> // open, stat, mmap, munmap
#  include <sys/stat.h>  // stat
#  include <fcntl.h>     // open
#  include <unistd.h>    // stat, mmap, munmap
#  include <sys/mman.h>  // mmap, mmunmap
#endif

///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit {

BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN

///////////////////////////////////////////////////////////////////////////////
namespace fileiter_impl {

///////////////////////////////////////////////////////////////////////////////
//
//  std_file_iterator
//
//  Base class that implements iteration through a file using standard C
//  stream library (fopen and friends). This class and the following are
//  the base components on which the iterator is built (through the
//  iterator adaptor library).
//
//  The opened file stream (FILE) is held with a shared_ptr<>, whose
//  custom deleter invokes fcose(). This makes the syntax of the class
//  very easy, especially everything related to copying.
//
///////////////////////////////////////////////////////////////////////////////

template <typename CharT>
class std_file_iterator
{
public:
    typedef CharT value_type;

    std_file_iterator()
    {}

    explicit std_file_iterator(std::string fileName)
    {
        using namespace std;
        FILE* f = fopen(fileName.c_str(), "rb");

        // If the file was opened, store it into
        //  the smart pointer.
        if (f)
        {
            m_file.reset(f, fclose);
            m_pos = 0;
            m_eof = false;
            update_char();
        }
    }

    std_file_iterator(const std_file_iterator& iter)
    { *this = iter; }

    std_file_iterator& operator=(const std_file_iterator& iter)
    {
        m_file = iter.m_file;
        m_curChar = iter.m_curChar;
        m_eof = iter.m_eof;
        m_pos = iter.m_pos;

        return *this;
    }

    // Nasty bug in Comeau up to 4.3.0.1, we need explicit boolean context
    //  for shared_ptr to evaluate correctly
    operator bool() const
    { return m_file ? true : false; }

    bool operator==(const std_file_iterator& iter) const
    {
        return (m_file == iter.m_file) && (m_eof == iter.m_eof) &&
            (m_pos == iter.m_pos);
    }

    const CharT& get_cur_char(void) const
    {
        return m_curChar;
    }

    void prev_char(void)
    {
        m_pos -= sizeof(CharT);
        update_char();
    }

    void next_char(void)
    {
        m_pos += sizeof(CharT);
        update_char();
    }

    void seek_end(void)
    {
        using namespace std;
        fseek(m_file.get(), 0, SEEK_END);
        m_pos = ftell(m_file.get()) / sizeof(CharT);
        m_eof = true;
    }

    void advance(std::ptrdiff_t n)
    {
        m_pos += n * sizeof(CharT);
        update_char();
    }

    std::ptrdiff_t distance(const std_file_iterator& iter) const
    {
        return (std::ptrdiff_t)(m_pos - iter.m_pos) / sizeof(CharT);
    }

private:
    boost::shared_ptr<std::FILE> m_file;
    std::size_t m_pos;
    CharT m_curChar;
    bool m_eof;

    void update_char(void)
    {
        using namespace std;
        if ((std::size_t)ftell(m_file.get()) != m_pos)
            fseek(m_file.get(), m_pos, SEEK_SET);

        m_eof = (fread(&m_curChar, sizeof(CharT), 1, m_file.get()) < 1);
    }
};


///////////////////////////////////////////////////////////////////////////////
//
//  mmap_file_iterator
//
//  File iterator for memory mapped files, for now implemented on Windows and
//  POSIX  platforms. This class has the same interface of std_file_iterator,
//  and can be used in its place (in fact, it's the default for Windows and
//  POSIX).
//
///////////////////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////////////////////////
// mmap_file_iterator, Windows version
#ifdef BOOST_SPIRIT_FILEITERATOR_WINDOWS
template <typename CharT>
class mmap_file_iterator
{
public:
    typedef CharT value_type;

    mmap_file_iterator()
    {}

    explicit mmap_file_iterator(std::string fileName)
    {
        HANDLE hFile = ::CreateFileA(
            fileName.c_str(),
            GENERIC_READ,
            FILE_SHARE_READ,
            NULL,
            OPEN_EXISTING,
            FILE_FLAG_SEQUENTIAL_SCAN,
            NULL
        );

        if (hFile == INVALID_HANDLE_VALUE)
            return;

        // Store the size of the file, it's used to construct
        //  the end iterator
        m_filesize = ::GetFileSize(hFile, NULL);

        HANDLE hMap = ::CreateFileMapping(
            hFile,
            NULL,
            PAGE_READONLY,
            0, 0,
            NULL
        );

        if (hMap == NULL)
        {
            ::CloseHandle(hFile);
            return;
        }

        LPVOID pMem = ::MapViewOfFile(
            hMap,
            FILE_MAP_READ,
            0, 0, 0
        );

        if (pMem == NULL)
        {
            ::CloseHandle(hMap);
            ::CloseHandle(hFile);
            return;
        }

        // We hold both the file handle and the memory pointer.
        // We can close the hMap handle now because Windows holds internally
        //  a reference to it since there is a view mapped.
        ::CloseHandle(hMap);

        // It seems like we can close the file handle as well (because
        //  a reference is hold by the filemap object).
        ::CloseHandle(hFile);

        // Store the handles inside the shared_ptr (with the custom destructors)
        m_mem.reset(static_cast<CharT*>(pMem), ::UnmapViewOfFile);

        // Start of the file
        m_curChar = m_mem.get();
    }

    mmap_file_iterator(const mmap_file_iterator& iter)
    { *this = iter; }

    mmap_file_iterator& operator=(const mmap_file_iterator& iter)
    {
        m_curChar = iter.m_curChar;
        m_mem = iter.m_mem;
        m_filesize = iter.m_filesize;

        return *this;
    }

    // Nasty bug in Comeau up to 4.3.0.1, we need explicit boolean context
    //  for shared_ptr to evaluate correctly
    operator bool() const
    { return m_mem ? true : false; }

    bool operator==(const mmap_file_iterator& iter) const
    { return m_curChar == iter.m_curChar; }

    const CharT& get_cur_char(void) const
    { return *m_curChar; }

    void next_char(void)
    { m_curChar++; }

    void prev_char(void)
    { m_curChar--; }

    void advance(std::ptrdiff_t n)
    { m_curChar += n; }

    std::ptrdiff_t distance(const mmap_file_iterator& iter) const
    { return m_curChar - iter.m_curChar; }

    void seek_end(void)
    {
        m_curChar = m_mem.get() +
            (m_filesize / sizeof(CharT));
    }

private:
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
    typedef boost::remove_pointer<HANDLE>::type handle_t;
#else
    typedef void handle_t;
#endif

    boost::shared_ptr<CharT> m_mem;
    std::size_t m_filesize;
    CharT* m_curChar;
};

#endif // BOOST_SPIRIT_FILEITERATOR_WINDOWS

///////////////////////////////////////////////////////////////////////////////
// mmap_file_iterator, POSIX version
#ifdef BOOST_SPIRIT_FILEITERATOR_POSIX
template <typename CharT>
class mmap_file_iterator
{
private:
    struct mapping
    {
        mapping(void *p, off_t len)
            : data(p)
            , size(len)
        { }

        CharT const *begin() const
        {
            return static_cast<CharT *>(data);
        }

        CharT const *end() const
        {
            return static_cast<CharT *>(data) + size/sizeof(CharT);
        }

        ~mapping()
        {
            munmap(static_cast<char*>(data), size);
        }

    private:
        void *data;
        off_t size;
    };

public:
    typedef CharT value_type;

    mmap_file_iterator()
    {}

    explicit mmap_file_iterator(std::string file_name)
    {
        // open the file
       int fd = open(file_name.c_str(),
#ifdef O_NOCTTY
            O_NOCTTY | // if stdin was closed then opening a file
                       // would cause the file to become the controlling
                       // terminal if the filename refers to a tty. Setting
                       // O_NOCTTY inhibits this.
#endif
            O_RDONLY);

        if (fd == -1)
            return;

        // call fstat to find get information about the file just
        // opened (size and file type)
        struct stat stat_buf;
        if ((fstat(fd, &stat_buf) != 0) || !S_ISREG(stat_buf.st_mode))
        {   // if fstat returns an error or if the file isn't a
            // regular file we give up.
            close(fd);
            return;
        }

        // perform the actual mapping
        void *p = mmap(0, stat_buf.st_size, PROT_READ, MAP_SHARED, fd, 0);
        // it is safe to close() here. POSIX requires that the OS keeps a
        // second handle to the file while the file is mmapped.
        close(fd);

        if (p == MAP_FAILED)
            return;

        mapping *m = 0;
        try
        {
            m = new mapping(p, stat_buf.st_size);
        }
        catch(...)
        {
            munmap(static_cast<char*>(p), stat_buf.st_size);
            throw;
        }

        m_mem.reset(m);

        // Start of the file
        m_curChar = m_mem->begin();
    }

    mmap_file_iterator(const mmap_file_iterator& iter)
    { *this = iter; }

    mmap_file_iterator& operator=(const mmap_file_iterator& iter)
    {
        m_curChar = iter.m_curChar;
        m_mem = iter.m_mem;

        return *this;
    }

    // Nasty bug in Comeau up to 4.3.0.1, we need explicit boolean context
    //  for shared_ptr to evaluate correctly
    operator bool() const
    { return m_mem ? true : false; }

    bool operator==(const mmap_file_iterator& iter) const
    { return m_curChar == iter.m_curChar; }

    const CharT& get_cur_char(void) const
    { return *m_curChar; }

    void next_char(void)
    { m_curChar++; }

    void prev_char(void)
    { m_curChar--; }

    void advance(signed long n)
    { m_curChar += n; }

    long distance(const mmap_file_iterator& iter) const
    { return m_curChar - iter.m_curChar; }

    void seek_end(void)
    {
        m_curChar = m_mem->end();
    }

private:

    boost::shared_ptr<mapping> m_mem;
    CharT const* m_curChar;
};

#endif // BOOST_SPIRIT_FILEITERATOR_POSIX

///////////////////////////////////////////////////////////////////////////////
} /* namespace boost::spirit::fileiter_impl */

template <typename CharT, typename BaseIteratorT>
file_iterator<CharT,BaseIteratorT>
file_iterator<CharT,BaseIteratorT>::make_end(void)
{
    file_iterator iter(*this);
    iter.base_reference().seek_end();
    return iter;
}

template <typename CharT, typename BaseIteratorT>
file_iterator<CharT,BaseIteratorT>&
file_iterator<CharT,BaseIteratorT>::operator=(const base_t& iter)
{
    base_t::operator=(iter);
    return *this;
}

///////////////////////////////////////////////////////////////////////////////
BOOST_SPIRIT_CLASSIC_NAMESPACE_END

}} /* namespace boost::spirit */


#endif /* BOOST_SPIRIT_FILE_ITERATOR_IPP */
