/// <summary> /// Defaults data to the section (IE, sets it if not present!) /// </summary> /// <param name="key">The key to set data from.</param> /// <param name="data">The key to set data to.</param> public void DefaultData(string key, FDSData data) { int lind = key.LastIndexOf(SectionPathSplit); if (lind < 0) { if (GetRootData(key) == null) { SetRootData(key, data); } return; } if (lind == key.Length - 1) { throw new FDSInputException("Invalid SetData key: Ends in a path splitter!"); } FDSSection sec = GetSectionInternal(key.Substring(0, lind), false, false); string k = key.Substring(lind + 1); if (sec.GetRootData(k) == null) { sec.SetRootData(k, data); } }
/// <summary> /// Gets an optional ulong from the section. /// Returns def if not found. /// </summary> /// <param name="key">The key to get data from.</param> /// <param name="def">The default object.</param> /// <returns>The data found, or the default.</returns> public ulong?GetUlong(string key, ulong?def = null) { FDSData got = GetData(key); if (got == null) { return(def); } object o = got.Internal; if (o is ulong oul) { return(oul); } else if (o is uint oui) { return(oui); } else { if (ulong.TryParse(o.ToString(), out ulong ul)) { return(ul); } return(def); } }
/// <summary> /// Gets an optional long from the section. /// Returns def if not found. /// </summary> /// <param name="key">The key to get data from.</param> /// <param name="def">The default object.</param> /// <returns>The data found, or the default.</returns> public long?GetLong(string key, long?def = null) { FDSData got = GetData(key); if (got == null) { return(def); } object o = got.Internal; if (o is long) { return((long)o); } else if (o is int) { return((int)o); } else { if (long.TryParse(o.ToString(), out long l)) { return(l); } return(def); } }
/// <summary> /// Gets an optional double from the section. /// Returns def if not found. /// </summary> /// <param name="key">The key to get data from.</param> /// <param name="def">The default object.</param> /// <returns>The data found, or the default.</returns> public double?GetDouble(string key, double?def = null) { FDSData got = GetData(key); if (got == null) { return(def); } object o = got.Internal; if (o is double) { return((double)o); } else if (o is float) { return((float)o); } else { if (double.TryParse(o.ToString(), out double d)) { return(d); } return(def); } }
/// <summary> /// Gets an object from the section. /// Returns def if not found. /// </summary> /// <param name="key">The key to get data from.</param> /// <param name="def">The default object.</param> /// <returns>The data found, or the default.</returns> public object GetObject(string key, object def = null) { FDSData got = GetData(key); if (got == null) { return(def); } return(got.Internal); }
/// <summary> /// Converts this FDSSection to a textual representation of itself. /// </summary> /// <param name="tabulation">How many tabs to start with. Generally do not set this.</param> /// <param name="newline">What string to use as a new line. Generally do not set this.</param> /// <returns>The string.</returns> public string SaveToString(int tabulation = 0, string newline = null) { if (newline == null) { newline = "\n"; } StringBuilder sb = new StringBuilder(); foreach (string key in Data.Keys) { FDSData dat = Data[key]; foreach (string str in dat.PrecedingComments) { sb.Append('\t', tabulation); sb.Append("#").Append(str).Append(newline); } sb.Append('\t', tabulation); sb.Append(FDSUtility.EscapeKey(key)); if (dat.Internal is FDSSection) { sb.Append(":").Append(newline).Append(((FDSSection)dat.Internal).SaveToString(tabulation + 1, newline)); } else if (dat.Internal is byte[]) { sb.Append("= ").Append(dat.Outputable()).Append(newline); } else if (dat.Internal is List <FDSData> datums) { sb.Append(":").Append(newline); foreach (FDSData cdat in datums) { foreach (string com in cdat.PrecedingComments) { sb.Append('\t', tabulation); sb.Append("#").Append(com).Append(newline); } sb.Append('\t', tabulation); sb.Append("- ").Append(FDSUtility.Escape(cdat.Outputable())).Append(newline); } } else { sb.Append(": ").Append(FDSUtility.Escape(dat.Outputable())).Append(newline); } } return(sb.ToString()); }
/// <summary> /// Gets a string from the section. Can stringify non-string values. /// Returns def if not found. /// </summary> /// <param name="key">The key to get data from.</param> /// <param name="def">The default object.</param> /// <returns>The data found, or the default.</returns> public string GetString(string key, string def = null) { FDSData got = GetData(key); if (got == null) { return(def); } object o = got.Internal; if (o is string) { return((string)o); } else { return(o.ToString()); } }
/// <summary> /// Gets a bool from the section. /// Returns def if not found. /// </summary> /// <param name="key">The key to get data from.</param> /// <param name="def">The default object.</param> /// <returns>The data found, or the default.</returns> public bool?GetBool(string key, bool?def = null) { FDSData got = GetData(key); if (got == null) { return(def); } object o = got.Internal; if (o is bool) { return((bool)o); } else { return(o.ToString().ToLowerFast() == "true"); } }
/// <summary> /// Gets a string from the section. Can stringify non-string values. /// Returns null if not found. /// </summary> /// <param name="key">The key to get data from.</param> /// <returns>The data found, or the default.</returns> public List <FDSData> GetDataList(string key) { FDSData got = GetData(key); if (got == null) { return(null); } object o = got.Internal; if (o is List <FDSData> ) { return((List <FDSData>)o); } else { return(new List <FDSData>() { got }); } }
/// <summary> /// Gets a sub-section of this FDS section. /// </summary> /// <param name="key">The key of the section.</param> /// <param name="allowNull">Whether to allow null returns, otherwise enforce the section's existence. If true, can throw an FDSInputException!</param> /// <param name="lowered">Whether to read lowercase section names. If set, expects lowercased input key!</param> /// <returns>The subsection.</returns> private FDSSection GetSectionInternal(string key, bool allowNull, bool lowered) { if (key == null || key.Length == 0) { return(this); } string[] dat = key.SplitFast(SectionPathSplit); FDSSection current = this; for (int i = 0; i < dat.Length; i++) { FDSData fdat = lowered ? current.GetRootDataLowered(dat[i]) : current.GetRootData(dat[i]); if (fdat != null && fdat.Internal is FDSSection) { current = (FDSSection)fdat.Internal; } else { if (allowNull) { return(null); } if (fdat != null) { throw new FDSInputException("Key contains non-section contents!"); } FDSSection temp = new FDSSection(); current.SetRootData(dat[i], new FDSData() { Internal = temp, PrecedingComments = new List <string>() }); current = temp; } } return(current); }
/// <summary> /// Sets data direct on the root level. /// </summary> /// <param name="key">The key to set data to.</param> /// <param name="data">The data to read.</param> public void SetRootData(string key, FDSData data) { Data[key] = data; DataLowered[key.ToLowerFast()] = data; }