/// <summary> /// Initializes a new instance of the <see cref="HierarchicalPath"/> class. /// </summary> /// <param name="path">The path.</param> /// <param name="options">The options.</param> public HierarchicalPath( string path, HierarchicalPathOptions options) { // Create the path components ParsePath(path, null, options); }
/// <summary> /// This parses the given path and sets the internal variables to /// represent the given path. /// </summary> /// <param name="path">The path.</param> /// <param name="context">The context.</param> /// <param name="options">The options.</param> private void ParsePath( string path, HierarchicalPath context, HierarchicalPathOptions options) { // Perform some sanity checking on the path if (String.IsNullOrEmpty(path)) { throw new ArgumentNullException("path"); } // Check for simple paths that are only a / (absolute root) or // . (relative root). if (path.Length == 1) { if (path == "/") { // We can short-cut the processing of this path since there // is only one element. isRelative = false; levels = new string[] { }; return; } if (path == ".") { // This is a relative path that has no other elements inside // it. We can short-cut the parsing and finish up here. if (context != null) { isRelative = context.IsRelative; levels = context.levels; } else { isRelative = true; levels = new string[] { }; } return; } } // We don't have a simple root path. Check to see if the path starts // with a forward slash. If it does, it is an absolute path, otherwise // it will be relative. var parsedLevels = new List <string>(); int index = 0; if (path.StartsWith("/")) { // This is an absolute root path. isRelative = false; index++; } else { // This is a relative path, so prepend the context, if we have // one to our parsed levels. if (context != null) { // Copy the contents of the context. isRelative = context.IsRelative; parsedLevels.AddRange(context.Levels); } else { // This is a relative path. isRelative = true; } } // Go through the remaining elements of the string and break them // into the individual levels. var currentLevel = new StringBuilder(); for (; index < path.Length; index++) { // Check for the next character. switch (path[index]) { case '\\': // Check to see if the escape character is the last // character in the input string. if (index == path.Length - 1) { // We have an escape backslash but we are at the end of // the line. throw new InvalidPathException( "Cannot parse with escape at end of line: " + path); } // Grab the next character after the backslash. currentLevel.Append(path[index + 1]); index++; break; case '/': AppendLevel(parsedLevels, currentLevel.ToString()); currentLevel.Length = 0; break; default: // Add the character to the current level. currentLevel.Append(path[index]); break; } } // Outside of the loop, we check to see if there is anything left // in the current level and add it to the list. AppendLevel(parsedLevels, currentLevel.ToString()); // Saved the parsed levels into the levels property. levels = parsedLevels.ToArray(); // If we are interning, then intern all the strings. if ((options & HierarchicalPathOptions.InternStrings) == HierarchicalPathOptions.InternStrings) { for (int i = 0; i < levels.Length; i++) { levels[i] = String.Intern(levels[i]); } } }