/* * 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); } } }