/*
* $Id$
*
* Copyright (C) 2003-2015 JNode.org
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This library 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 Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; If not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
package org.jnode.fs.exfat;
import java.io.IOException;
/**
* @author Matthias Treydte <waldheinz at gmail.com>
*/
public final class Node {
public static final int ATTRIB_RO = 0x01;
public static final int ATTRIB_HIDDEN = 0x02;
public static final int ATTRIB_SYSTEM = 0x04;
public static final int ATTRIB_VOLUME = 0x08;
public static final int ATTRIB_DIR = 0x10;
public static final int ATTRIB_ARCH = 0x20;
public static Node createRoot(ExFatSuperBlock sb)
throws IOException {
final Node result = new Node(sb, sb.getRootDirCluster(), null);
result.clusterCount = result.rootDirSize();
result.flags = ATTRIB_DIR;
return result;
}
public static Node create(
ExFatSuperBlock sb, long startCluster, int flags,
String name, boolean isContiguous, long size, EntryTimes times, boolean deleted) {
final Node result = new Node(sb, startCluster, times);
result.name = name;
result.isContiguous = isContiguous;
result.size = size;
result.flags = flags;
result.deleted = deleted;
return result;
}
private final ExFatSuperBlock sb;
private final DeviceAccess da;
private final long startCluster;
private final EntryTimes times;
private boolean isContiguous;
private long clusterCount;
private int flags;
private String name;
private long size;
private boolean deleted;
private Node(ExFatSuperBlock sb, long startCluster, EntryTimes times) {
this.sb = sb;
this.da = sb.getDeviceAccess();
this.startCluster = startCluster;
this.times = times;
}
/**
* Gets the flags for this node.
*
* @return the flags.
*/
public int getFlags() {
return flags;
}
/**
* Returns whether this node is contiguous.
*
* @return {@code true} if contiguous.
*/
public boolean isContiguous() {
return isContiguous;
}
public boolean isDirectory() {
return ((this.flags & ATTRIB_DIR) != 0);
}
public EntryTimes getTimes() {
return times;
}
public ExFatSuperBlock getSuperBlock() {
return sb;
}
public long getClusterCount() {
return clusterCount;
}
public long getStartCluster() {
return startCluster;
}
public String getName() {
return name;
}
public long getSize() {
return size;
}
public boolean isDeleted() {
return deleted;
}
/**
* Determines the size of the root directory in clusters.
*
* @return the number of clusters for the root directoy
* @throws IOException on read error
*/
private long rootDirSize() throws IOException {
long result = 0;
long current = this.sb.getRootDirCluster();
while (!Cluster.invalid(current)) {
result++;
current = nextCluster(current);
}
return result;
}
public long nextCluster(long cluster) throws IOException {
Cluster.checkValid(cluster);
if (this.isContiguous) {
return cluster + 1;
} else {
final long fatOffset =
sb.blockToOffset(this.sb.getFatBlockStart()) +
cluster * Cluster.SIZE;
return this.da.getUint32(fatOffset);
}
}
@Override
public String toString() {
final StringBuilder result = new StringBuilder();
result.append(Node.class.getName());
result.append(" [name=");
result.append(this.name);
result.append(", contiguous=");
result.append(this.isContiguous);
result.append("]");
return result.toString();
}
}