/// <summary> /// Constructor used in reading from configuration file. /// </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="indentSpaces">Number of space characters in left indent.</param> /// <param name="reader">Reader used for reading the configuration file.</param> /// <param name="validNode">Predicate that determines if a particular node is <em>valid</em>, thus should be added to /// <see cref="Children"/> collection, or not. If <c>null</c> all the nodes are considered <em>valid</em>. Defaults to /// <c>null</c>.</param> /// <param name="isEmptyArray">Indicates if this instance represents an empty array. Defaults to <c>false</c>.</param> protected ConfigurationNode(ConfigurationNode parent, [NotNull] string name, ushort indentSpaces, ConfigFileReader reader, Predicate <IConfigNode> validNode = null, bool isEmptyArray = false) { Parent = parent; IndentLevel = parent == null || parent is ConfigurationFile ? (ushort)0 : (ushort)(parent.IndentLevel + 1); Name = name; if (isEmptyArray) { _children = new List <IConfigNode>(); IsArray = true; } else { _children = LoadChildren(this, indentSpaces, reader, validNode).ToList(); if (_children.Any(c => string.Equals(c.Name, "-", StringComparison.Ordinal))) { if (_children.Any(c => !string.Equals(c.Name, "-", StringComparison.Ordinal))) { throw new Exception("Node contains both array item nodes, and regular nodes."); } IsArray = true; } } Children = _children.AsReadOnly(); }
/// <summary> /// Constructor used in reading configuration file. /// </summary> /// <param name="reader">Configuration file reader used.</param> /// <param name="validNode">Predicate that determines if a particular node is <em>valid</em>, thus should be added to /// <see cref="ConfigurationNode.Children"/> collection, or not. If <c>null</c> all the nodes are considered /// <em>valid</em>. Defaults to a function which returns <c>false</c> for nodes with <see cref="IConfigNode.Name"/> /// <c>"_core"</c>.</param> private ConfigurationFile(ConfigFileReader reader, Predicate <IConfigNode> validNode = null) : base(null, reader.File.Name.EndsWith(".yml", StringComparison.OrdinalIgnoreCase) ? reader.File.Name.Substring(0, reader.File.Name.Length - 4) : reader.File.Name, 0, reader, validNode ?? DefaultValidNode) { if (!reader.EoF) { throw new Exception($"Not all lines are loaded from file '{reader.File.Name}'."); } File = reader.File; }
public static bool TryLoadFromFile(FileInfo file, out ConfigurationFile configuration, Predicate <IConfigNode> validNode = null) { configuration = null; try { using (ConfigFileReader reader = new ConfigFileReader(file)) configuration = new ConfigurationFile(reader, validNode); return(true); } catch (Exception ex) { Console.WriteLine(); $"Exception while loading configuration from '{file}':{Environment.NewLine}{ex}".WriteLineRed(); } return(false); }
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}"); }