using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using Yaulw.Tools;
using Yaulw.Win32;
using System.Diagnostics;
namespace Yaulw.File
{
///
/// Responsible for Reading and Writing an INI File.
/// Simply construct an INIFile Object passing in a File name and Path,
/// as well as an enum that lists all the Categories and Keys.
///
/// An example *You can mix and match Categories and Keys as needed *:
/// public enum INICatsNKeys
/// {
/// App_Settings__Load_XML_At_StartUp,
/// App_Settings__Allow_Command_Line_to_override_INI,
/// App_Settings__Default_User,
/// App_Settings__Default_Server,
/// Runtime_Debug__Error_Debug_Level,
/// Data_Access__Read_Only,
/// Settings__Program_Folder,
/// Settings__User1_Default,
/// Recent_File_List__File1,
/// Recent_File_List__File2,
/// Recent_File_List__File3,
/// Recent_File_List__File4,
/// }
///
/// The '__' Character signifies a category to Key change
/// the '_' will be replaced by ' ', when actually writing to the Ini File.
///
public class INIFile
{
#region Private Members
private string _IniPathNFileName = String.Empty;
private Type _IniKeysNCategories = null;
#endregion
#region Construction
///
/// Initialize an INIFile object with a valid path and FileName to write/read from.
/// Also pass in an Enum Type that contains Category and Key Information. This Enum will be used
/// to read and write to the INIFile (to determine which Section/Key to read/write from/to)
///
/// Pass in the full file name and path to use * Creates Directory, if it does not exits *
/// Pass in an Enum that specifies the Categories and Keys
/// Thrown if an invalid Enum is passed in via IniKeysNCategories
public INIFile(string IniPathNFileName, Type IniKeysNCategories)
{
// Check and ensure Enum Accuracy
if (IniKeysNCategories.IsEnum && EnumTool.EnumType_HasCategoryNKey(IniKeysNCategories))
{
_IniKeysNCategories = IniKeysNCategories;
}
else
throw new ArgumentException("IniKeysNCategories is not an Enum or not all Enums contain Key and Category Information");
// Ensure Directory Existence
if (!Directory.Exists(Path.GetDirectoryName(IniPathNFileName)))
Directory.CreateDirectory(Path.GetDirectoryName(IniPathNFileName));
_IniPathNFileName = IniPathNFileName;
}
#endregion
#region Public Properties
///
/// Ini File Used by IniFile
///
public string IniFile { get { return _IniPathNFileName; } }
#endregion
#region Public Ini Key Reader / Writer Functions
///
/// Use this to directly set a key to any string value
///
/// Specify Key and category set Directly
/// value to set
/// If cKey is not a valid Category/Key Pair Enum
public void SetKeyValue(Enum cKey, T Value)
{
if (EnumTool.Enum_HasCategoryNKey(cKey))
{
string Category;
string Key;
EnumTool.Enum_ToCategoryNKey(cKey, out Category, out Key);
string ValueStr = ObjTool.ConvertObjToString(Value);
SetKeyValueString(Category, Key, ValueStr);
}
else
{
throw new ArgumentException("cKey must have both Category and Key Information");
}
}
///
/// Use this to directly retrieve a key
///
/// Specify Key and category set Directly
/// default value to return, if not found
/// value retrieved or default value
/// If cKey is not a valid Category/Key Pair Enum
public T GetKeyValue(Enum cKey, T defaultValue)
{
try
{
if (EnumTool.Enum_HasCategoryNKey(cKey))
{
string Category;
string Key;
EnumTool.Enum_ToCategoryNKey(cKey, out Category, out Key);
// Get Key and verify that something was found
string defaultValueStr = ObjTool.ConvertObjToString(defaultValue);
string KeyValue = GetKeyValueString(Category, Key, defaultValueStr);
bool bHasAValue = (KeyValue.Trim().Length != 0);
// always write the value back out to ini
SetKeyValue(cKey, bHasAValue ? KeyValue : defaultValueStr);
// Return value
if (bHasAValue)
{
return ObjTool.ConvertStringToObj(KeyValue);
}
else
{
return defaultValue;
}
}
else
{
throw new ArgumentException("cKey must have both Category and Key Information");
}
}
catch (Exception) { /* ignore */ }
return defaultValue;
}
#endregion
#region Private Generic Ini Key Reader / Writer Functions
///
/// Set a value for the specified Key and for the specified category
///
/// specify category
/// specify key
/// specify a value to set
private void SetKeyValueString(string category, string key, string value)
{
bool bSuccess = Kernel32.WritePrivateProfileString(category, key, value, IniFile);
Debug.Assert(bSuccess);
}
///
/// Retrieve the value for a specified Key and for a specified category
///
/// specify category
/// specify key
/// specify default value, returned when no value found
/// the value for the Key, or default value if no value found
private string GetKeyValueString(string category, string key, string defaultValue)
{
StringBuilder returnString = new StringBuilder(1024);
Kernel32.GetPrivateProfileString(category, key, defaultValue, returnString, 1024, IniFile);
return returnString.ToString().Split('\0')[0];
}
#endregion
#region Private Generic Ini File Readers (Not Used)
///
/// Use this to return all the categories in an INI File
///
/// a list with Gategory Items, or 0 length list is none found
private List GetAllCategories()
{
StringBuilder returnString = new StringBuilder(65536);
uint returnValue = Kernel32.GetPrivateProfileString(null, null, null, returnString, 65536, IniFile);
List result = new List(returnString.ToString().Split('\0'));
result.RemoveRange(result.Count - 2, 2);
return result;
}
///
/// Use this to return the Keys from a category from an INI File
///
/// a list with Key Items, or 0 length list is none found
private List GetAllKeysInCategory(string category)
{
StringBuilder returnString = new StringBuilder(32768);
Kernel32.GetPrivateProfileString(category, null, null, returnString, 32768, IniFile);
List result = new List(returnString.ToString().Split('\0'));
result.RemoveRange(result.Count - 2, 2);
return result;
}
#endregion
}
}