func __read()

in Sources/SwiftDocC/Indexing/Navigator/NavigatorTree.swift [137:188]


        func __read() {
            let deadline = DispatchTime.now() + timeout
            var processedNodes = [NavigatorTree.Node]()
            
            while readingCursor.cursor < readingCursor.data.count {
                let length = MemoryLayout<UInt32>.stride
                
                let parentID: UInt32 = unpackedValueFromData(data[readingCursor.cursor..<readingCursor.cursor + length])
                readingCursor.cursor += length
                
                let objectLength: UInt32 = unpackedValueFromData(data[readingCursor.cursor..<readingCursor.cursor + length])
                readingCursor.cursor += length
                
                // Not copying the data would EXC_BAD_ACCESS due to a problem in Swift 4.
                let objectData = data.subdata(in: readingCursor.cursor..<readingCursor.cursor + Int(objectLength))
                readingCursor.cursor += Int(objectLength)
                
                guard let item = NavigatorItem(rawValue: objectData) else {
                    broadcast?(processedNodes, false, Error.invalidData)
                    self.readingCursor = nil
                    break
                }
                
                let node = Node(item: item, bundleIdentifier: bundleIdentifier ?? "")
                node.id = UInt32(readingCursor.index)
                node.presentationIdentifier = presentationIdentifier
                
                let parent = self.numericIdentifierToNode[parentID]
                parent?.add(child: node)
                
                self.numericIdentifierToNode[readingCursor.index] = node
                processedNodes.append(node)
                readingCursor.index += 1
                
                if DispatchTime.now() > deadline {
                    queue.async(flags: .barrier) {
                        broadcast?(processedNodes, false, nil)
                    }
                    queue.asyncAfter(deadline: .now() + delay) {
                        __read()
                    }
                    break
                }
            }
            
            if readingCursor.cursor >= data.count {
                queue.async(flags: .barrier) {
                    broadcast?(processedNodes, true, nil)
                }
                self.readingCursor = nil
            }
        }