/// <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;
        }
Exemple #2
0
        /// <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}");
        }
Exemple #4
0
        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);
                }
            }
        }
Exemple #5
0
        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}");
        }
Exemple #6
0
        /// <inheritdoc />
        public virtual IConfigNode Clone(ConfigurationNode parent)
        {
            this.VerifyParent(parent);

            return(new ConfigurationNode(parent, Name, Children, IsArray));
        }
Exemple #7
0
 /// <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));