/*
 * Copyright (C) 2006 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

//
// Encapsulate a shared file mapping.
//
#ifndef __LIBS_FILE_MAP_H
#define __LIBS_FILE_MAP_H

#include <sys/types.h>

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

namespace android {

/*
 * This represents a memory-mapped file.  It might be the entire file or
 * only part of it.  This requires a little bookkeeping because the mapping
 * needs to be aligned on page boundaries, and in some cases we'd like to
 * have multiple references to the mapped area without creating additional
 * maps.
 *
 * This always uses MAP_SHARED.
 *
 * TODO: we should be able to create a new FileMap that is a subset of
 * an existing FileMap and shares the underlying mapped pages.  Requires
 * completing the refcounting stuff and possibly introducing the notion
 * of a FileMap hierarchy.
 */
class FileMap {
public:
    FileMap(void);

    /*
     * Create a new mapping on an open file.
     *
     * Closing the file descriptor does not unmap the pages, so we don't
     * claim ownership of the fd.
     *
     * Returns "false" on failure.
     */
    bool create(const char* origFileName, int fd,
                off_t offset, size_t length, bool readOnly);

    /*
     * Return the name of the file this map came from, if known.
     */
    const char* getFileName(void) const { return mFileName; }
    
    /*
     * Get a pointer to the piece of the file we requested.
     */
    void* getDataPtr(void) const { return mDataPtr; }

    /*
     * Get the length we requested.
     */
    size_t getDataLength(void) const { return mDataLength; }

    /*
     * Get the data offset used to create this map.
     */
    off_t getDataOffset(void) const { return mDataOffset; }

    /*
     * Get a "copy" of the object.
     */
    FileMap* acquire(void) { mRefCount++; return this; }

    /*
     * Call this when mapping is no longer needed.
     */
    void release(void) {
        if (--mRefCount <= 0)
            delete this;
    }

    /*
     * This maps directly to madvise() values, but allows us to avoid
     * including <sys/mman.h> everywhere.
     */
    enum MapAdvice {
        NORMAL, RANDOM, SEQUENTIAL, WILLNEED, DONTNEED
    };

    /*
     * Apply an madvise() call to the entire file.
     *
     * Returns 0 on success, -1 on failure.
     */
    int advise(MapAdvice advice);

protected:
    // don't delete objects; call release()
    ~FileMap(void);

private:
    // these are not implemented
    FileMap(const FileMap& src);
    const FileMap& operator=(const FileMap& src);

    int         mRefCount;      // reference count
    char*       mFileName;      // original file name, if known
    void*       mBasePtr;       // base of mmap area; page aligned
    size_t      mBaseLength;    // length, measured from "mBasePtr"
    off_t       mDataOffset;    // offset used when map was created
    void*       mDataPtr;       // start of requested data, offset from base
    size_t      mDataLength;    // length, measured from "mDataPtr"
#ifdef HAVE_WIN32_FILEMAP
    HANDLE      mFileHandle;    // Win32 file handle
    HANDLE      mFileMapping;   // Win32 file mapping handle
#endif

    static long mPageSize;
};

}; // namespace android

#endif // __LIBS_FILE_MAP_H
