Home | History | Annotate | Download | only in fat
      1 /*
      2  * Copyright (C) 2009,2010 Matthias Treydte <mt (at) waldheinz.de>
      3  *
      4  * This library is free software; you can redistribute it and/or modify it
      5  * under the terms of the GNU Lesser General Public License as published
      6  * by the Free Software Foundation; either version 2.1 of the License, or
      7  * (at your option) any later version.
      8  *
      9  * This library is distributed in the hope that it will be useful, but
     10  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
     11  * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
     12  * License for more details.
     13  *
     14  * You should have received a copy of the GNU Lesser General Public License
     15  * along with this library; If not, write to the Free Software Foundation, Inc.,
     16  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
     17  */
     18 
     19 package de.waldheinz.fs.fat;
     20 
     21 import de.waldheinz.fs.BlockDevice;
     22 import java.io.IOException;
     23 import java.nio.ByteBuffer;
     24 import java.nio.ByteOrder;
     25 
     26 /**
     27  *
     28  * @author Matthias Treydte &lt;waldheinz at gmail.com&gt;
     29  */
     30 class Sector {
     31     private final BlockDevice device;
     32     private final long offset;
     33 
     34     /**
     35      * The buffer holding the contents of this {@code Sector}.
     36      */
     37     protected final ByteBuffer buffer;
     38 
     39     private boolean dirty;
     40 
     41     protected Sector(BlockDevice device, long offset, int size) {
     42         this.offset = offset;
     43         this.device = device;
     44         this.buffer = ByteBuffer.allocate(size);
     45         this.buffer.order(ByteOrder.LITTLE_ENDIAN);
     46         this.dirty = true;
     47     }
     48 
     49     /**
     50      * Reads the contents of this {@code Sector} from the device into the
     51      * internal buffer and resets the "dirty" state.
     52      *
     53      * @throws IOException on read error
     54      * @see #isDirty()
     55      */
     56     protected void read() throws IOException {
     57         buffer.rewind();
     58         buffer.limit(buffer.capacity());
     59         device.read(offset, buffer);
     60         this.dirty = false;
     61     }
     62 
     63     public final boolean isDirty() {
     64         return this.dirty;
     65     }
     66 
     67     protected final void markDirty() {
     68         this.dirty = true;
     69     }
     70 
     71     /**
     72      * Returns the {@code BlockDevice} where this {@code Sector} is stored.
     73      *
     74      * @return this {@code Sector}'s device
     75      */
     76     public BlockDevice getDevice() {
     77         return this.device;
     78     }
     79 
     80     public final void write() throws IOException {
     81         if (!isDirty()) return;
     82 
     83         buffer.position(0);
     84         buffer.limit(buffer.capacity());
     85         device.write(offset, buffer);
     86         this.dirty = false;
     87     }
     88 
     89     protected int get16(int offset) {
     90         return buffer.getShort(offset) & 0xffff;
     91     }
     92 
     93     protected long get32(int offset) {
     94         return buffer.getInt(offset) & 0xffffffff;
     95     }
     96 
     97     protected int get8(int offset) {
     98         return buffer.get(offset) & 0xff;
     99     }
    100 
    101     protected void set16(int offset, int value) {
    102         buffer.putShort(offset, (short) (value & 0xffff));
    103         dirty = true;
    104     }
    105 
    106     protected void set32(int offset, long value) {
    107         buffer.putInt(offset, (int) (value & 0xffffffff));
    108         dirty = true;
    109     }
    110 
    111     protected void set8(int offset, int value) {
    112         if ((value & 0xff) != value) {
    113             throw new IllegalArgumentException(
    114                     value + " too big to be stored in a single octet");
    115         }
    116 
    117         buffer.put(offset, (byte) (value & 0xff));
    118         dirty = true;
    119     }
    120 
    121     /**
    122      * Returns the device offset to this {@code Sector}.
    123      *
    124      * @return the {@code Sector}'s device offset
    125      */
    126     protected long getOffset() {
    127         return this.offset;
    128     }
    129 }
    130