private static int GetFirstLineOfSection(List <string> lines, string section) { // The global section always starts at the first line if (section == null) { return(0); } // Find the first setting line of a named section section = section.Trim(); int currentLine = 0; while (currentLine < lines.Count) { IniParseResult result = ParseIni(lines, currentLine); if (result.Type == IniLineType.SectionHeader && result.PrimaryContent == section) { return(currentLine); } currentLine += result.LinesRead; } // No section with the given name found return(-1); }
/// <summary> /// Removes the section with the given name and all its lines until the next section starts. /// </summary> /// <param name="section">The name of the section to remove.</param> internal void RemoveSection(string section) { // Read in all text lines List <string> lines = new List <string>(ReadFileLines(FileName)); // Get the line where the section starts int firstLine = GetFirstLineOfSection(lines, section); if (firstLine == -1) { throw new InvalidDataException("Section \"" + section + "\" does not exist."); } // Get the line where the section ends int lastLine = firstLine + 1; while (lastLine < lines.Count) { IniParseResult result = ParseIni(lines, lastLine); if (result.Type == IniLineType.SectionHeader) { break; } lastLine += result.LinesRead; } // Remove the lines for (int i = lastLine - 1; i >= firstLine; i--) { lines.RemoveAt(i); } // Write the changes to the file WriteFileLines(FileName, lines); }
private bool TryGetString(string section, string key, out string value) { // Check arguments if (section != null && section.Trim().Length == 0) { throw new ArgumentException("Section name must not be whitespace. Pass null to query the global " + "section."); } if (string.IsNullOrWhiteSpace(key)) { throw new ArgumentException("Key name must not be null or whitespace."); } key = key.Trim(); // Read in all text lines List <string> lines = ReadFileLines(FileName); // Find the first setting line of the given section int firstSettingLine = GetFirstLineOfSection(lines, section); if (firstSettingLine == -1) { // Section and thus value not found. value = null; return(false); } firstSettingLine++; // Find the setting in the section int currentLine = firstSettingLine; while (currentLine < lines.Count) { IniParseResult result = ParseIni(lines, currentLine); if ((result.Type == IniLineType.SingeLineValue || result.Type == IniLineType.MultiLineValue) && result.PrimaryContent == key) { value = result.SecondaryContent; return(true); } currentLine += result.LinesRead; } // Value not found value = null; return(false); }
private static IniParseResult ParseIni(List <string> lines, int firstLine) { IniParseResult result = null; string key = null; string value = null; bool isInMultilineValue = false; for (int i = firstLine; i < lines.Count; i++) { string line = lines[i]; string trimmedLine = line.Trim(); // In multiline mode, every line except "}" counts as a part of the value if (isInMultilineValue) { if (trimmedLine == "}") { // End of multiline value result = new IniParseResult(IniLineType.MultiLineValue, key, value, i - firstLine + 1); break; } else { // Additional multiline line value = value == null ? line : string.Join(Environment.NewLine, value, line); } } else { if (trimmedLine.Length == 0) { // Empty line result = new IniParseResult(IniLineType.EmptyLine, null, null, 1); break; } else if (trimmedLine[0] == ';' || trimmedLine[0] == '#') { // Comment string commentText = trimmedLine.Substring(1).TrimEnd(); result = new IniParseResult(IniLineType.Comment, commentText, null, 1); break; } else if (trimmedLine[0] == '[' && trimmedLine[trimmedLine.Length - 1] == ']') { // Section header string sectionName = trimmedLine.Substring(1, trimmedLine.Length - 2).Trim(); result = new IniParseResult(IniLineType.SectionHeader, sectionName, null, 1); break; } else { int equalsIndex = trimmedLine.IndexOf('='); if (equalsIndex > 0) { // Setting key = trimmedLine.Substring(0, equalsIndex).Trim(); value = trimmedLine.Substring(equalsIndex + 1).Trim(); if (value == "{") { // Multiline setting isInMultilineValue = true; value = null; } else { // Single line setting result = new IniParseResult(IniLineType.SingeLineValue, key, value, 1); break; } } else { // Invalid line result = new IniParseResult(IniLineType.InvalidLine, line, null, 1); break; } } } } // Invalid content return(result); }
/// <summary> /// Sets the specified string value in the given section under the provided key. /// </summary> /// <param name="section">The section under which the setting is stored.</param> /// <param name="key">The key of the setting.</param> /// <param name="value">The value of the setting.</param> internal void SetValue(string section, string key, string value) { // Set up parameters if (section != null) { section = section.Trim(); } if (string.IsNullOrWhiteSpace(key)) { throw new ArgumentException("Key name must not be null or whitespace."); } key = key.Trim(); value = value == null ? string.Empty : value.ToString().Trim(); // Read in all text lines List <string> lines = new List <string>(ReadFileLines(FileName)); // Get the section line of the setting int lastLine = GetFirstLineOfSection(lines, section); if (lastLine == -1) { // If the section does not exist, insert a new one at the end of the file lines.Add("[" + section + "]"); InsertSettingLines(lines, key, value, lines.Count); } else { // Find the setting line or add it to the bottom of the section int lastSettingLine = -1; while (lastLine < lines.Count) { IniParseResult result = ParseIni(lines, lastLine); if (result.Type == IniLineType.SingeLineValue || result.Type == IniLineType.MultiLineValue) { lastSettingLine = lastLine - 1 + result.LinesRead; // Check if this is the setting searched for and change it then if (result.PrimaryContent == key) { // Remove the lines of the multiline value first for (int i = lastLine + result.LinesRead - 1; i >= lastLine; i--) { lines.RemoveAt(i); } // Insert the new value InsertSettingLines(lines, key, value, lastLine); break; } } else if (result.Type == IniLineType.SectionHeader && result.PrimaryContent != section) { // Value not found in section, add it after the last setting of the previous section InsertSettingLines(lines, key, value, lastSettingLine + 1); break; } lastLine += result.LinesRead; } // Setting not found in the last section, insert the setting at the end of the file if (lastLine == lines.Count) { InsertSettingLines(lines, key, value, lastSettingLine + 1); } } // Write the changes to the file WriteFileLines(FileName, lines); }