Subversion Repositories mkgmap

Rev

Rev 1870 | Blame | Compare with Previous | Last modification | View Log | RSS feed

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