view IniFileReader.cs @ 3:3c26f463977a

Re #7 - Add INI parsing tests * Make IniSection throw a new DuplicateIniLineException to make testing of duplicates easier
author IBBoard <dev@ibboard.co.uk>
date Sun, 18 Jan 2009 14:18:07 +0000
parents 2dde4c1d19d9
children f6f726c92e56
line wrap: on
line source

// This file (IniFileReader.cs) is a part of the IBBoard.Ini library and is copyright 2009 IBBoard.
//
// The file and the library/program it is in are licensed under the GNU LGPL license. Please see COPYING.LGPL for more information and the full license.

using System;
using System.IO;
using System.Text;

namespace IBBoard.Ini
{
	public class IniFileReader
	{
		public static IniFile ReadFile(string iniFileContent)
		{
			MemoryStream memoryStream = new MemoryStream(System.Text.ASCIIEncoding.ASCII.GetBytes(iniFileContent));
			return LoadIniFileFromStream(new StreamReader(memoryStream));
		}
		
		public static IniFile ReadFile(FileInfo file)
		{
			if (!file.Exists)
			{
				throw new FileNotFoundException(file.FullName+" did not exist and could not be read");
			}
			
			return LoadIniFileFromFile(file);
		}
		
		private static IniFile LoadIniFileFromFile(FileInfo file)
		{
			StreamReader stream = file.OpenText();
			IniFile iniFile = null;
			
			try
			{
				iniFile = LoadIniFileFromStream(stream);
			}
			finally
			{
				stream.Close();
			}

			return iniFile;
		}
		
		private static IniFile LoadIniFileFromStream(StreamReader stream)
		{
			string firstHeader = ReadToFirstSectionHeader(stream);
			return ReadIniFileSectionsToFile(stream, firstHeader);
		}

		private static string ReadToFirstSectionHeader(StreamReader stream)
		{
			string firstSectionHeader = null;
			
			while (!stream.EndOfStream && firstSectionHeader == null)
			{
				string line = stream.ReadLine().Trim();

				if (IniSectionParser.IsLineStartOfNewSection(line))
				{
					firstSectionHeader = line + "\n";
				}
			}

			return firstSectionHeader;
		}

		private static IniFile ReadIniFileSectionsToFile(StreamReader stream, string firstHeader)
		{
			IniFile iniFile = new IniFile();			
			StringBuilder sectionStringBuilder = SetUpStringBuilder(firstHeader);
			
			while (!stream.EndOfStream)
			{
				string line = stream.ReadLine().Trim();
				
				if (IniSectionParser.IsLineStartOfNewSection(line))
				{
					AddSectionFromStringBuilderContents(sectionStringBuilder, iniFile);
					sectionStringBuilder.Length = 0;
				}
				
				sectionStringBuilder.Append(line);
				sectionStringBuilder.Append("\n");
			}

			if (sectionStringBuilder.Length > 0)
			{
				AddSectionFromStringBuilderContents(sectionStringBuilder, iniFile);
			}

			return iniFile;
		}

		private static StringBuilder SetUpStringBuilder(string firstHeader)
		{
			StringBuilder sectionStringBuilder = new StringBuilder();

			if (firstHeader!=null)
			{
				sectionStringBuilder.Append(firstHeader);
				sectionStringBuilder.Append("\n");
			}

			return sectionStringBuilder;
		}

		private static void AddSectionFromStringBuilderContents(StringBuilder sectionStringBuilder, IniFile iniFile)
		{			
			IniSection section = IniSectionParser.CreateSection(sectionStringBuilder.ToString());
			iniFile.AddSection(section);
		}
	}
}