Пример #1
0
        /// <summary>
        /// Create a configuration by parsing the given ini lines
        /// </summary>
        /// <param name="iniLines"></param>
        /// <param name="configuration"></param>
        /// <returns></returns>
        public static bool TryParse(IEnumerable <string> iniLines, out Configuration?configuration)
        {
            var lines = new List <ConfigurationLine>();
            ConfigurationLine?   previousLine   = null;
            ConfigurationSection?currentSection = null;

            foreach (var iniLine in iniLines)
            {
                if (ConfigurationLine.TryPrase(iniLine, previousLine, out var line))
                {
                    if (line != previousLine)
                    {
                        line.Index = lines.Count;
                        lines.Add(line);
                        previousLine = line;
                        if (line is ConfigurationSection section)
                        {
                            currentSection = section;
                        }
                        else if (line is ConfigurationValue value)
                        {
                            if (currentSection == null)
                            {
                                // Section expected
                                configuration = null;
                                return(false);
                            }
                            currentSection.Add(value);
                        }
                    }
                }
                else
                {
                    configuration = null;
                    return(false);
                }
            }
            configuration = new Configuration(lines);
            return(true);
        }
Пример #2
0
        public static bool TryPrase(string iniLine, ConfigurationLine?previousLine, out ConfigurationLine line)
        {
            var indentation = "";
            var i           = 0;

            while (i < iniLine.Length && IsWhitespace(iniLine[i]))
            {
                indentation += iniLine[i];
                ++i;
            }

            // Empty or whitespace-only
            if (i == iniLine.Length)
            {
                line = new ConfigurationLine(indentation);
                return(true);
            }

            // Comment
            if (iniLine[i] == '#' || iniLine[i] == ';')
            {
                var delimiter = iniLine[i];
                ++i;
                var leadingWhitespace = "";
                while (i < iniLine.Length && IsWhitespace(iniLine[i]))
                {
                    leadingWhitespace += iniLine[i];
                    ++i;
                }
                var text = iniLine.Substring(i);
                line = new ConfigurationComment(indentation, delimiter, leadingWhitespace, text);
                return(true);
            }

            // Section
            if (iniLine[i] == '[')
            {
                var name = "";
                ++i;
                while (i < iniLine.Length && iniLine[i] != ']')
                {
                    name += iniLine[i];
                    ++i;
                }
                if (iniLine[i] == ']')
                {
                    ++i;
                    var trailingWhitespace = "";
                    while (i < iniLine.Length && IsWhitespace(iniLine[i]))
                    {
                        trailingWhitespace += iniLine[i];
                        ++i;
                    }
                    if (i == iniLine.Length)
                    {
                        var trimmedName           = name.TrimStart();
                        var nameLeadingWhitespace = name.Substring(0, name.Length - trimmedName.Length);
                        trimmedName = trimmedName.TrimEnd();
                        var nameTrailingWhitespace = name.Substring(nameLeadingWhitespace.Length + trimmedName.Length);
                        line = new ConfigurationSection(indentation, nameLeadingWhitespace, trimmedName, nameTrailingWhitespace, trailingWhitespace);
                        return(true);
                    }
                }
                line = null !;
                return(false);
            }

            // Value
            var    key = "";
            var    keyTrailingWhitespace       = "";
            char   keyValueDelimiter           = '=';
            var    delimiterTrailingWhitespace = "";
            string?value = null;
            var    valueTrailingWhitespace = "";

            while (i < iniLine.Length && iniLine[i] != ':' && iniLine[i] != '=')
            {
                key += iniLine[i];
                ++i;
            }
            var j = key.Length - 1;

            while (j >= 0 && IsWhitespace(key[j]))
            {
                keyTrailingWhitespace = key[j] + keyTrailingWhitespace;
                --j;
            }
            key = key.Substring(0, j + 1);

            if (i < iniLine.Length && (iniLine[i] == ':' || iniLine[i] == '='))
            {
                if (key.Length == 0)
                {
                    // Expecting key before = or :
                    line = null !;
                    return(false);
                }
                keyValueDelimiter = iniLine[i];
                ++i;
                while (i < iniLine.Length && IsWhitespace(iniLine[i]))
                {
                    delimiterTrailingWhitespace += iniLine[i];
                    ++i;
                }
                value = iniLine.Substring(i);
                j     = value.Length - 1;
                while (j >= 0 && IsWhitespace(value[j]))
                {
                    valueTrailingWhitespace = value[j] + valueTrailingWhitespace;
                    --j;
                }
                value = value.Substring(0, j + 1);
            }
            else
            {
                // Blank line
                if (key.Length == 0)
                {
                    line = new ConfigurationLine(indentation);
                    return(true);
                }
            }

            // Check for wrapped lines and unwrap into the previous line's value
            if (previousLine is ConfigurationValue previousValueLine)
            {
                if (indentation.Length > previousValueLine.Indentation.Length)
                {
                    previousValueLine.Value += " " + key;
                    previousValueLine.ValueTrailingWhitespace = valueTrailingWhitespace;
                    line = previousValueLine;
                    return(true);
                }
            }

            line = new ConfigurationValue(indentation, key, keyTrailingWhitespace, keyValueDelimiter, delimiterTrailingWhitespace, value, valueTrailingWhitespace);
            return(true);
        }