/// <summary> /// Writes the string representation of a specific <see cref="IniDocument"/> /// object to the specified destination stream. /// </summary> /// <param name="source"> /// The <see cref="IniDocument"/> object to write. /// </param> /// <param name="destStream"> /// The destination stream to be written. /// </param> /// <exception cref="ArgumentNullException"> /// source or destStream is null. /// </exception> public static void WriteTo(this IniDocument source, Stream destStream) { if (source == null) { throw new ArgumentNullException(nameof(source)); } if (destStream == null) { throw new ArgumentNullException(nameof(destStream)); } var fileFormat = source.FileFormat; using var sw = new StreamWriter(destStream, fileFormat == IniFileFormat.Regedit4 ? EncodingEx.Ansi : EncodingEx.Utf8NoBom, 8192, true); switch (fileFormat) { case IniFileFormat.Regedit4: sw.WriteLine("REGEDIT4"); sw.WriteLine(); break; case IniFileFormat.Regedit5: sw.WriteLine("Windows Registry Editor Version 5.00"); sw.WriteLine(); break; } foreach (var section in source.Sections) { if (IniHelper.SectionIsInvalid(section)) { continue; } var keyValueDict = source[section]; var hasNoValue = !keyValueDict?.Any() ?? true; if (hasNoValue && !IniHelper.IsImportantSection(section)) { continue; } if (!string.IsNullOrEmpty(section)) { sw.Write('['); sw.Write(section.Trim()); sw.WriteLine(']'); } if (hasNoValue) { sw.WriteLine(); continue; } foreach (var pair in keyValueDict) { if (IniHelper.KeyIsInvalid(pair.Key) || !pair.Value.Any()) { continue; } foreach (var value in pair.Value) { if (string.IsNullOrEmpty(value) || value.Any(TextEx.IsLineSeparator)) { continue; } sw.Write(pair.Key.Trim()); sw.Write('='); if (!IniHelper.IsHex(value) || value.Length < 76) { sw.WriteLine(value); } else { for (var i = 0; i < value.Length; i++) { sw.Write(value[i]); if (i == 0 || i % 75 != 0) { continue; } sw.WriteLine('\\'); } sw.WriteLine(); } } } sw.WriteLine(); } }
internal static IDictionary <string, IDictionary <string, IList <string> > > Parse(string fileOrContent, bool ignoreCase, out IniFileFormat fileFormat) { fileFormat = IniFileFormat.Default; var source = fileOrContent; if (string.IsNullOrEmpty(source)) { throw new ArgumentNullException(nameof(fileOrContent)); } var path = PathEx.Combine(source); if (File.Exists(path)) { source = File.ReadAllText(path, EncodingEx.Utf8NoBom); } var lines = source.Split(TextSeparatorChar.AllNewLineChars, StringSplitOptions.RemoveEmptyEntries); var comparer = ignoreCase ? StringComparer.OrdinalIgnoreCase : StringComparer.Ordinal; var content = new Dictionary <string, IDictionary <string, IList <string> > >(comparer); var section = string.Empty; var key = string.Empty; var index = 0; var isHex = false; for (var i = 0; i < lines.Length; i++) { var line = lines[i]; if (i == 0) { if (line.Equals("Windows Registry Editor Version 5.00", StringComparison.Ordinal)) { fileFormat = IniFileFormat.Regedit5; } else if (line.Equals("REGEDIT4", StringComparison.Ordinal)) { fileFormat = IniFileFormat.Regedit4; } } if (isHex && (isHex = IniHelper.IsHex(line))) { content[section][key][index] += line.TrimEnd('\\'); continue; } var item = line.Trim(); if (item.Length < 3 || item[0] == ';' || item[0] == '#') { continue; } int length; if (item[0] == '[' && (length = item.LastIndexOf(']') - 1) > 0) { section = item.Substring(1, length); if (IniHelper.IsImportantSection(section) && !content.ContainsKey(section)) { content.Add(section, default); } continue; } if ((length = item.IndexOf('=')) < 1 || length > item.Length - 2) { continue; } key = item.Substring(0, length); var value = item.Substring(length + 1); if (IniHelper.HasHexPrefix(value) && IniHelper.IsHex(value) && value.EndsWith("\\", StringComparison.Ordinal)) { isHex = true; value = value.TrimEnd('\\'); } if (!content.ContainsKey(section)) { content.Add(section, new Dictionary <string, IList <string> >(comparer)); } if (!content[section].ContainsKey(key)) { content[section].Add(key, new List <string>()); } content[section][key].Add(value); if (isHex) { index = content[section][key].Count - 1; } } return(content); }