view IniSection.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 (IniSection.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.Collections;
using System.Collections.Generic;
using System.Text;

namespace IBBoard.Ini
{
	/// <summary>
	/// The <code>IniSection</code> holds a header from an INI file ("[header]") and all INI lines until either the end of the file
	/// or to the next <code>IniSection</code>.
	/// </summary>
	public class IniSection : IEnumerable<IIniLine>
	{
		private string name;
		private Dictionary<string, IniKeyValuePairLine> values;
		private List<IIniLine> iniSectionLines;
		
		public IniSection(string sectionName)
		{			
			CheckSectionName(sectionName);
			name = sectionName;
			values = new Dictionary<string,IniKeyValuePairLine>();
			iniSectionLines = new List<IIniLine>();
		}
		
		private static void CheckSectionName(string sectionName)
		{
			if (sectionName == null)
			{
				throw new ArgumentException("sectionName cannot be null");
			}
			
			sectionName = sectionName.Trim();
			
			if (sectionName == "")
			{
				throw new ArgumentException("sectionName cannot be an empty string");
			}
		}

		/// <value>
		/// Gets the name of the INI section, as written between the square brackets
		/// </value>
		public string Name
		{
			get
			{
				return name;
			}
		}

		/// <value>
		/// Gets an array of the keys of all of the <see cref=" IniKeyValuePairLine"/>s in the <code>IniSection</code>
		/// </value>
		public string[] Keys
		{
			get
			{
				int valCount = values.Count;
				string[] col = new string[valCount];
				
				if (valCount > 0)
				{
					values.Keys.CopyTo(col, 0);
				}
				
				return col;
			}
		}
		
		/// <value>
		/// Gets an <see cref=" IniKeyValuePairLine"/> by key, or <code>null</code> if the key doesn't exist
		/// </value>
		public IniKeyValuePairLine this[string key]
		{
			get
			{	
				IniKeyValuePairLine keyValuePair = null;
				values.TryGetValue(key.Trim(), out keyValuePair);				
				return keyValuePair;
			}
		}

		/// <summary>
		/// Adds an <see cref=" IIniLine"/> to the <code>IniSection</code>. If <code>iniLine</code> is also an <see cref=" IniKeyValuePairLine"/>
		/// then it becomes available through <code>this[key]</code>.
		/// <p>
		/// Throws a <see cref=" DuplicateIniException"/> if the line is a <see cref=" IniKeyValuePairLine"/> and the key already exists
		/// </summary>
		public void AddIniLine(IIniLine iniLine)
		{
			if (iniLine is IniKeyValuePairLine)
			{
				IniKeyValuePairLine keyValuePair = (IniKeyValuePairLine)iniLine;
				string key = keyValuePair.Key;
				
				if (!values.ContainsKey(key))
				{
					values.Add(key, keyValuePair);
				}
				else
				{
					throw new DuplicateIniLineException(Name, key);
				}
			}
			
			iniSectionLines.Add(iniLine);
		}

		public IEnumerator<IIniLine> GetEnumerator()
		{
			return iniSectionLines.GetEnumerator();
		}

		IEnumerator IEnumerable.GetEnumerator()
        {
            return iniSectionLines.GetEnumerator();
        }
		
		public override string ToString()
		{
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.Append("[");
			stringBuilder.Append(Name);
			stringBuilder.Append("]\n");

			foreach (IIniLine iniLine in this)
			{
				stringBuilder.Append(iniLine.ToString());
				stringBuilder.Append("\n");
			}

			stringBuilder.Append("\n");			
			return stringBuilder.ToString().Trim();
		}

	}
}