public Node CreateNodeAt(NodePath nodePath, AbsoluteNodePath currentPath) { if (LookupNodeNoSearch(nodePath, currentPath) != null) { throw new NodeAlreadyExistsException(); } // Find deepest existing node on the path NodePath ancestorNodePath = nodePath; Node ancestorNode; int stepsUp = 0; do { ancestorNodePath = ancestorNodePath.RemoveSegment(); stepsUp++; ancestorNode = LookupNodeNoSearch(ancestorNodePath, currentPath); } while (ancestorNode == null); // Create remaining names to get a node with the desired path Node newNode = null; string[] nameSegments = nodePath.NameSegments; for (int i = nameSegments.Length - stepsUp; i < nameSegments.Length; i++) { newNode = new Node((string)nameSegments[i], ancestorNode); ancestorNode = newNode; } return(newNode); }
/// <summary> /// Look up the node at a given absolute or relative node path. /// This may include "single segment name" paths which invoke the /// search strategy described in section 5.3 of the ACPI spec 3.0b. /// </summary> /// <param name="currentPath">Absolute path of the current path /// relative to which any relative node path will be determined.</param> /// <returns>The requested node, or null if the node is not found.</returns> public Node LookupNode(NodePath nodePath, AbsoluteNodePath currentPath) { if (nodePath.IsAbsolute) { return(LookupDescendantNode(rootNode, nodePath.NameSegments)); } else { Node startNode = LookupNode(currentPath); Debug.Assert(startNode != null, "LookupNode: Current path did not resolve"); if (nodePath.NumParentPrefixes > 0) { for (int i = 0; i < nodePath.NumParentPrefixes; i++) { startNode = startNode.ParentNode; if (startNode == null) { throw new ArgumentException("Relative path attempts to move above root"); } } return(LookupDescendantNode(startNode, nodePath.NameSegments)); } else { // The search rules apply - try successively larger scopes while (startNode != null) { Node result = LookupDescendantNode(startNode, nodePath.NameSegments); if (result != null) { return(result); } startNode = startNode.ParentNode; } return(null); } } }
/// <summary> /// A version of LookupNode that does not ever apply the search rules. /// </summary> private Node LookupNodeNoSearch(NodePath nodePath, AbsoluteNodePath currentPath) { if (nodePath.IsAbsolute) { return(LookupDescendantNode(rootNode, nodePath.NameSegments)); } else { Node startNode = LookupNode(currentPath); Debug.Assert(startNode != null, "LookupNode: Current path did not resolve"); for (int i = 0; i < nodePath.NumParentPrefixes; i++) { startNode = startNode.ParentNode; if (startNode == null) { throw new ArgumentException("Relative path attempts to move above root"); } } return(LookupDescendantNode(startNode, nodePath.NameSegments)); } }
/// <summary> /// Look up the node at a given absolute node path. /// </summary> /// <returns>The requested node, or null if the node is not found.</returns> public Node LookupNode(AbsoluteNodePath nodePath) { return(LookupDescendantNode(rootNode, nodePath.NameSegments)); }