/*
 *  Copyright 2013 Brian S O'Neill
 *
 *  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.
 */

package org.cojen.tupl.io;

import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;

import java.nio.ByteBuffer;
import java.nio.MappedByteBuffer;

import java.nio.channels.FileChannel;
import static java.nio.channels.FileChannel.MapMode.*;

/**
 * 
 *
 * @author Brian S O'Neill
 */
final class NioMapping extends Mapping {
    private final RandomAccessFile mRaf;
    private final FileChannel mChannel;
    private final MappedByteBuffer mBuffer;

    NioMapping(File file, boolean readOnly, long position, int size) throws IOException {
        mRaf = new RandomAccessFile(file, readOnly ? "r" : "rw");
        mChannel = mRaf.getChannel();
        mBuffer = mChannel.map(readOnly ? READ_ONLY : READ_WRITE, position, size);
    }

    @Override
    void read(int start, byte[] b, int off, int len) {
        ByteBuffer bb = mBuffer.slice();
        bb.position(start);
        bb.get(b, off, len);
    }

    @Override
    void read(int start, ByteBuffer b) {
        ByteBuffer bb = mBuffer.slice();
        bb.position(start);
        b.put(bb);
    }

    @Override
    void write(int start, byte[] b, int off, int len) {
        ByteBuffer bb = mBuffer.slice();
        bb.position(start);
        bb.put(b, off, len);
    }

    @Override
    void write(int start, ByteBuffer b) {
        ByteBuffer bb = mBuffer.slice();
        bb.position(start);
        bb.put(b);
    }

    @Override
    void sync(boolean metadata) throws IOException {
        mBuffer.force();
        mChannel.force(metadata);
    }

    @Override
    public void close() throws IOException {
        Utils.delete(mBuffer);
        mRaf.close();
    }
}

@@ -1444,34 +1444,35 @@
      ByteBuffer 
-bb
+src
  = mBuffer.slice
@@ -1475,34 +1475,35 @@
 lice();%0A        
-bb
+src
 .position(start)
@@ -1512,18 +1512,19 @@
         
-bb
+src
 .get(b, 
@@ -1583,33 +1583,35 @@
 art, ByteBuffer 
-b
+dst
 ) %7B%0A        Byte
@@ -1609,34 +1609,35 @@
      ByteBuffer 
-bb
+src
  = mBuffer.slice
@@ -1640,34 +1640,79 @@
 lice();%0A        
-bb
+src.limit(start + dst.remaining());%0A        src
 .position(start)
@@ -1725,16 +1725,19 @@
     
-b
+dst
 .put(
-bb
+src
 );%0A 
@@ -1823,34 +1823,35 @@
      ByteBuffer 
-bb
+dst
  = mBuffer.slice
@@ -1854,34 +1854,35 @@
 lice();%0A        
-bb
+dst
 .position(start)
@@ -1887,26 +1887,27 @@
 t);%0A        
-bb
+dst
 .put(b, off,
@@ -1971,17 +1971,19 @@
 eBuffer 
-b
+src
 ) %7B%0A    
@@ -1997,18 +1997,19 @@
 eBuffer 
-bb
+dst
  = mBuff
@@ -2028,18 +2028,19 @@
         
-bb
+dst
 .positio
@@ -2061,16 +2061,19 @@
     
-bb
+dst
 .put(
-b
+src
 );%0A 

Fix mapping support.