|
| 1 | +/* |
| 2 | + * [2012-06-09 First Version] |
| 3 | + * - provides strongly typed node classes and lists / dictionaries |
| 4 | + * - provides easy access to class members / array items / data values |
| 5 | + * - the parser now properly identifies types. So generating JSON with this framework should work. |
| 6 | + * - only double quotes (") are used for quoting strings. |
| 7 | + * - provides "casting" properties to easily convert to / from those types: |
| 8 | + * int / float / double / bool |
| 9 | + * - provides a common interface for each node so no explicit casting is required. |
| 10 | + * - the parser tries to avoid errors, but if malformed JSON is parsed the result is more or less undefined |
| 11 | + * - It can serialize/deserialize a node tree into/from an experimental compact binary format. It might |
| 12 | + * be handy if you want to store things in a file and don't want it to be easily modifiable |
| 13 | + * |
| 14 | + * [2012-12-17 Update] |
| 15 | + * - Added internal JSONLazyCreator class which simplifies the construction of a JSON tree |
| 16 | + * Now you can simple reference any item that doesn't exist yet and it will return a JSONLazyCreator |
| 17 | + * The class determines the required type by it's further use, creates the type and removes itself. |
| 18 | + * - Added binary serialization / deserialization. |
| 19 | + * - Added support for BZip2 zipped binary format. Requires the SharpZipLib ( http://www.icsharpcode.net/opensource/sharpziplib/ ) |
| 20 | + * The usage of the SharpZipLib library can be disabled by removing or commenting out the USE_SharpZipLib define at the top |
| 21 | + * - The serializer uses different types when it comes to store the values. Since my data values |
| 22 | + * are all of type string, the serializer will "try" which format fits best. The order is: int, float, double, bool, string. |
| 23 | + * It's not the most efficient way but for a moderate amount of data it should work on all platforms. |
| 24 | + * |
| 25 | + * [2017-03-08 Update] |
| 26 | + * - Optimised parsing by using a StringBuilder for token. This prevents performance issues when large |
| 27 | + * string data fields are contained in the json data. |
| 28 | + * - Finally refactored the badly named JSONClass into JSONObject. |
| 29 | + * - Replaced the old JSONData class by distict typed classes ( JSONString, JSONNumber, JSONBool, JSONNull ) this |
| 30 | + * allows to propertly convert the node tree back to json without type information loss. The actual value |
| 31 | + * parsing now happens at parsing time and not when you actually access one of the casting properties. |
| 32 | + * |
| 33 | + * [2017-04-11 Update] |
| 34 | + * - Fixed parsing bug where empty string values have been ignored. |
| 35 | + * - Optimised "ToString" by using a StringBuilder internally. This should heavily improve performance for large files |
| 36 | + * - Changed the overload of "ToString(string aIndent)" to "ToString(int aIndent)" |
| 37 | + * |
| 38 | + * [2017-11-29 Update] |
| 39 | + * - Removed the IEnumerator implementations on JSONArray & JSONObject and replaced it with a common |
| 40 | + * struct Enumerator in JSONNode that should avoid garbage generation. The enumerator always works |
| 41 | + * on KeyValuePair<string, JSONNode>, even for JSONArray. |
| 42 | + * - Added two wrapper Enumerators that allows for easy key or value enumeration. A JSONNode now has |
| 43 | + * a "Keys" and a "Values" enumerable property. Those are also struct enumerators / enumerables |
| 44 | + * - A KeyValuePair<string, JSONNode> can now be implicitly converted into a JSONNode. This allows |
| 45 | + * a foreach loop over a JSONNode to directly access the values only. Since KeyValuePair as well as |
| 46 | + * all the Enumerators are structs, no garbage is allocated. |
| 47 | + * - To add Linq support another "LinqEnumerator" is available through the "Linq" property. This |
| 48 | + * enumerator does implement the generic IEnumerable interface so most Linq extensions can be used |
| 49 | + * on this enumerable object. This one does allocate memory as it's a wrapper class. |
| 50 | + * - The Escape method now escapes all control characters (# < 32) in strings as uncode characters |
| 51 | + * (\uXXXX) and if the static bool JSONNode.forceASCII is set to true it will also escape all |
| 52 | + * characters # > 127. This might be useful if you require an ASCII output. Though keep in mind |
| 53 | + * when your strings contain many non-ascii characters the strings become much longer (x6) and are |
| 54 | + * no longer human readable. |
| 55 | + * - The node types JSONObject and JSONArray now have an "Inline" boolean switch which will default to |
| 56 | + * false. It can be used to serialize this element inline even you serialize with an indented format |
| 57 | + * This is useful for arrays containing numbers so it doesn't place every number on a new line |
| 58 | + * - Extracted the binary serialization code into a seperate extension file. All classes are now declared |
| 59 | + * as "partial" so an extension file can even add a new virtual or abstract method / interface to |
| 60 | + * JSONNode and override it in the concrete type classes. It's of course a hacky approach which is |
| 61 | + * generally not recommended, but i wanted to keep everything tightly packed. |
| 62 | + * - Added a static CreateOrGet method to the JSONNull class. Since this class is immutable it could |
| 63 | + * be reused without major problems. If you have a lot null fields in your data it will help reduce |
| 64 | + * the memory / garbage overhead. I also added a static setting (reuseSameInstance) to JSONNull |
| 65 | + * (default is true) which will change the behaviour of "CreateOrGet". If you set this to false |
| 66 | + * CreateOrGet will not reuse the cached instance but instead create a new JSONNull instance each time. |
| 67 | + * I made the JSONNull constructor private so if you need to create an instance manually use |
| 68 | + * JSONNull.CreateOrGet() |
| 69 | + * |
| 70 | + * [2018-01-09 Update] |
| 71 | + * - Changed all double.TryParse and double.ToString uses to use the invariant culture to avoid problems |
| 72 | + * on systems with a culture that uses a comma as decimal point. |
| 73 | + * |
| 74 | + * [2018-01-26 Update] |
| 75 | + * - Added AsLong. Note that a JSONNumber is stored as double and can't represent all long values. However |
| 76 | + * storing it as string would work. |
| 77 | + * - Added static setting "JSONNode.longAsString" which controls the default type that is used by the |
| 78 | + * LazyCreator when using AsLong |
| 79 | + * |
| 80 | + * [2018-04-25 Update] |
| 81 | + * - Added support for parsing single values (JSONBool, JSONString, JSONNumber, JSONNull) as top level value. |
| 82 | + * |
| 83 | + * [2019-02-18 Update] |
| 84 | + * - Added HasKey(key) and GetValueOrDefault(key, default) to the JSONNode class to provide way to read |
| 85 | + * values conditionally without creating a LazyCreator |
| 86 | + * |
| 87 | + * [2019-03-25 Update] |
| 88 | + * - Added static setting "allowLineComments" to the JSONNode class which is true by default. This allows |
| 89 | + * "//" line comments when parsing json text as long as it's not within quoted text. All text after // up |
| 90 | + * to the end of the line is completely ignored / skipped. This makes it easier to create human readable |
| 91 | + * and editable files. Note that stripped comments are not read, processed or preserved in any way. So |
| 92 | + * this feature is only relevant for human created files. |
| 93 | + * - Explicitly strip BOM (Byte Order Mark) when parsing to avoid getting it leaked into a single primitive |
| 94 | + * value. That's a rare case but better safe than sorry. |
| 95 | + * - Allowing adding the empty string as key |
| 96 | + * |
| 97 | + * [2019-12-10 Update] |
| 98 | + * - Added Clone() method to JSONNode to allow cloning of a whole node tree. |
| 99 | + * |
| 100 | + */ |
0 commit comments