/** * Gets all overflow extents that match the given key. * * @param key the key to match. * @param nodeNumber the current node to read from. * @return the overflow extents. * @throws IOException if an error occurs. */ public final ExtentDescriptor[] getOverflowExtents(final ExtentKey key, long nodeNumber) throws IOException { try { long currentNodeNumber = nodeNumber; int nodeSize = bthr.getNodeSize(); ByteBuffer nodeData = ByteBuffer.allocate(nodeSize); extentFile.read(fs, (currentNodeNumber * nodeSize), nodeData); byte[] data = nodeData.array(); NodeDescriptor nd = new NodeDescriptor(data, 0); if (nd.isIndexNode()) { ExtentNode extentNode = new ExtentNode(data, nodeSize); IndexRecord[] records = extentNode.findAll(key); List<ExtentDescriptor> overflowExtents = new LinkedList<ExtentDescriptor>(); for (IndexRecord record : records) { Collections.addAll(overflowExtents, getOverflowExtents(key, record.getIndex())); } return overflowExtents.toArray(new ExtentDescriptor[overflowExtents.size()]); } else if (nd.isLeafNode()) { ExtentLeafNode node = new ExtentLeafNode(nodeData.array(), nodeSize); return node.getOverflowExtents(key); } else { log.info( String.format( "Node %d wasn't a leaf or index: %s\n%s", nodeNumber, nd, NumberUtils.hex(data))); return new ExtentDescriptor[0]; } } catch (Exception e) { e.printStackTrace(); throw new IOException(e); } }
public Extent(HfsPlusFileSystem fs) throws IOException { log.debug("Load B-Tree extent overflow file."); this.fs = fs; SuperBlock sb = fs.getVolumeHeader(); extentFile = sb.getExtentsFile(); if (!extentFile.getExtent(0).isEmpty()) { buffer = ByteBuffer.allocate( NodeDescriptor.BT_NODE_DESCRIPTOR_LENGTH + BTHeaderRecord.BT_HEADER_RECORD_LENGTH); extentFile.read(fs, 0, buffer); buffer.rewind(); byte[] data = ByteBufferUtils.toArray(buffer); log.debug("Load extent node descriptor."); btnd = new NodeDescriptor(data, 0); log.debug(btnd.toString()); log.debug("Load extent header record."); bthr = new BTHeaderRecord(data, NodeDescriptor.BT_NODE_DESCRIPTOR_LENGTH); log.debug(bthr.toString()); } }