Home | History | Annotate | Download | only in fat
      1 /*
      2  * Copyright (C) 2003-2009 JNode.org
      3  *               2009,2010 Matthias Treydte <mt (at) waldheinz.de>
      4  *
      5  * This library is free software; you can redistribute it and/or modify it
      6  * under the terms of the GNU Lesser General Public License as published
      7  * by the Free Software Foundation; either version 2.1 of the License, or
      8  * (at your option) any later version.
      9  *
     10  * This library is distributed in the hope that it will be useful, but
     11  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
     12  * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
     13  * License for more details.
     14  *
     15  * You should have received a copy of the GNU Lesser General Public License
     16  * along with this library; If not, write to the Free Software Foundation, Inc.,
     17  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
     18  */
     19 
     20 package de.waldheinz.fs.fat;
     21 
     22 /**
     23  * Enumerates the different entry sizes of 12, 16 and 32 bits for the different
     24  * FAT flavours.
     25  *
     26  * @author Ewout Prangsma &lt;epr at jnode.org&gt;
     27  * @author Matthias Treydte &lt;waldheinz at gmail.com&gt;
     28  */
     29 public enum FatType {
     30 
     31     /**
     32      * Represents a 12-bit file allocation table.
     33      */
     34     FAT12((1 << 12) - 16, 0xFFFL, 1.5f, "FAT12   ") { //NOI18N
     35 
     36         @Override
     37         long readEntry(byte[] data, int index) {
     38             final int idx = (int) (index * 1.5);
     39             final int b1 = data[idx] & 0xFF;
     40             final int b2 = data[idx + 1] & 0xFF;
     41             final int v = (b2 << 8) | b1;
     42 
     43             if ((index % 2) == 0) {
     44                 return v & 0xFFF;
     45             } else {
     46                 return v >> 4;
     47             }
     48         }
     49 
     50         @Override
     51         void writeEntry(byte[] data, int index, long entry) {
     52             final int idx = (int) (index * 1.5);
     53 
     54             if ((index % 2) == 0) {
     55                 data[idx] = (byte) (entry & 0xFF);
     56                 data[idx + 1] = (byte) ((entry >> 8) & 0x0F);
     57             } else {
     58                 data[idx] |= (byte) ((entry & 0x0F) << 4);
     59                 data[idx + 1] = (byte) ((entry >> 4) & 0xFF);
     60             }
     61         }
     62     },
     63 
     64     /**
     65      * Represents a 16-bit file allocation table.
     66      */
     67     FAT16((1 << 16) - 16, 0xFFFFL, 2.0f, "FAT16   ") { //NOI18N
     68 
     69         @Override
     70         long readEntry(byte[] data, int index) {
     71             final int idx = index << 1;
     72             final int b1 = data[idx] & 0xFF;
     73             final int b2 = data[idx + 1] & 0xFF;
     74             return (b2 << 8) | b1;
     75         }
     76 
     77         @Override
     78         void writeEntry(byte[] data, int index, long entry) {
     79             final int idx = index << 1;
     80             data[idx] = (byte) (entry & 0xFF);
     81             data[idx + 1] = (byte) ((entry >> 8) & 0xFF);
     82         }
     83     },
     84 
     85     /**
     86      * Represents a 32-bit file allocation table.
     87      */
     88     FAT32((1 << 28) - 16, 0xFFFFFFFFL, 4.0f, "FAT32   ") { //NOI18N
     89 
     90         @Override
     91         long readEntry(byte[] data, int index) {
     92             final int idx = index * 4;
     93             final long l1 = data[idx] & 0xFF;
     94             final long l2 = data[idx + 1] & 0xFF;
     95             final long l3 = data[idx + 2] & 0xFF;
     96             final long l4 = data[idx + 3] & 0xFF;
     97             return (l4 << 24) | (l3 << 16) | (l2 << 8) | l1;
     98         }
     99 
    100         @Override
    101         void writeEntry(byte[] data, int index, long entry) {
    102             final int idx = index << 2;
    103             data[idx] = (byte) (entry & 0xFF);
    104             data[idx + 1] = (byte) ((entry >> 8) & 0xFF);
    105             data[idx + 2] = (byte) ((entry >> 16) & 0xFF);
    106             data[idx + 3] = (byte) ((entry >> 24) & 0xFF);
    107         }
    108     };
    109 
    110     private final long minReservedEntry;
    111     private final long maxReservedEntry;
    112     private final long eofCluster;
    113     private final long eofMarker;
    114     private final long bitMask;
    115     private final int maxClusters;
    116     private final String label;
    117     private final float entrySize;
    118 
    119     private FatType(int maxClusters,
    120             long bitMask, float entrySize, String label) {
    121 
    122         this.minReservedEntry = (0xFFFFFF0L & bitMask);
    123         this.maxReservedEntry = (0xFFFFFF6L & bitMask);
    124         this.eofCluster = (0xFFFFFF8L & bitMask);
    125         this.eofMarker = (0xFFFFFFFL & bitMask);
    126         this.entrySize = entrySize;
    127         this.label = label;
    128         this.maxClusters = maxClusters;
    129         this.bitMask = bitMask;
    130     }
    131 
    132     abstract long readEntry(byte[] data, int index);
    133 
    134     abstract void writeEntry(byte[] data, int index, long entry);
    135 
    136     /**
    137      * Returns the maximum number of clusters this file system can address.
    138      *
    139      * @return the maximum cluster count supported
    140      */
    141     long maxClusters() {
    142         return this.maxClusters;
    143     }
    144 
    145     /**
    146      * Returns the human-readable FAT name string as written to the
    147      * {@link com.meetwise.fs.BootSector}.
    148      *
    149      * @return the boot sector label for this FAT type
    150      */
    151     String getLabel() {
    152         return this.label;
    153     }
    154 
    155     boolean isReservedCluster(long entry) {
    156         return ((entry >= minReservedEntry) && (entry <= maxReservedEntry));
    157     }
    158 
    159     boolean isEofCluster(long entry) {
    160         return (entry >= eofCluster);
    161     }
    162 
    163     long getEofMarker() {
    164         return eofMarker;
    165     }
    166 
    167     float getEntrySize() {
    168         return entrySize;
    169     }
    170 
    171     long getBitMask() {
    172         return bitMask;
    173     }
    174 }
    175