in hfs/btree.c [755:837]
static int growBTree(BTree* tree) {
int i;
unsigned char* buffer;
uint16_t offset;
uint32_t byteNumber;
uint32_t mapNode;
int increasedNodes;
off_t newNodeOffset;
uint32_t newNodesStart;
BTNodeDescriptor* descriptor;
BTNodeDescriptor newDescriptor;
allocate((RawFile*)(tree->io->data), ((RawFile*)(tree->io->data))->forkData->logicalSize + ((RawFile*)(tree->io->data))->forkData->clumpSize);
increasedNodes = (((RawFile*)(tree->io->data))->forkData->logicalSize/tree->headerRec->nodeSize) - tree->headerRec->totalNodes;
newNodesStart = tree->headerRec->totalNodes / tree->headerRec->nodeSize;
tree->headerRec->freeNodes += increasedNodes;
tree->headerRec->totalNodes += increasedNodes;
byteNumber = tree->headerRec->totalNodes / 8;
mapNode = 0;
buffer = (unsigned char*) malloc(tree->headerRec->nodeSize - 20);
for(i = 0; i < (tree->headerRec->nodeSize - 20); i++) {
buffer[i] = 0;
}
if(byteNumber < (tree->headerRec->nodeSize - 256)) {
ASSERT(writeBTHeaderRec(tree), "writeBTHeaderREc");
free(buffer);
return TRUE;
} else {
byteNumber -= tree->headerRec->nodeSize - 256;
while(TRUE) {
descriptor = readBTNodeDescriptor(mapNode, tree);
if(descriptor->fLink == 0) {
descriptor->fLink = newNodesStart;
ASSERT(writeBTNodeDescriptor(descriptor, mapNode, tree), "writeBTNodeDescriptor");
newDescriptor.fLink = 0;
newDescriptor.bLink = 0;
newDescriptor.kind = kBTMapNode;
newDescriptor.height = 0;
newDescriptor.numRecords = 1;
newDescriptor.reserved = 0;
ASSERT(writeBTNodeDescriptor(&newDescriptor, descriptor->fLink, tree), "writeBTNodeDescriptor");
newNodeOffset = descriptor->fLink * tree->headerRec->nodeSize;
ASSERT(WRITE(tree->io, newNodeOffset + 14, tree->headerRec->nodeSize - 20, buffer), "WRITE");
offset = 14;
FLIPENDIAN(offset);
ASSERT(WRITE(tree->io, newNodeOffset + tree->headerRec->nodeSize - 2, sizeof(offset), &offset), "WRITE");
offset = 14 + tree->headerRec->nodeSize - 20;
FLIPENDIAN(offset);
ASSERT(WRITE(tree->io, newNodeOffset + tree->headerRec->nodeSize - 4, sizeof(offset), &offset), "WRITE");
// mark the map node as being used
ASSERT(markUsed(newNodesStart, tree), "markUsed");
tree->headerRec->freeNodes--;
newNodesStart++;
}
mapNode = descriptor->fLink;
if(byteNumber > (tree->headerRec->nodeSize - 20)) {
byteNumber -= tree->headerRec->nodeSize - 20;
} else {
free(buffer);
ASSERT(writeBTHeaderRec(tree), "writeBTHeaderRec");
return TRUE;
}
}
}
return FALSE;
}