view IniSection.cs @ 10:848e7b151d3c

Re #17 - Make INI section names and keys case insensitive * Add ToLower() when adding sections and lines to dictionaries * Add ToLower() when getting sections and lines from dictionaries
author IBBoard <dev@ibboard.co.uk>
date Thu, 26 Mar 2009 20:12:07 +0000
parents 5b0052b5585f
children
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, either version 3 of the License or (at your option) any later version. 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().ToLower(), 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.ToLower();
				
				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();
		}
		
		/// <summary>
		/// Gets the value from a given key-value pair in this section. If ethe key does not exist in the section then NULL will be returned. 
		/// If the key exists in the section then its corresponding value will be returned.
		/// </summary>
		/// <param name="lineKey">
		/// The key for the <code>IniKeyValuePairLine</code> within the <code>IniSection</code> to get the value for
		/// </param>
		/// <returns>
		/// The value for the key in the section, or NULL if the key does not exist
		/// </returns>
		public string GetLineValue(string lineKey)
		{
			IniKeyValuePairLine line = this[lineKey];
			return (line == null ? null : line.Value);;
		}
		
		/// <summary>
		/// Gets the value from a given key-value pair in a given section. If the key does not exist in the section then <code>defaultValue</code>
		/// will be returned. If the key exists in the section then its corresponding value will be returned.
		/// </summary>
		/// <param name="lineKey">
		/// The key for the <code>IniKeyValuePairLine</code> within the <code>IniSection</code> to get the value for
		/// </param>
		/// <param name="defaultValue">
		/// The default value to return if the key does not exist
		/// </param>
		/// <returns>
		/// The value for the key in the section, or NULL if the key does not exist
		/// </returns>
		public string GetLineValue(string lineKey, string defaultValue)
		{
			string lineValue = GetLineValue(lineKey);
			return (lineValue == null ? defaultValue : lineValue);
		}
	}
}