private ContainerEntry FindContainerAtDepth(long position, int desiredDepth) { // Find the first container ending after position. ContainerEntry firstAfter = _containerIndex.FirstEndingAfter(position); int firstAfterDepth = _containerIndex.Depth(firstAfter); // Find the ancestor at the desired depth. If there is one, and it contains position, we can use it ContainerEntry firstAtDepth = AncestorAtDepth(firstAfter, firstAfterDepth, desiredDepth); if (firstAtDepth.Contains(position)) { return(firstAtDepth); } // If nothing deep enough was indexed, we must find the nearest point of known depth and walk the BION long seekToPosition; int seekToDepth; // The nearest point is... if (firstAfter.StartByteOffset < position) { // The start of the first container ending after position, if it starts before position seekToPosition = firstAfter.StartByteOffset; seekToDepth = firstAfterDepth - 1; } else if (firstAfter.Index > 0) { // The end of the container before that, if it started after position ContainerEntry lastBefore = _containerIndex[firstAfter.Index - 1]; seekToPosition = lastBefore.EndByteOffset; seekToDepth = _containerIndex.Depth(lastBefore) - 1; } else { // The start of the document, if the first container was found seekToPosition = 0; seekToDepth = 0; } // Seek to that position and read until we find a container at the right depth which contains position _bionReader.Seek(seekToPosition); long lastContainerStart = -1; long lastContainerEnd = -1; while (_bionReader.BytesRead < position + 3) { _bionReader.Read(); if (_bionReader.Depth + seekToDepth == desiredDepth) { lastContainerStart = _bionReader.BytesRead - 1; _bionReader.SkipRest(); lastContainerEnd = _bionReader.BytesRead; } } ContainerEntry found = new ContainerEntry(lastContainerStart, lastContainerEnd, -1); if (!found.Contains(position)) { return(ContainerEntry.Empty); } return(found); }