Ejemplo n.º 1
0
        /// <summary>
        /// Reads the key and value.
        /// </summary>
        /// <param name="currentSection">The current section.</param>
        /// <param name="currentLine">The current line.</param>
        /// <param name="lineRaw">The line raw.</param>
        /// <param name="lineNumber">The line number.</param>
        /// <param name="append">if set to <c>true</c> [append].</param>
        /// <exception cref="ConfigParserException">Arrays must start from a new line and not after the key!
        /// or</exception>
        /// <exception cref="NotImplementedException"></exception>
        private void ReadKeyAndValue(ref ConfigSection currentSection, ref ConfigLine currentLine, string lineRaw,
                                     int lineNumber, bool append = false, bool forceIncludeKey = false)
        {
            if (null != currentLine && !append)
            {
                BackupCurrentLine(ref currentSection, ref currentLine, lineNumber);
            }

            if (append && null == currentLine)
            {
                throw new ConfigParserException("You are trying to append value to a null line!", lineNumber);
            }

            var keyMatch  = Settings.KeyMatcher.Match(lineRaw);
            var keyName   = keyMatch.Groups["key"]?.Value;
            var separator = (string.IsNullOrWhiteSpace(keyMatch.Groups["separator"]?.Value))
                ? Settings.KeyValueSeparator
                : keyMatch.Groups["separator"]?.Value;

            if (!forceIncludeKey && keyMatch.Success && keyMatch.Captures.Count > 0)
            {
                lineRaw = lineRaw.Substring(keyMatch.Captures[0].Value.Length);
            }

            var valueMatch = Settings.ValueMatcher.Match(lineRaw);
            var value      = valueMatch.Groups["value"]?.Value;

            switch (Settings.MultiLineValues)
            {
            case var _ when Settings.MultiLineValues.HasFlag(MultiLineValues.QuoteDelimitedValues):
                if (!string.IsNullOrEmpty(value))
                {
                    if (Equals('"', value.First()))
                    {
                        value = value.Substring(1);
                    }
                    if (Equals('"', value.Last()))
                    {
                        value = value.Remove(value.Length - 1);
                    }
                }

                break;

            case var _ when Settings.MultiLineValues.HasFlag(MultiLineValues.NotAllowed) ||
                Settings.MultiLineValues.HasFlag(MultiLineValues.Simple):
                // Do nothing add with quotes if any
                break;

            default:
                throw new ConfigParserException("Unknown key=value situation detected!", lineNumber);
            }

            try
            {
                if (append)
                {
                    currentLine.Content = $"{currentLine.Content}{Settings.NewLine}{value}";
                }
                else
                {
                    currentLine = new ConfigKeyValue <object>(keyName, separator, value, lineNumber);
                }
            }
            catch (Exception ex)
            {
                throw new ConfigParserException($"Failed to parse the following line: '{lineRaw}'", lineNumber, ex);
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Reads the specified configuration content.
        /// </summary>
        /// <param name="configContent">Content of the configuration.</param>
        /// <exception cref="ArgumentException">configContent</exception>
        private void Read(string configContent)
        {
            if (string.IsNullOrWhiteSpace(configContent))
            {
                throw new ArgumentException(nameof(configContent));
            }

            using var stringReader = new StringReader(configContent);
            string lineRaw;
            var lineNumber = 0;
            ConfigSection currentSection = null;
            ConfigLine currentLine       = null;

            while (null != (lineRaw = stringReader.ReadLine()))
            {
                lineNumber++;

                switch (lineRaw)
                {
                case var _ when string.IsNullOrWhiteSpace(lineRaw):
                    ReadEmptyLine(ref currentSection, ref currentLine, lineRaw, lineNumber);

                    continue;

                case var _ when ConfigParserSettings.SectionMatcher.IsMatch(lineRaw):
                    ReadSection(ref currentSection, ref currentLine, lineRaw, lineNumber);

                    break;

                case var _ when Settings.CommentMatcher.IsMatch(lineRaw):
                    ReadComment(ref currentSection, ref currentLine, lineRaw, lineNumber);

                    break;

                case var _ when Settings.KeyMatcher.IsMatch(lineRaw):
                    if (!Settings.MultiLineValues.HasFlag(MultiLineValues.NotAllowed) && IsKeyLikeArrayValue(currentLine?.Content, lineRaw))
                    {
                        ReadKeyAndValue(ref currentSection, ref currentLine, lineRaw, lineNumber, append: true, forceIncludeKey: true);
                    }
                    else
                    {
                        ReadKeyAndValue(ref currentSection, ref currentLine, lineRaw, lineNumber);
                    }
                    break;

                // Multi-line + allow value-less option on
                case var _ when Settings.ValueMatcher.IsMatch(lineRaw) && currentLine != null &&
                    Settings.KeyMatcher.IsMatch(currentLine.ToString()) &&
                    Settings.MultiLineValues.HasFlag(MultiLineValues.AllowValuelessKeys) &&
                    Settings.MultiLineValues.HasFlag(MultiLineValues.Simple) &&
                    ConfigLine.IndentationMatcher.IsMatch(lineRaw) &&
                    !Equals(currentLine.Indentation, ConfigLine.IndentationMatcher.Match(lineRaw).Value):
                    AppendValueToKey(ref currentSection, ref currentLine, lineRaw, lineNumber);

                    break;

                case var _ when Settings.ValueMatcher.IsMatch(lineRaw):
                    if (Settings.MultiLineValues.HasFlag(MultiLineValues.AllowValuelessKeys))
                    {
                        ReadValuelessKey(ref currentSection, ref currentLine, lineRaw, lineNumber);
                    }
                    else
                    {
                        AppendValueToKey(ref currentSection, ref currentLine, lineRaw, lineNumber);
                    }
                    break;

                default:
                    throw new ConfigParserException("Unknown element found!", lineNumber);
                }
            }

            if (null != currentLine)
            {
                BackupCurrentLine(ref currentSection, ref currentLine, lineNumber);
            }

            if (null != currentSection)
            {
                sections.Add(currentSection.SectionName, currentSection);
            }
        }