package com.github.mjdev.libaums.driver.file;

import com.github.mjdev.libaums.driver.BlockDeviceDriver;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.net.URL;
import java.nio.ByteBuffer;
import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel;

/**
 * Created by magnusja on 01/08/17.
 */

public class FileBlockDeviceDriver implements BlockDeviceDriver {
    private RandomAccessFile file;
    private int blockSize;

    public FileBlockDeviceDriver(File file, int blockSize) throws FileNotFoundException {
        this.file = new RandomAccessFile(file, "rw");
        this.blockSize = blockSize;
    }

    public FileBlockDeviceDriver(File file) throws FileNotFoundException {
        this(file, 512);
    }

    public FileBlockDeviceDriver(URL url, int blockSize) throws IOException {
        ReadableByteChannel rbc = Channels.newChannel(url.openStream());
        File tempFile = File.createTempFile("blockdevice", "bin");
        FileOutputStream fos = new FileOutputStream(tempFile);
        fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);

        this.file = new RandomAccessFile(tempFile, "rw");
        this.blockSize = blockSize;
    }

    public FileBlockDeviceDriver(URL url) throws IOException {
        this(url, 512);
    }

    @Override
    public void init() throws IOException {

    }

    @Override
    public void read(long deviceOffset, ByteBuffer buffer) throws IOException {
        file.seek(deviceOffset * blockSize);
        file.read(buffer.array(), buffer.position(), buffer.limit());
        buffer.position(buffer.limit());
    }

    @Override
    public void write(long deviceOffset, ByteBuffer buffer) throws IOException {
        file.seek(deviceOffset * blockSize);
        file.write(buffer.array(), buffer.position(), buffer.limit());
        buffer.position(buffer.limit());
    }

    @Override
    public int getBlockSize() {
        return blockSize;
    }
}

@@ -555,16 +555,44 @@
 ockSize;
+%0A    private int byteOffset;
 %0A%0A    pu
@@ -634,32 +634,48 @@
 e, int blockSize
+, int byteOffset
 ) throws FileNot
@@ -773,32 +773,70 @@
 ze = blockSize;%0A
+        this.byteOffset = byteOffset;%0A
     %7D%0A%0A    publi
@@ -868,16 +868,32 @@
 ile file
+, int byteOffset
 ) throws
@@ -935,24 +935,146 @@
 is(file, 512
+, byteOffset);%0A    %7D%0A%0A    public FileBlockDeviceDriver(File file) throws FileNotFoundException %7B%0A        this(file, 512, 0
 );%0A    %7D%0A%0A  
@@ -1126,16 +1126,32 @@
 lockSize
+, int byteOffset
 ) throws
@@ -1157,32 +1157,70 @@
 s IOException %7B%0A
+        this.byteOffset = byteOffset;%0A
         Readable
@@ -1563,32 +1563,154 @@
 ockSize;%0A    %7D%0A%0A
+    public FileBlockDeviceDriver(URL url, int byteOffset) throws IOException %7B%0A        this(url, 512, byteOffset);%0A    %7D%0A%0A
     public FileB
@@ -1777,16 +1777,19 @@
 url, 512
+, 0
 );%0A    %7D
@@ -1984,32 +1984,45 @@
 fset * blockSize
+ + byteOffset
 );%0A        file.
@@ -2263,16 +2263,29 @@
 lockSize
+ + byteOffset
 );%0A     

Add byte offset