public List <hfsPlusForkData.HFSPlusExtentRecord> getSelf(uint totalBlocks, uint knownBlocks) { // get any additional extents not defined in the volume header of the extents overflow file List <hfsPlusForkData.HFSPlusExtentRecord> result = new List <hfsPlusForkData.HFSPlusExtentRecord>(); uint getNode = this.header.headerInfo.firstLeafNode; byte[] nodeRawData = new byte[this.nodeSize]; fs.Seek(this.nodeSize * getNode, SeekOrigin.Begin); fs.Read(nodeRawData, 0, this.nodeSize); HFSPlusExtentKey theKey = new HFSPlusExtentKey(); theKey.fileID = 3; theKey.startBlock = knownBlocks; theKey.type = forkType.data; // do this until all of the extents have been found while (knownBlocks < totalBlocks) { extentsOverflowLeafNode leaf = new extentsOverflowLeafNode(ref nodeRawData); foreach (extentsOverflowLeafNode.extentsOverflowLeafRecord record in leaf.records) { dataOperations.keyCompareResult correctRecord = extentsOverflowKeyCompare(record.key, theKey); if (correctRecord == dataOperations.keyCompareResult.equalsTrialKey) { // add all of the extents that contain any blocks foreach (hfsPlusForkData.HFSPlusExtentRecord extent in record.extents) { if (extent.blockCount > 0) { result.Add(extent); knownBlocks += extent.blockCount; } } } } // prepare the next node's data in case extents go into following node getNode = leaf.BTNodeDescriptor.fLink; fs.Seek(this.nodeSize * getNode, SeekOrigin.Begin); fs.Read(nodeRawData, 0, this.nodeSize); } return(result); }
public dataOperations.keyCompareResult catalogKeyCompare(HFSPlusCatalogKey trialKey, HFSPlusCatalogKey searchKey, bool caseSensitive) { // catalog keys are compared by parent ID first - therefore all children // of a given directory will be grouped together. This is followed by a // comparison of the nodename, which is case-sensitive on some volumes if (searchKey.parentID > trialKey.parentID) { return(dataOperations.keyCompareResult.greaterThanTrialKey); } else if (searchKey.parentID < trialKey.parentID) { return(dataOperations.keyCompareResult.lessThanTrialKey); } else { if (searchKey.nodeName == null) { return(dataOperations.keyCompareResult.greaterThanTrialKey); } else if (caseSensitive) { dataOperations.keyCompareResult result = dataOperations.keyCompareResult.equalsTrialKey; for (int i = 0; i < searchKey.nodeName.Length; i++) { if (searchKey.nodeName[i] > trialKey.nodeName[i]) { result = dataOperations.keyCompareResult.greaterThanTrialKey; break; } else if (searchKey.nodeName[i] < trialKey.nodeName[i]) { result = dataOperations.keyCompareResult.lessThanTrialKey; break; } } return(result); } else { return((dataOperations.keyCompareResult) string.CompareOrdinal(Encoding.Unicode.GetString(searchKey.nodeName), Encoding.Unicode.GetString(trialKey.nodeName))); } } }
public dataOperations.keyCompareResult attrKeyCompare(HFSPlusAttrKey trialKey, HFSPlusAttrKey searchKey, bool caseSensitive) { if (searchKey.fileID > trialKey.fileID) { return(dataOperations.keyCompareResult.greaterThanTrialKey); } else if (searchKey.fileID < trialKey.fileID) { return(dataOperations.keyCompareResult.lessThanTrialKey); } else { dataOperations.keyCompareResult result = dataOperations.keyCompareResult.equalsTrialKey; if (searchKey.attrName == null) { // this will match all keys relating to a given fileID return(dataOperations.keyCompareResult.equalsTrialKey); } else if (caseSensitive) { // case sensitive names are compared on a per-byte basis for (int i = 0; i < searchKey.attrName.Length; i++) { if (searchKey.attrName[i] > trialKey.attrName[i]) { result = dataOperations.keyCompareResult.greaterThanTrialKey; break; } else if (searchKey.attrName[i] < trialKey.attrName[i]) { result = dataOperations.keyCompareResult.lessThanTrialKey; break; } } return(result); } else { int num = string.CompareOrdinal(Encoding.Unicode.GetString(searchKey.attrName), Encoding.Unicode.GetString(trialKey.attrName)); switch ((dataOperations.keyCompareResult)num) { case dataOperations.keyCompareResult.equalsTrialKey: // if it is for the same attribute, the startblock is the final determinant if (searchKey.startBlock > trialKey.startBlock) { result = dataOperations.keyCompareResult.greaterThanTrialKey; } else if (searchKey.startBlock < trialKey.startBlock) { result = dataOperations.keyCompareResult.lessThanTrialKey; } else { result = dataOperations.keyCompareResult.equalsTrialKey; } break; case dataOperations.keyCompareResult.greaterThanTrialKey: result = dataOperations.keyCompareResult.greaterThanTrialKey; break; case dataOperations.keyCompareResult.lessThanTrialKey: result = dataOperations.keyCompareResult.lessThanTrialKey; break; } return(result); } } }