/// <summary> /// INI ファイル (初期化ファイル) のコンテンツをストリームから読み込みます。 /// </summary> /// <param name="stream"> /// コンテンツのストリーム /// </param> public void Read(Stream stream) { #if DEBUG Debug.WriteLine("Start reading Stream", DebugInfo.ShortName); #endif using (var reader = new StreamReader(stream, Encoding.UTF8, false, 255, true)) { // SET Position of BaseStream to 0 reader.BaseStream.Position = 0; // Read 1st Line of Stream var current_line = reader.ReadLine(); // MAIN LOOP: START while (current_line != null) { // NEW & READ Section PrivateProfileSection section = PrivateProfileSection.Read(reader, current_line, out string next_line, this.IgnoreDuplicatedEntry); // Validations: if (string.IsNullOrWhiteSpace(section.Name)) { // for Null Section: // Validation: Null Section Check; Null Section is allowed only for 1st section (sections[0]). if (this.sections.Count > 0) { throw new InvalidDataException(Resources.PrivateProfileNullSectionAlreadyExistsErrorMessage); } } else { // for Normal Section: // Validation: If the same Section Name already exists. if (this.sections.ContainsKey(section.Name)) { throw new InvalidDataException(Resources.PrivateProfileSectionNameAlreadyExistsErrorMessage); } } // ADD Section this.sections.Add(section.Name, section); // SET Next Line current_line = next_line; } // MAIN LOOP: END } #if DEBUG Debug.WriteLine("End reading Stream", DebugInfo.ShortName); #endif }
// ---------------------------------------------------------------------------------------------------- // Static Method(s) // ---------------------------------------------------------------------------------------------------- /// <summary> /// INI ファイル (初期化ファイル) からセクションを読み込みます。 /// </summary> /// <param name="reader"> /// このセクションを読み込む INI ファイルの <see cref="StreamReader"/> を指定します。 /// </param> /// <param name="firstLine"> /// このセクションの最初の 1 行を指定します。 /// </param> /// <param name="nextLine"> /// このセクションの次にセクションがある場合に、そのセクションの最初の 1 ラインが格納されます。 /// このセクションが最後のセクションだった場合は <c>null</c> が格納されます。 /// </param> /// <param name="ignoreDuplicatedEntry"> /// エントリのキーが重複しているセクションを読み込むことを許可する場合に <c>true</c> を指定します。 /// 既定は <c>false</c> です。 /// </param> /// <returns> /// 読み込みに成功した場合は、読み込んだセクション (<see cref="PrivateProfileSection"/>) を返します。 /// 読み込みに失敗した場合は <c>null</c> を返します。 /// </returns> public static PrivateProfileSection Read(TextReader reader, string firstLine, out string nextLine, bool ignoreDuplicatedEntry = false) { // Validation (Null Check): if (reader is null) { throw new ArgumentNullException(nameof(reader)); } if (firstLine is null) { throw new ArgumentNullException(nameof(firstLine)); } // Initialize value(s) nextLine = null; var raw_line = firstLine; // Initialize Section (NOT NEW) PrivateProfileSection section = null; #if DEBUG Debug.WriteLine("Start reading the Section.", DebugInfo.ShortName); #endif // MAIN LOOP: START while (raw_line != null) // instead of (!reader.EndOfStream) { // NEW Line var line = new PrivateProfileLine(raw_line); // Check only for 1st Line if (section is null) { // NEW Section; because Section is NOT yet initialized. section = new PrivateProfileSection(ignoreDuplicatedEntry); // Check LineType (Null Section Check) if (line.LineType != PrivateProfileLineType.Section) { // Insert Line for Null Section section.Append(new PrivateProfileLine(null)); // ADD SECTION section.Append(line); // Check NEXT Line if ((raw_line = reader.ReadLine()) == null) { break; } // Read NEXT Line line = new PrivateProfileLine(raw_line); } } // ADD SECTION or ENTRY (or, Go to NEXT Section) switch (line.LineType) { // SECTION Line: case PrivateProfileLineType.Section: // Check if Section Name is for Current or NEXT Section if (section.lines.Count == 0) { // CURRENT Section: // ADD SECTION section.Append(line); break; } else { // NEXT Section: Current Section has ended. #if DEBUG Debug.Write("End reading Section " + (section.Name is null ? "(null)" : $"\"{section.Name}\""), DebugInfo.ShortName); Debug.WriteLine($", because NEXT Section \"{line.SectionName}\" was found."); #endif // SET 1st Line of NEXT Section nextLine = raw_line; // RETURN CURRENT Section return(section); } // ENTRY Line: case PrivateProfileLineType.Entry: // ADD ENTRY section.Append(line); break; // ENTRY Line (Blank Line or Comment Line): case PrivateProfileLineType.Other: // ADD ENTRY section.Append(line); break; default: throw new NotSupportedException(); } // Read NEXT Line raw_line = reader.ReadLine(); } // MAIN LOOP: END #if DEBUG Debug.WriteLine("End reading Section " + (section.Name is null ? "(null)" : $"\"{section.Name}\"") + ".", DebugInfo.ShortName); #endif // RETURN return(section); }