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 25 /** 26 * The root directory of a FAT12/16 partition. 27 * 28 * @author Matthias Treydte <waldheinz at gmail.com> 29 */ 30 final class Fat16RootDirectory extends AbstractDirectory { 31 private final BlockDevice device; 32 private final long deviceOffset; 33 34 private Fat16RootDirectory(Fat16BootSector bs, boolean readOnly) { 35 super(bs.getRootDirEntryCount(), readOnly, true); 36 37 if (bs.getRootDirEntryCount() <= 0) throw new IllegalArgumentException( 38 "root directory size is " + bs.getRootDirEntryCount()); 39 40 this.deviceOffset = FatUtils.getRootDirOffset(bs); 41 this.device = bs.getDevice(); 42 } 43 44 /** 45 * Reads a {@code Fat16RootDirectory} as indicated by the specified 46 * {@code Fat16BootSector}. 47 * 48 * @param bs the boot sector that describes the root directory to read 49 * @param readOnly if the directory shold be created read-only 50 * @return the directory that was read 51 * @throws IOException on read error 52 */ 53 public static Fat16RootDirectory read( 54 Fat16BootSector bs, boolean readOnly) throws IOException { 55 56 final Fat16RootDirectory result = new Fat16RootDirectory(bs, readOnly); 57 result.read(); 58 return result; 59 } 60 61 /** 62 * Creates a new {@code Fat16RootDirectory} as indicated by the specified 63 * {@code Fat16BootSector}. The directory will always be created in 64 * read-write mode. 65 * 66 * @param bs the boot sector that describes the root directory to create 67 * @return the directory that was created 68 * @throws IOException on write error 69 */ 70 public static Fat16RootDirectory create( 71 Fat16BootSector bs) throws IOException { 72 73 final Fat16RootDirectory result = new Fat16RootDirectory(bs, false); 74 result.flush(); 75 return result; 76 } 77 78 @Override 79 protected void read(ByteBuffer data) throws IOException { 80 this.device.read(deviceOffset, data); 81 } 82 83 @Override 84 protected void write(ByteBuffer data) throws IOException { 85 this.device.write(deviceOffset, data); 86 } 87 88 /** 89 * By convention always returns 0, as the FAT12/16 root directory is not 90 * stored in a cluster chain. 91 * 92 * @return always 0 93 */ 94 @Override 95 protected long getStorageCluster() { 96 return 0; 97 } 98 99 /** 100 * As a FAT12/16 root directory can not change it's size, this method 101 * throws a {@code DirectoryFullException} if the requested size is 102 * larger than {@link #getCapacity()} and does nothing else. 103 * 104 * @param entryCount {@inheritDoc} 105 */ 106 @Override 107 protected void changeSize(int entryCount) throws DirectoryFullException { 108 if (getCapacity() < entryCount) { 109 throw new DirectoryFullException(getCapacity(), entryCount); 110 } 111 } 112 113 } 114