| File: FrameworkFork\Microsoft.Xml\Xml\Core\ReadOnlyTernaryTree.cs | Web Access |
| Project: src\src\dotnet-svcutil\lib\src\dotnet-svcutil-lib.csproj (dotnet-svcutil-lib) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. using System; using System.IO; using System.Diagnostics; namespace Microsoft.Xml { using System; // Array index to indicate the meaning of the each byte. internal enum TernaryTreeByte { characterByte = 0, leftTree = 1, rightTree = 2, data = 3 }; // // XSL HTML output method properties // // Keep the first four bits in sync, so that the element and attribute mask operation can be combined. internal enum ElementProperties : uint { DEFAULT = 0, URI_PARENT = 1, BOOL_PARENT = 2, NAME_PARENT = 4, EMPTY = 8, NO_ENTITIES = 16, HEAD = 32, BLOCK_WS = 64, HAS_NS = 128 } internal enum AttributeProperties : uint { DEFAULT = 0, URI = 1, BOOLEAN = 2, NAME = 4 } /** * TernaryTreeRO * ------------- * * Ternary tree implementation used to make fast dictionary lookups in pre-generated * ternary trees. * * Note: Only strings composed of ASCII characters can exist in the tree. */ /// <include file='doc\ReadOnlyTernaryTree.uex' path='docs/doc[@for="TernaryTreeReadOnly"]/*' /> internal class TernaryTreeReadOnly { private byte[] _nodeBuffer; //define the array positions /// <include file='doc\ReadOnlyTernaryTree.uex' path='docs/doc[@for="TernaryTreeReadOnly.TernaryTreeReadOnly"]/*' /> public TernaryTreeReadOnly(byte[] nodeBuffer) { _nodeBuffer = nodeBuffer; } /* ---------------------------------------------------------------------------- findStringI() Find a Unicode string in the ternary tree and return the data byte it's mapped to. Find is case-insensitive. */ /// <include file='doc\ReadOnlyTernaryTree.uex' path='docs/doc[@for="TernaryTreeReadOnly.FindCaseInsensitiveString"]/*' /> public byte FindCaseInsensitiveString(String stringToFind) { //Debug.Assert(wszFind != null && wszFind.Length != 0); int stringPos = 0, nodePos = 0; int charToFind, charInTheTree; byte[] node = _nodeBuffer; charToFind = stringToFind[stringPos]; if (charToFind > 'z') return 0; // Ternary tree only stores ASCII strings if (charToFind >= 'a') charToFind -= ('a' - 'A'); // Normalize to upper case while (true) { int pos = nodePos * 4; charInTheTree = node[pos + (int)TernaryTreeByte.characterByte]; //Console.WriteLine("charToFind: {0},charInTheTree: {1}, nodePos: {2}", charToFind, charInTheTree, nodePos); if (charToFind < charInTheTree) { // If input character is less than the tree character, take the left branch if (node[pos + (int)TernaryTreeByte.leftTree] == 0x0) { break; } nodePos = nodePos + node[pos + (int)TernaryTreeByte.leftTree]; } else if (charToFind > charInTheTree) { // If input character is greater than the tree character, take the right branch if (node[pos + (int)TernaryTreeByte.rightTree] == 0x0) break; nodePos = nodePos + node[pos + (int)TernaryTreeByte.rightTree]; } else { // If input character is equal to the tree character, take the equal branch if (charToFind == 0) return node[pos + (int)TernaryTreeByte.data]; // The offset for the equal branch is always one ++nodePos; // Move to the next input character ++stringPos; if (stringPos == stringToFind.Length) { charToFind = 0; } else { charToFind = stringToFind[stringPos]; if (charToFind > 'z') return 0; // Ternary tree only stores ASCII strings if (charToFind >= 'a') charToFind -= ('a' - 'A'); // Normalize to upper case } } } // Return default return 0; } } }