/* * $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.extent; import org.jnode.fs.hfsplus.catalog.CatalogNodeId; import org.jnode.fs.hfsplus.tree.AbstractKey; import org.jnode.fs.hfsplus.tree.Key; import org.jnode.util.BigEndian; public class ExtentKey extends AbstractKey { public static final byte DATA_FORK = (byte) 0x00; public static final byte RESOURCE_FORK = (byte) 0xFF; public static final int KEY_LENGTH = 12; public static final int MAXIMUM_KEY_LENGTH = 10; private int forkType; private int pad; private CatalogNodeId fileId; private long startBlock; /** * @param src * @param offset */ public ExtentKey(final byte[] src, final int offset) { byte[] ek = new byte[KEY_LENGTH]; System.arraycopy(src, offset, ek, 0, KEY_LENGTH); //TODO Understand why the +2 is necessary keyLength = BigEndian.getUInt16(ek, 0) + 2; forkType = BigEndian.getUInt8(ek, 2); pad = BigEndian.getUInt8(ek, 3); fileId = new CatalogNodeId(ek, 4); startBlock = BigEndian.getUInt32(ek, 8); } /** * @param forkType * @param pad * @param fileId * @param startBlock */ public ExtentKey(int forkType, int pad, CatalogNodeId fileId, int startBlock) { super(); this.forkType = forkType; this.pad = pad; this.fileId = fileId; this.startBlock = startBlock; } @Override public final int compareTo(final Key key) { int res = -1; if (key instanceof ExtentKey) { ExtentKey compareKey = (ExtentKey) key; res = fileId.compareTo(compareKey.getFileId()); if (res == 0) { res = compareForkType(compareKey.getForkType()); if (res == 0) { return compareStartBlock(compareKey.getStartBlock()); } } } return res; } @Override public int hashCode() { return 73 ^ fileId.hashCode() * forkType + (int) startBlock; } @Override public boolean equals(Object obj) { if (!(obj instanceof ExtentKey)) { return false; } ExtentKey otherKey = (ExtentKey) obj; return fileId.getId() == otherKey.fileId.getId() && forkType == otherKey.forkType; } @Override public byte[] getBytes() { byte[] data = new byte[this.getKeyLength()]; return data; } private int compareForkType(int fork) { Integer currentForkType = Integer.valueOf(forkType); Integer forkType = Integer.valueOf(fork); return currentForkType.compareTo(forkType); } private int compareStartBlock(long block) { Long currentStartBlock = Long.valueOf(startBlock); Long startBlock = Long.valueOf(block); return currentStartBlock.compareTo(startBlock); } public int getForkType() { return forkType; } public int getPad() { return pad; } public CatalogNodeId getFileId() { return fileId; } public long getStartBlock() { return startBlock; } @Override public final String toString() { return String.format("[%s type:%s start:%d]", fileId, forkType == DATA_FORK ? "data" : "resource", startBlock); } }