/// <summary> /// Constructor. /// </summary> /// <param name="parent">To be assigned to <see cref="Parent"/> property.</param> /// <param name="name">To be assigned to <see cref="Name"/> property.</param> /// <param name="value">To be assigned to <see cref="Value"/> property.</param> internal SingleValueNode([NotNull] ConfigurationNode parent, [NotNull] string name, [NotNull] string value) { if (string.IsNullOrEmpty(name)) { throw new ArgumentNullException($"{nameof(name)} is null or empty."); } Parent = parent; IndentLevel = parent is ConfigurationFile ? (ushort)0 : (ushort)(parent.IndentLevel + 1); Name = name; Value = value; }
/// <summary> /// Constructor used in cloning. /// </summary> /// <param name="parent">To be assigned to <see cref="Parent"/> property.</param> /// <param name="name">To be assigned to <see cref="Name"/> property.</param> /// <param name="children">Enumeration of child nodes. Nodes from this enumeration won't be added /// to the <see cref="Children"/> list of the newly created instance, but their clones.</param> /// <param name="isArray">Indicates if this instance represents an array.</param> protected ConfigurationNode(ConfigurationNode parent, [NotNull] string name, IEnumerable <IConfigNode> children, bool isArray) { Parent = parent; IndentLevel = parent == null || parent is ConfigurationFile ? (ushort)0 : (ushort)(parent.IndentLevel + 1); Name = name; IsArray = isArray; _children = children.Select(c => c.Clone(this)).ToList(); Children = _children.AsReadOnly(); }
/// <summary> /// Returns a full path to configuration settings represented by the calling <paramref name="node"/>. /// </summary> /// <param name="node">Configuration setting whose path we want to get.</param> /// <returns>The path of the configuration setting represented by <paramref name="node"/>. It is in format: /// <c>[file.name].setting.path</c>. For example: <c>[views.view.comment].display.default.display_plugin</c>. /// Note that full path also supports arrays. One example with an array is: /// <c>[views.view.comment].dependencies.module[0]</c>.</returns> internal static string GetPathName([NotNull] this IConfigNode node) { if (node is ConfigurationFile) { return($"[{node.Name}]"); } ConfigurationNode parent = node.Parent; string pathName = node.Name; if (string.Equals(pathName, "-", StringComparison.Ordinal)) { pathName = $"[{parent?.Children?.Index().FirstOrDefault(n => ReferenceEquals(n.Value, node)).Key.ToString("##########") ?? string.Empty}]"; } return(parent == null ? pathName : $"{parent.GetPathName()}.{pathName}"); }
private static IEnumerable <IConfigNode> LoadChildren(ConfigurationNode parent, ushort indentSpaces, ConfigFileReader reader, Predicate <IConfigNode> validNode) { if (reader.EoF) { yield break; } ushort requiredIndent = (ushort)reader.CurrentLineIndentSpaces; if (requiredIndent < indentSpaces) { yield break; } if (requiredIndent == indentSpaces && !(parent is ConfigurationFile)) { yield break; } while (!reader.EoF) { if (reader.CurrentLineIndentSpaces != requiredIndent) { yield break; } string content = reader.CurrentLineContent; reader.NextLine(); IConfigNode node = LoadNode(parent, requiredIndent, content, reader); if (validNode?.Invoke(node) ?? true) { yield return(node); } } }
private static IConfigNode LoadNode([NotNull] ConfigurationNode parent, ushort indentSpaces, string content, [NotNull] ConfigFileReader reader) { Match match = RxEmptyArrayNode.Match(content); if (match.Success) { return(new ConfigurationNode(parent, match.Groups["name"].Value, indentSpaces, reader, isEmptyArray: true)); } match = RxSingleValueNode.Match(content); if (match.Success) { return(new SingleValueNode(parent, match.Groups["name"].Value, match.Groups["value"].Value)); } match = RxNameNode.Match(content); if (match.Success) { return(new ConfigurationNode(parent, match.Groups["name"].Value, indentSpaces, reader)); } if (string.Equals(content, "-", StringComparison.Ordinal)) { return(new ConfigurationNode(parent, "-", indentSpaces, reader)); } if (content.StartsWith("- ", StringComparison.Ordinal) && content.Length > 2) { return(new SingleValueNode(parent, "-", content.Substring(1).Trim())); } throw new Exception($"Line content cannot be parsed: {content}"); }
/// <inheritdoc /> public virtual IConfigNode Clone(ConfigurationNode parent) { this.VerifyParent(parent); return(new ConfigurationNode(parent, Name, Children, IsArray)); }
/// <inheritdoc cref="ConfigurationNode.Clone" select="summary" /> /// <param name="parent">Has to be <c>null</c>.</param> /// <returns>Cloned instance.</returns> /// <exception cref="ArgumentException">If <paramref name="parent"/> isn't <c>null</c>.</exception> public override IConfigNode Clone(ConfigurationNode parent) => parent == null ? Clone() : throw new ArgumentNullException($"{nameof(parent)} has to be null.", nameof(parent));