//Because of https://www.reddit.com/r/programming/comments/4v6chu/why_json_doesnt_support_comments_douglas_crockford/d5w343r using System; using System.Collections.Generic; using System.Text; using System.Collections; namespace BetterConfig { /// /// Provides loading and creation of human readable config files. /// public static class Config { /// /// Creates a configuration file /// /// Binary data /// First token /// Second token /// Configuration content public static string Save(byte[] Data, string Token0, string Token1) { StringBuilder OMG = new StringBuilder(); BitArray BA = new BitArray(Data); if (!CheckTokens(Token0, Token1)) { throw new ArgumentException("Tokens are ambiguous"); } foreach (bool b in BA) { OMG.Append(b ? Token1 : Token0); } return OMG.ToString(); } /// /// Loads a configuration file /// /// Configuration data /// First token /// Second token /// Binary Configuration public static byte[] Load(string Data, string Token0, string Token1) { return Load(Data, Token0, Token1, false); } /// /// Loads a configuration file /// /// Configuration data /// First token /// Second token /// Ignores invalid tokens in the file /// Binary Configuration public static byte[] Load(string Data, string Token0, string Token1, bool FilterInvalid) { List ConfigValues = new List(); bool[] Values = new bool[] { false, true }; byte[] Result; int Pos = 0; if (!CheckTokens(Token0, Token1)) { throw new ArgumentException("Tokens are ambiguous"); } //swap tokens if needed so we always check for the longer token first. //Also swap values then if (Token1.Length > Token0.Length) { var temp = Token0; Token0 = Token1; Token1 = temp; Values[0] = true; Values[1] = false; } while (Pos < Data.Length) { if (Data.IndexOf(Token0, Pos) == Pos) { ConfigValues.Add(Values[0]); Pos += Token0.Length; } else if (Data.IndexOf(Token1, Pos) == Pos) { ConfigValues.Add(Values[1]); Pos += Token1.Length; } else if (FilterInvalid) { ++Pos; } else { throw new ArgumentException("Data is not a valid configuration"); } } if (ConfigValues.Count % 8 != 0) { throw new ArgumentException("Data is not a valid configuration"); } Result = new byte[ConfigValues.Count / 8]; (new BitArray(ConfigValues.ToArray())).CopyTo(Result, 0); return Result; } /// /// Makes sure, tokens are unambiguous /// /// First token /// Second token /// true, if valid tokens public static bool CheckTokens(string Token0, string Token1) { //for tokens to be valid there are multiple conditions that all must be met: //- Neither token must be null or an empty string //- Tokens must not be identical //- A token must not be only made up of the other token multiple times if (string.IsNullOrEmpty(Token0) || string.IsNullOrEmpty(Token1) || Token0 == Token1 || Token0.Replace(Token1,"").Length==0 || Token1.Replace(Token0, "").Length == 0) { return false; } return true; } } }