/*
* Copyright (C) 2007 Steve Ratcliffe
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*
* Author: Steve Ratcliffe
* Create date: Dec 14, 2007
*/
package uk.me.parabola.imgfmt.sys;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import uk.me.parabola.imgfmt.ReadFailedException;
import uk.me.parabola.imgfmt.fs.ImgChannel;
/**
* This is an implementation of ImgChannel that delegates to a regular channel.
* It can therefore be used to read or write regular files on the file system.
*
* @author Steve Ratcliffe
*/
public class FileImgChannel implements ImgChannel {
private final FileChannel channel;
private long position;
public FileImgChannel(String filename, String mode) {
RandomAccessFile raf;
try {
raf = new RandomAccessFile(filename, mode);
} catch (FileNotFoundException e) {
throw new ReadFailedException("Could not open " + filename, e);
}
this.channel = raf.getChannel();
}
public FileImgChannel(FileChannel channel) {
this.channel = channel;
}
public int read(ByteBuffer dst) throws IOException {
int n = channel.read(dst);
if (n > 0)
position += n;
return n;
}
public boolean isOpen() {
return channel.isOpen();
}
public void close() throws IOException {
channel.close();
}
public int write(ByteBuffer src) throws IOException {
int n = channel.write(src);
position += n;
return n;
}
/**
* Get the file position. Note that this is a logical position relative to the
* beginning of the file (the file within the .img file, not the beginning of the
* .img file itself).
*
* @return The offset in bytes from the beginning of the file.
*/
public long position() {
return position;
}
/**
* Set the position within the file.
*
* @param pos The position to set.
*/
public void position(long pos) {
try {
channel.position(pos);
position = pos;
} catch (IOException e) {
throw new ReadFailedException("Could not seek", e);
}
}
}