Exemplo n.º 1
0
        /// <summary>
        ///     Adds a key to a concrete <see cref="PropertyCollection"/> instance, checking
        ///     if duplicate keys are allowed in the configuration
        /// </summary>
        /// <param name="key">
        ///     Key name
        /// </param>
        /// <param name="value">
        ///     Key's value
        /// </param>
        /// <param name="keyDataCollection">
        ///     <see cref="Property"/> collection where the key should be inserted
        /// </param>
        /// <param name="sectionName">
        ///     Name of the section where the <see cref="PropertyCollection"/> is contained.
        ///     Used only for logging purposes.
        /// </param>
        private void AddKeyToKeyValueCollection(string key, string value, PropertyCollection keyDataCollection, string sectionName)
        {
            // Check for duplicated keys
            if (keyDataCollection.Contains(key))
            {
                // We already have a key with the same name defined in the current section
                HandleDuplicatedKeyInCollection(key, value, keyDataCollection, sectionName);
            }
            else
            {
                // Save the keys
                keyDataCollection.Add(key, value);
            }

            if (Configuration.ParseComments)
            {
                keyDataCollection.FindByKey(key).Comments = CurrentCommentListTemp;
                CurrentCommentListTemp.Clear();
            }
        }
Exemplo n.º 2
0
        protected virtual bool ProcessComment(StringBuffer currentLine)
        {
            // Line is  med when it came here, so we only need to check if
            // the first characters are those of the comments
            var currentLineTrimmed = currentLine.SwallowCopy();

            currentLineTrimmed.TrimStart();

            if (!currentLineTrimmed.StartsWith(Scheme.CommentString))
            {
                return(false);
            }

            if (!Configuration.ParseComments)
            {
                return(true);
            }

            currentLineTrimmed.TrimEnd();

            var commentRange = currentLineTrimmed.FindSubstring(Scheme.CommentString);
            // Exctract the range of the string that contains the comment but not
            // the comment delimiter
            var startIdx = commentRange.start + Scheme.CommentString.Length;
            var size     = currentLineTrimmed.Count - Scheme.CommentString.Length;
            var range    = Range.FromIndexWithSize(startIdx, size);

            var comment = currentLineTrimmed.Substring(range);

            if (Configuration.TrimComments)
            {
                comment.Trim();
            }

            CurrentCommentListTemp.Add(comment.ToString());

            return(true);
        }
Exemplo n.º 3
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);
        }
Exemplo n.º 4
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();
            }
        }