Beispiel #1
0
        /// <summary>
        ///     Proccess a string which contains an ini section.%
        /// </summary>
        /// <param name="currentLine">
        ///     The string to be processed
        /// </param>
        protected virtual bool ProcessSection(StringBuffer currentLine, IniData iniData)
        {
            if (currentLine.Count <= 0)
            {
                return(false);
            }

            var sectionStartRange = currentLine.FindSubstring(Scheme.SectionStartString);

            if (sectionStartRange.IsEmpty)
            {
                return(false);
            }

            var sectionEndRange = currentLine.FindSubstring(Scheme.SectionEndString, sectionStartRange.size);

            if (sectionEndRange.IsEmpty)
            {
                if (Configuration.SkipInvalidLines)
                {
                    return(false);
                }


                var errorFormat = "No closing section value. Please see configuration option {0}.{1} to ignore this error.";
                var errorMsg    = string.Format(errorFormat,
                                                nameof(Configuration),
                                                nameof(Configuration.SkipInvalidLines));

                throw new ParsingException(errorMsg,
                                           _currentLineNumber,
                                           currentLine.DiscardChanges().ToString());
            }

            var startIdx = sectionStartRange.start + Scheme.SectionStartString.Length;
            var endIdx   = sectionEndRange.end - Scheme.SectionEndString.Length;

            currentLine.ResizeBetweenIndexes(startIdx, endIdx);

            if (Configuration.TrimSections)
            {
                currentLine.Trim();
            }

            var sectionName = currentLine.ToString();

            // Temporally save section name.
            _currentSectionNameTemp = sectionName;

            //Checks if the section already exists
            if (!Configuration.AllowDuplicateSections)
            {
                if (iniData.Sections.Contains(sectionName))
                {
                    if (Configuration.SkipInvalidLines)
                    {
                        return(false);
                    }

                    var errorFormat = "Duplicate section with name '{0}'. Please see configuration option {1}.{2} to ignore this error.";
                    var errorMsg    = string.Format(errorFormat,
                                                    sectionName,
                                                    nameof(Configuration),
                                                    nameof(Configuration.SkipInvalidLines));

                    throw new ParsingException(errorMsg,
                                               _currentLineNumber,
                                               currentLine.DiscardChanges().ToString());
                }
            }

            // If the section does not exists, add it to the ini data
            iniData.Sections.Add(sectionName);

            // Save comments read until now and assign them to this section
            if (Configuration.ParseComments)
            {
                var sections    = iniData.Sections;
                var sectionData = sections.FindByName(sectionName);
                sectionData.Comments.AddRange(CurrentCommentListTemp);
                CurrentCommentListTemp.Clear();
            }

            return(true);
        }
Beispiel #2
0
        protected virtual bool ProcessProperty(StringBuffer currentLine, IniData iniData)
        {
            if (currentLine.Count <= 0)
            {
                return(false);
            }

            var propertyAssigmentIdx = currentLine.FindSubstring(Scheme.PropertyAssigmentString);

            if (propertyAssigmentIdx.IsEmpty)
            {
                return(false);
            }

            var keyRange      = Range.WithIndexes(0, propertyAssigmentIdx.start - 1);
            var valueStartIdx = propertyAssigmentIdx.end + 1;
            var valueSize     = currentLine.Count - propertyAssigmentIdx.end - 1;
            var valueRange    = Range.FromIndexWithSize(valueStartIdx, valueSize);

            var key   = currentLine.Substring(keyRange);
            var value = currentLine.Substring(valueRange);

            if (Configuration.TrimProperties)
            {
                key.Trim();
                value.Trim();
            }

            if (key.IsEmpty)
            {
                if (Configuration.SkipInvalidLines)
                {
                    return(false);
                }

                var errorFormat = "Found property without key. Please see configuration option {0}.{1} to ignore this error";
                var errorMsg    = string.Format(errorFormat,
                                                nameof(Configuration),
                                                nameof(Configuration.SkipInvalidLines));

                throw new ParsingException(errorMsg,
                                           _currentLineNumber,
                                           currentLine.DiscardChanges().ToString());
            }

            // Check if we haven't read any section yet
            if (string.IsNullOrEmpty(_currentSectionNameTemp))
            {
                if (!Configuration.AllowKeysWithoutSection)
                {
                    var errorFormat = "Properties must be contained inside a section. Please see configuration option {0}.{1} to ignore this error.";
                    var errorMsg    = string.Format(errorFormat,
                                                    nameof(Configuration),
                                                    nameof(Configuration.AllowKeysWithoutSection));

                    throw new ParsingException(errorMsg,
                                               _currentLineNumber,
                                               currentLine.DiscardChanges().ToString());
                }

                AddKeyToKeyValueCollection(key.ToString(),
                                           value.ToString(),
                                           iniData.Global,
                                           "global");
            }
            else
            {
                var currentSection = iniData.Sections.FindByName(_currentSectionNameTemp);

                AddKeyToKeyValueCollection(key.ToString(),
                                           value.ToString(),
                                           currentSection.Properties,
                                           _currentSectionNameTemp);
            }


            return(true);
        }
Beispiel #3
0
        /// <summary>
        ///     Parses a string containing valid ini data
        /// </summary>
        /// <param name="textReader">
        ///     Text reader for the source string contaninig the ini data
        /// </param>
        /// <returns>
        ///     An <see cref="IniData"/> instance containing the data readed
        ///     from the source
        /// </returns>
        /// <exception cref="ParsingException">
        ///     Thrown if the data could not be parsed
        /// </exception>
        public void Parse(TextReader textReader, ref IniData iniData)
        {
            iniData.Clear();

            iniData.Scheme = Scheme.DeepClone();

            _errorExceptions.Clear();
            if (Configuration.ParseComments)
            {
                CurrentCommentListTemp.Clear();
            }
            _currentSectionNameTemp = null;
            _mBuffer.Reset(textReader);
            _currentLineNumber = 0;

            while (_mBuffer.ReadLine())
            {
                _currentLineNumber++;

                try
                {
                    ProcessLine(_mBuffer, iniData);
                }
                catch (Exception ex)
                {
                    _errorExceptions.Add(ex);
                    if (Configuration.ThrowExceptionsOnError)
                    {
                        throw;
                    }
                }
            }

            // TODO: is this try necessary?
            try
            {
                // Orphan comments, assing to last section/key value
                if (Configuration.ParseComments && CurrentCommentListTemp.Count > 0)
                {
                    if (iniData.Sections.Count > 0)
                    {
                        // Check if there are actually sections in the file
                        var sections = iniData.Sections;
                        var section  = sections.FindByName(_currentSectionNameTemp);
                        section.Comments.AddRange(CurrentCommentListTemp);
                    }
                    else if (iniData.Global.Count > 0)
                    {
                        // No sections, put the comment in the last key value pair
                        // but only if the ini file contains at least one key-value pair
                        iniData.Global.GetLast().Comments.AddRange(CurrentCommentListTemp);
                    }

                    CurrentCommentListTemp.Clear();
                }
            }
            catch (Exception ex)
            {
                _errorExceptions.Add(ex);
                if (Configuration.ThrowExceptionsOnError)
                {
                    throw;
                }
            }

            if (HasError)
            {
                iniData.Clear();
            }
        }