diff --git a/src/IniParser.Tests/Unit/Parser/ParserTests.cs b/src/IniParser.Tests/Unit/Parser/ParserTests.cs index b625d7cf..fbf971c9 100644 --- a/src/IniParser.Tests/Unit/Parser/ParserTests.cs +++ b/src/IniParser.Tests/Unit/Parser/ParserTests.cs @@ -90,6 +90,34 @@ public void parse_ini_string_with_custom_configuration() Assert.That(section1.Properties["key2"], Is.EqualTo("value5")); } + [Test, Description("Tests for ability to parse properties with no values")] + public void test_parsing_properties_without_value() + { + var iniString = @" +[section1] +value1 +value2"; + var parser = new IniDataParser(); + parser.Configuration.AllowPropertiesWithoutValue = true; + var parsedData = parser.Parse(iniString); + + Assert.That(parsedData["section1"].Contains("value1"), Is.True); + Assert.That(parsedData["section1"]["value1"], Is.Null); + } + + [Test, Description("Tests for ability to parse properties with empty values")] + public void test_parsing_properties_with_empty_value() + { + var iniString = @" +[section1] +value1="; + var parser = new IniDataParser(); + var parsedData = parser.Parse(iniString); + + Assert.That(parsedData["section1"].Contains("value1"), Is.True); + Assert.That(parsedData["section1"]["value1"], Is.Empty); + } + [Test, Description("Test for Issue 3: http://code.google.com/p/ini-parser/issues/detail?id=3")] public void allow_keys_with_dots() { diff --git a/src/IniParser/Configuration/IniParserConfiguration.cs b/src/IniParser/Configuration/IniParserConfiguration.cs index ac597d7d..bfbcb4fb 100644 --- a/src/IniParser/Configuration/IniParserConfiguration.cs +++ b/src/IniParser/Configuration/IniParserConfiguration.cs @@ -37,6 +37,7 @@ public IniParserConfiguration() AllowDuplicateSections = ori.AllowDuplicateSections; ThrowExceptionsOnError = ori.ThrowExceptionsOnError; SkipInvalidLines = ori.SkipInvalidLines; + AllowPropertiesWithoutValue = ori.AllowPropertiesWithoutValue; TrimSections = ori.TrimSections; TrimProperties = ori.TrimProperties; } @@ -142,6 +143,15 @@ public enum EDuplicatePropertiesBehaviour /// public bool SkipInvalidLines { get; set; } = false; + /// + /// If true, it will consider lines that does not contains an assignment + /// character as properties with a null value + /// + /// + /// Defaults to false. + /// + public bool AllowPropertiesWithoutValue { get; set; } + /// /// If set to true, it will trim the whitespace out of the property when parsing. /// If set to false, it will consider all the whitespace in the line as part of the diff --git a/src/IniParser/IniDataParser.cs b/src/IniParser/IniDataParser.cs index 63a0e22a..46a2deb4 100644 --- a/src/IniParser/IniDataParser.cs +++ b/src/IniParser/IniDataParser.cs @@ -343,20 +343,33 @@ protected virtual bool ProcessProperty(StringBuffer currentLine, IniData iniData 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); + StringBuffer key; + StringBuffer value; + if (propertyAssigmentIdx.IsEmpty) + { + if (Configuration.AllowPropertiesWithoutValue) + { + key = currentLine; + value = null; + } + else + return false; + } + else + { + 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); + key = currentLine.Substring(keyRange); + value = currentLine.Substring(valueRange); + } if (Configuration.TrimProperties) { key.Trim(); - value.Trim(); + value?.Trim(); } if (key.IsEmpty) @@ -389,7 +402,7 @@ protected virtual bool ProcessProperty(StringBuffer currentLine, IniData iniData } AddKeyToKeyValueCollection(key.ToString(), - value.ToString(), + value?.ToString(), iniData.Global, "global"); } @@ -398,7 +411,7 @@ protected virtual bool ProcessProperty(StringBuffer currentLine, IniData iniData var currentSection = iniData.Sections.FindByName(_currentSectionNameTemp); AddKeyToKeyValueCollection(key.ToString(), - value.ToString(), + value?.ToString(), currentSection.Properties, _currentSectionNameTemp); }