/// <summary> /// Include or just save fileName into current KeyValues Class /// </summary> /// <returns> /// true if the sucessfully include file (KeyValue is valid); otherwise, false. /// </returns> /// <param name="fileName">File to include on current KeyValues Class</param> /// <param name="loadToKeyValues">if true will load file and in current KeyValues Class; otherwise false.</param> /// <param name="addToList"> /// if true on save KeyValues to HDD will put a #include macro for the fileName on correct place; /// otherwise false. /// </param> public bool AddIncludeFile(string fileName, bool loadToKeyValues, bool addToList) { if (addToList) { if (!ExistsInclude(fileName)) { IncludedFiles.Add(fileName); } } if (loadToKeyValues) { var incKv = new KeyValues("include"); if (!incKv.LoadFromFile(fileName)) { return(false); } /*incKv.FirstParent = Parent == null ? this : Parent.FirstParent; * incKv.Parent = this; * incKv.DistanceFromTop = DistanceFromTop + 1;*/ Update(incKv, true); KeyChilds.Add(incKv); } return(true); }
public bool RemoveSubKey(KeyValues pSubkey) { if (!KeyChilds.Remove(pSubkey)) { return(false); } Update(pSubkey, false); return(true); }
/// <summary> /// Add a SubKey to the current KeyValues /// </summary> /// <param name="pSubkey">KeyValue to Append.</param> public void AddSubKey(KeyValues pSubkey) { if (!pSubkey.IsValid()) { return; } Update(pSubkey, true); KeyChilds.Add(pSubkey); }
public bool RemoveSubKey(int index) { try { KeyChilds.RemoveAt(index); Update(KeyChilds[index], false); return(true); } catch (ArgumentOutOfRangeException) { return(false); } }
/// <summary> /// Serves as a hash function for a particular type. <see cref="M:System.Object.GetHashCode"></see> is suitable for use /// in hashing algorithms and data structures like a hash table. /// </summary> /// <returns> /// A hash code for the current <see cref="T:System.Object"></see>. /// </returns> /// <filterpriority>2</filterpriority> public override int GetHashCode() { // Getting hash codes from volatile variables doesn't seem a good move... //TODO Find an immutable way? var result = Name?.GetHashCode() ?? 0; result = (result * 397) ^ (KeyNameValues?.GetHashCode() ?? 0); result = (result * 397) ^ (KeyChilds?.GetHashCode() ?? 0); result = (result * 397) ^ (FirstParent?.GetHashCode() ?? 0); result = (result * 397) ^ (Parent?.GetHashCode() ?? 0); result = (result * 397) ^ NextSubKeyIndex.GetHashCode(); result = (result * 397) ^ NextKeyValueIndex.GetHashCode(); result = (result * 397) ^ DistanceFromTop.GetHashCode(); return(result); }
/// <summary> /// Serves as a hash function for a particular type. <see cref="M:System.Object.GetHashCode"></see> is suitable for use in hashing algorithms and data structures like a hash table. /// </summary> /// <returns> /// A hash code for the current <see cref="T:System.Object"></see>. /// </returns> /// <filterpriority>2</filterpriority> public override int GetHashCode() { unchecked { int result = (Name != null ? Name.GetHashCode() : 0); result = (result * 397) ^ (KeyNameValues != null ? KeyNameValues.GetHashCode() : 0); result = (result * 397) ^ (KeyChilds != null ? KeyChilds.GetHashCode() : 0); result = (result * 397) ^ (FirstParent != null ? FirstParent.GetHashCode() : 0); result = (result * 397) ^ (Parent != null ? Parent.GetHashCode() : 0); result = (result * 397) ^ NextSubKeyIndex.GetHashCode(); result = (result * 397) ^ NextKeyValueIndex.GetHashCode(); result = (result * 397) ^ DistanceFromTop.GetHashCode(); return(result); } }
public KeyValues FindKey(string keyName, bool create) { foreach (var t in KeyChilds.Where(t => t.Name == keyName)) { return(t); } if (!create) { return(null); } var newKv = new KeyValues(keyName) { FirstParent = Parent == null ? this : Parent.FirstParent, Parent = this, DistanceFromTop = DistanceFromTop + 1 }; return(newKv); }
/// <summary> /// Create a KeyValue from List wich contains file lines /// </summary> /// <returns> /// true if the sucessfully load (KeyValue is valid); otherwise, false. /// </returns> /// <param name="stream">List collection wich contain file lines</param> /// <param name="startPos">Start parse List in that position</param> /// <param name="endPos">Return end position index</param> private bool LoadFromList(List <string> stream, uint startPos, ref uint endPos) { if (stream == null) { return(false); } bool wasQuoted = false; bool wasComment = false; string lastComment = null; bool wasName = false; endPos = 0; for (uint i = startPos; i < stream.Count; i++) { KeyValuePair <string, string> kvPair = ReadToken(stream[(int)i], ref wasQuoted, ref wasComment); if (string.IsNullOrEmpty(kvPair.Key)) { continue; } endPos = i; // Is the end of KeyValues Class? if (kvPair.Key == "}") { endPos = i + 1; return(Name == null ? false : true); } // This line is a comment if (wasComment) { lastComment = kvPair.Value; continue; } // KeyValue Name not yet seted! if (!wasName) { if (!string.IsNullOrEmpty(kvPair.Value)) { return(false); } Name = kvPair.Key; if (!string.IsNullOrEmpty(lastComment)) { Comment = lastComment; } wasName = true; lastComment = null; uint beganIndex = RetriveIndex(stream, "{", i + 1); if (beganIndex == 0) { return(false); } i = beganIndex; continue; } // Begin a new KeyValue Class if (kvPair.Key == "{") { if (!wasQuoted) { lastComment = null; KeyValues kvChild = new KeyValues("NewName"); if (!kvChild.LoadFromList(stream, i - 1, ref endPos)) { continue; } Update(kvChild, true); KeyChilds.Add(kvChild); if (endPos >= stream.Count) { return(true); } i = endPos; continue; } } // Is a KeyValue "Key" "Value" if (string.IsNullOrEmpty(kvPair.Value)) { continue; } KeyValuesData kvData = new KeyValuesData(kvPair.Key, kvPair.Value, lastComment, this); KeyNameValues.Add(kvData); lastComment = null; } return(true); }
/// <summary> /// Check if exists a SubKey under that KeyValues Class /// </summary> /// <returns> /// true if exists; otherwise, false. /// </returns> /// <param name="subKeyName">SubKey Name to check.</param> public bool ExistsSubKey(string subKeyName) { return(KeyChilds.Any(t => t.Name == subKeyName)); }
/// <summary> /// Create a KeyValue from List wich contains file lines /// </summary> /// <returns> /// true if the sucessfully load (KeyValue is valid); otherwise, false. /// </returns> /// <param name="stream">List collection wich contain file lines</param> /// <param name="startPos">Start parse List in that position</param> /// <param name="endPos">Return end position index</param> private bool LoadFromList(List <string> stream, uint startPos, ref uint endPos) { if (stream == null) { return(false); } string lastComment = null; var wasName = false; endPos = 0; for (var i = startPos; i < stream.Count; i++) { bool wasQuoted; bool wasComment; var kvPair = ReadToken(stream[(int)i], out wasQuoted, out wasComment); if (string.IsNullOrEmpty(kvPair.Key)) { continue; } endPos = i; // Is the end of KeyValues Class? if (kvPair.Key == "}") { endPos = i + 1; return(Name != null); } // This line is a comment if (wasComment) { lastComment = kvPair.Value; continue; } // KeyValue Name not yet seted! if (!wasName) { if (!string.IsNullOrEmpty(kvPair.Value)) { return(false); } Name = kvPair.Key; if (!string.IsNullOrEmpty(lastComment)) { Comment = lastComment; } wasName = true; lastComment = null; var beganIndex = RetriveIndex(stream, "{", i + 1); if (beganIndex == 0) { return(false); } i = beganIndex; continue; } // special include macro (not a key name) if (kvPair.Key.StartsWith("#include") && !wasQuoted) { lastComment = null; if (string.IsNullOrEmpty(kvPair.Value)) { continue; } AddIncludeFile(kvPair.Value, true, true); continue; } // Begin a new KeyValue Class if (kvPair.Key == "{") { if (!wasQuoted) { lastComment = null; var kvChild = new KeyValues("NewName"); if (!kvChild.LoadFromList(stream, i - 1, ref endPos)) { continue; } Update(kvChild, true); KeyChilds.Add(kvChild); if (endPos >= stream.Count) { return(true); } i = endPos; continue; } } // Is a KeyValue "Key" "Value" if (string.IsNullOrEmpty(kvPair.Value)) { continue; } var kvData = new KeyValuesData(kvPair.Key, kvPair.Value, lastComment, this); KeyNameValues.Add(kvData); lastComment = null; } return(true); }