public INIDataItem this[String index] { get { INIDataItem returnthis = getValues().FirstOrDefault((w) => w.Name.Equals(index, StringComparison.OrdinalIgnoreCase)); if (returnthis == null) { //returnthis = new INISection(index, null, new List<INIItem>()); returnthis = new INIDataItem(index, "", this); INIItems.Add(returnthis); } return(returnthis); } set { //remove any existing value with the given name... INIItem itemfound = getValues().FirstOrDefault(w => w.Name.Equals(index, StringComparison.OrdinalIgnoreCase)); if (itemfound != null) { INIItems.Remove(itemfound); } INIItems.Add(value); } }
public IEnumerable <INIDataItem> getValues() { foreach (INIItem loopitem in INIItems) { INIDataItem casted = loopitem as INIDataItem; if (casted != null) { yield return(casted); } } }
public INIDataItem this[String index, String defaultvalue] { get { INIDataItem returnthis = getValues().FirstOrDefault((w) => w.Name.Equals(index, StringComparison.OrdinalIgnoreCase)); if (returnthis == null) { returnthis = new INIDataItem(index, defaultvalue, this); } return(returnthis); } }
public override bool TrySetMember(SetMemberBinder binder, object value) { //if it is a dataitem, set it directly. if (value is INIDataItem) { this[binder.Name] = (INIDataItem)value; return(true); } else if (value is Tuple <String, Object> ) { Tuple <String, Object> theTuple = (Tuple <String, Object>)value; INIDataItem getitem = this[binder.Name]; getitem.Name = theTuple.Item1; getitem.Value = theTuple.Item2.ToString(); return(true); } else if (value is Tuple <String, String> ) { Tuple <String, Object> theTuple = (Tuple <String, Object>)value; INIDataItem getitem = this[binder.Name]; getitem.Name = theTuple.Item1; getitem.Value = theTuple.Item2.ToString(); return(true); } else if (value is KeyValuePair <String, Object> ) { //Allow a KeyValuePair<String,Object> to be passed to set Name and Value. KeyValuePair <String, Object> castedval = (KeyValuePair <String, Object>)value; INIDataItem getitem = this[binder.Name]; getitem.Name = castedval.Key; getitem.Value = castedval.Value.ToString(); return(true); } else if (value is KeyValuePair <String, String> ) { //Allow a KeyValuePair<String,String> to be passed to set Name and Value. KeyValuePair <String, String> castedval = (KeyValuePair <String, String>)value; INIDataItem getitem = this[binder.Name]; getitem.Name = castedval.Key; getitem.Value = castedval.Value; return(true); } else { this[binder.Name].Value = value.ToString(); return(true); } }
public void LoadINI(StreamReader fromstream) { String currentline = null; Sections = new List <INISection>(); INISection globalsection = new INISection("cINIFilecsGlobals", "", new List <INIItem>(), this); INISection currentSection = globalsection; //while there is still text to read. while ((currentline = fromstream.ReadLine()) != null) { //trim the read in line... currentline = currentline.Trim(); //if it starts with a square bracket, it's a section. if (currentline.StartsWith("[")) { //parse out the section name... String newsectionname = currentline.Substring(1, currentline.IndexOf(']') - 1); String eolComment = ""; if (currentline.IndexOf(';') > -1) { eolComment = currentline.Substring(currentline.IndexOf(';')); } currentSection = new INISection(newsectionname, eolComment, new List <INIItem>(), this); Sections.Add(currentSection); } else if (currentline.StartsWith(";")) { //add a new Comment INIItem to the current section. INIItem newitem = new INIComment(currentline); currentSection.INIItems.Add(newitem); } else { INIDataItem createitem = ParseINIValue(currentline, currentSection); if (createitem != null) { currentSection.INIItems.Add(createitem); //createitem.OwnerSection=currentSection; } } } if (globalsection.INIItems.Count() > 0) { Sections.Add(globalsection); } }
/// <summary> /// Logical inverse of the getValue routine... a bit faster to implement... /// </summary> /// <typeparam name="T">Type of the parameter being set</typeparam> /// <param name="dataitem">INIDataItem class instance</param> /// <param name="newvalue">New value to set.</param> /// <remarks> /// The SetValue Extension method will save the object to the INI value. This is achieved by converting the object to a String. /// If the object doesn't have a static TryParse() method, but implements the ISerializable interface, the routine will use a BinaryFormatter /// to serialize the object, and then take that byte stream and create a Base64 encoded string from it, and set that as the value. /// If the class type implements a static TryParse() routine, however, the routine will simply use .ToString() on the given reference and save that. /// </remarks> public static void SetValue <T>(this INIDataItem dataitem, T newvalue) { //if T implements ISerializable and doesn't have a TryParse, we'll serialize to a //Base64 string, and save that instead. if (Base64Applicable <T>()) { String useb64 = SerializeToBase64((ISerializable)newvalue); dataitem.Value = useb64; } else { dataitem.Value = newvalue.ToString(); } }
public static void SetValue <T>(this INIDataItem dataitem) { dataitem.SetValue <T>(default(T)); }
//extensions for INIDataItem //normally, INIDataItem is a Name/Value Pair; More Specifically, because of the way INI files are, they are //naturally typeless. However, most configuration options are mapped to a different type by the application. //and I've found it to be a gigantic pain to have to write the same TryParse() handling code over and over. //so I added these handy extensions to the INIDataItem class, which provide some functions for setting. //I keep them out of the main code simply because that way it doesn't clutter it up. It's already cluttered enough as-is. /// <summary> /// Attempts to use Convert.ChangeType() to change the Value of this INIDataItem to the specified type parameter. /// If this fails, it will attempt to call a static "TryParse(String, out T)" method on the generic type parameter. /// If THAT fails, it will return the passed in DefaultValue parameter. /// </summary> /// <typeparam name="T">Parameter Type to retrieve and act on in Static context.</typeparam> /// <param name="dataitem">INIDataItem instance whose value is to be parsed to the given type.</param> /// <param name="DefaultValue">Default value to return</param> /// <returns>Result of the parse/Conversion, or the passed in DefaultValue</returns> public static T GetValue <T>(this INIDataItem dataitem, T DefaultValue) { //first check if it is a Type that uses Base64... if (Base64Applicable <T>()) { // T grabvalue = DeserializeFromBase64<T>(dataitem.Value); //sigh, darn constraints... now we need to use reflection to create and invoke the generic method with our type T. var Searchmethods = typeof(INItemValueExtensions).GetMethods(); foreach (MethodInfo iteratemethod in Searchmethods) { if (iteratemethod.Name.Equals("DeserializeFromBase64", StringComparison.OrdinalIgnoreCase)) { MethodInfo DeserializeMethod = iteratemethod.MakeGenericMethod(typeof(T)); //now, invoke it... T grabvalue = (T)DeserializeMethod.Invoke(null, BindingFlags.Static | BindingFlags.InvokeMethod, null, new object[] { dataitem.Value }, null); return(grabvalue); } } } //Generic method, attempts to call a static "TryParse" argument on the given class type, passing in the dataitem's value. try { return((T)Convert.ChangeType(dataitem.Value, typeof(T))); } catch (Exception ece) { //attempt to call TryParse. on the static class type. //TryParse(String, out T) Type usetype = typeof(T); T result = default(T); Object[] passparams = new object[] { dataitem.Value, result }; try { MethodInfo TryParseMethod = null; foreach (MethodInfo iteratemember in usetype.GetMethods()) { if (iteratemember.Name.Equals("TryParse", StringComparison.OrdinalIgnoreCase)) { TryParseMethod = iteratemember; break; } } if (TryParseMethod != null) { bool tpresult = (bool)TryParseMethod.Invoke(result, BindingFlags.InvokeMethod, null, passparams, Thread.CurrentThread.CurrentCulture); if (tpresult) { //tryparse succeeded! return((T)passparams[1]); //second index was out parameter... } else { return(DefaultValue); } } else { return(DefaultValue); } } catch (Exception xx) { //curses... return(DefaultValue); } } return(DefaultValue); }
public void LoadINI(StreamReader fromstream) { String currentline = null; Sections = new List <INISection>(); INISection globalsection = new INISection("cINIFilecsGlobals", "", new List <INIItem>(), this); INISection currentSection = globalsection; //while there is still text to read. while ((currentline = fromstream.ReadLine()) != null) { //trim the read in line... currentline = currentline.Trim(); if (currentline.StartsWith("$")) { //Special metacommand. String Metacommand = currentline.Substring(1); String CommandName = Metacommand.Substring(0, Metacommand.IndexOf(' ')); String parameter = Metacommand.Substring(CommandName.Length + 1); if (parameter.StartsWith("\"") && parameter.EndsWith("\"")) { parameter = parameter.Substring(1, parameter.Length - 2); } ProcessMetacommand(CommandName, parameter); } else if (currentline.StartsWith("[")) { //if it starts with a square bracket, it's a section. //parse out the section name... String newsectionname = currentline.Substring(1, currentline.IndexOf(']') - 1); String eolComment = ""; if (currentline.IndexOf(';') > -1) { eolComment = currentline.Substring(currentline.IndexOf(';')); } //Added May 2012: What if we have duplicates of the same section? coalesce them :P. //we first see if there is a section with this name. var foundsection = Sections.Find((w) => w.Name.ToUpper() == newsectionname.ToUpper()); if (foundsection != null) { currentSection = foundsection; //set to the existing section. //add to it's comment. why not. currentSection.eolComment += eolComment.Substring(1); } else { currentSection = new INISection(newsectionname, eolComment, new List <INIItem>(), this); } Sections.Add(currentSection); } else if (currentline.StartsWith(";")) { //add a new Comment INIItem to the current section. INIItem newitem = new INIComment(currentline); currentSection.INIItems.Add(newitem); } else { INIDataItem createitem = ParseINIValue(currentline, currentSection); if (createitem != null) { INIDataItem found = null; //look for an existing item in the current section. if (null != (found = (INIDataItem)(currentSection.INIItems.Find((t) => (t is INIDataItem && ((INIDataItem)t).Name.ToUpper() == createitem.Name.ToUpper()))))) { //set the value of found. found.Value = createitem.Value; } else { currentSection.INIItems.Add(createitem); //createitem.OwnerSection=currentSection; } } } } if (globalsection.INIItems.Count() > 0) { Sections.Add(globalsection); } }