/*
* $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.hfsplus.tree;
import org.jnode.util.BigEndian;
public class BTHeaderRecord {
public static final int KEY_COMPARE_TYPE_CASE_FOLDING = 0xCF;
/**
* B-Tree was not closed correctly and need check for consistency.
*/
public static final int BT_BAD_CLOSE_MASK = 0x00000001;
public static final int BT_BIG_KEYS_MASK = 0x00000002;
public static final int BT_VARIABLE_INDEX_KEYS_MASK = 0x00000004;
public static final int BT_TYPE_HFS = 0;
public static final int BT_TYPE_USER = 128;
public static final int BT_TYPE_RESERVED = 256;
public static final int BT_HEADER_RECORD_LENGTH = 106;
/**
* The depth of the current B-Tree.
*/
private int treeDepth;
/**
* The root node number
*/
private long rootNode;
/**
* The number of records contains in all leaf nodes.
*/
private long leafRecords;
/**
* The number of the first leaf node. This may be zero.
*/
private long firstLeafNode;
/**
* The number of the last leaf node. This may be zero.
*/
private long lastLeafNode;
/**
* The size in bytes of a node.
*/
private int nodeSize;
/**
* The maximum length of a key.
*/
private int maxKeyLength;
/**
* The total number of free or used nodes in the B-Tree.
*/
private long totalNodes;
/**
* The number of free node in the B-Tree.
*/
private long freeNodes;
/**
* Ignore for HFS+, clumpSize field from {@code HFSPlusForkData} used
* instead.
*/
private long clumpSize;
/**
* The type of the B-Tree.
*/
private int treeType;
/**
* Ignore in HFS+, should be threat as reserved.
*/
private int keyCompareType;
/**
* Various attributes of the B-Tree.
*/
private long attributes;
public BTHeaderRecord(int treeDepth, int rootNode, int leafRecords, int firstLeafNode,
int lastLeafNode, int nodeSize, int maxKeyLength, int totalNodes, int freeNodes,
int clumpsize, int treeType, int keyCompareType, int attributes) {
this.treeDepth = treeDepth;
this.rootNode = rootNode;
this.leafRecords = leafRecords;
this.firstLeafNode = firstLeafNode;
this.lastLeafNode = lastLeafNode;
this.nodeSize = nodeSize;
this.maxKeyLength = maxKeyLength;
this.totalNodes = totalNodes;
this.freeNodes = freeNodes;
this.clumpSize = clumpsize;
this.treeType = treeType;
this.keyCompareType = keyCompareType;
this.attributes = attributes;
}
public BTHeaderRecord(final byte[] src, int offset) {
byte[] data = new byte[BT_HEADER_RECORD_LENGTH];
System.arraycopy(src, offset, data, 0, BT_HEADER_RECORD_LENGTH);
treeDepth = BigEndian.getUInt16(data, 0);
rootNode = BigEndian.getUInt32(data, 2);
leafRecords = BigEndian.getUInt32(data, 6);
firstLeafNode = BigEndian.getUInt32(data, 10);
lastLeafNode = BigEndian.getUInt32(data, 14);
nodeSize = BigEndian.getUInt16(data, 18);
maxKeyLength = BigEndian.getUInt16(data, 20);
totalNodes = BigEndian.getUInt32(data, 22);
freeNodes = BigEndian.getUInt32(data, 26);
// UInt16 reserved1 - offset 30
clumpSize = BigEndian.getUInt32(data, 32);
treeType = BigEndian.getUInt8(data, 36);
keyCompareType = BigEndian.getUInt8(data, 37);
attributes = BigEndian.getUInt32(data, 38);
}
public byte[] getBytes() {
byte[] data = new byte[BT_HEADER_RECORD_LENGTH];
BigEndian.setInt16(data, 0, treeDepth);
BigEndian.setInt32(data, 2, (int) rootNode);
BigEndian.setInt32(data, 6, (int) leafRecords);
BigEndian.setInt32(data, 10, (int) firstLeafNode);
BigEndian.setInt32(data, 14, (int) lastLeafNode);
BigEndian.setInt16(data, 18, nodeSize);
BigEndian.setInt16(data, 20, maxKeyLength);
BigEndian.setInt32(data, 22, (int) totalNodes);
BigEndian.setInt32(data, 26, (int) freeNodes);
BigEndian.setInt32(data, 32, (int) clumpSize);
BigEndian.setInt8(data, 36, treeType);
BigEndian.setInt8(data, 37, keyCompareType);
BigEndian.setInt32(data, 38, (int) attributes);
return data;
}
public final String toString() {
return ("Root node: " + getRootNode() + "\n" + "First leaf: " + getFirstLeafNode() + "\n" +
"Last leaf: " + getLastLeafNode() + "\n" + "node size: " + getNodeSize() + "\n");
}
public int getTreeDepth() {
return treeDepth;
}
public long getRootNode() {
return rootNode;
}
public long getLeafRecords() {
return leafRecords;
}
public long getFirstLeafNode() {
return firstLeafNode;
}
public long getLastLeafNode() {
return lastLeafNode;
}
public int getNodeSize() {
return nodeSize;
}
public int getMaxKeyLength() {
return maxKeyLength;
}
public long getTotalNodes() {
return totalNodes;
}
public long getFreeNodes() {
return freeNodes;
}
public long getClumpSize() {
return clumpSize;
}
public int getTreeType() {
return treeType;
}
public int getKeyCompareType() {
return keyCompareType;
}
public long getAttributes() {
return attributes;
}
}