Last active
August 6, 2019 14:32
-
-
Save markcastle/324cb4fa03048404ee1ecbac5174a7b5 to your computer and use it in GitHub Desktop.
Extremely fast Json encoder for c# with no dependancies (except StringBuilder).
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Copyright 2017, 2018, 2019 Captive Reality Ltd - All Rights Reserved | |
* Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is | |
* hereby granted, provided that the above copyright notice and this permission notice appear in all copies. | |
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE | |
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE | |
* FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM | |
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, | |
* ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |
* | |
* Source: https://gist.github.com/markcastle/324cb4fa03048404ee1ecbac5174a7b5 | |
* | |
* Description: | |
* Extremely fast Json encoder for c# with no dependancies (except StringBuilder). | |
* This is not a json parser. | |
* We can also automatically do some auto escaping. | |
* Written by Mark Castle <mark.castle@captivereality.com>, July 2017 | |
* | |
* Usage: | |
* | |
* Utils.Json json = new Utils.Json(); | |
* json.Add("App", "AppName"); | |
* json.Add("Integer1", intVariable1); | |
* json.Add("Integer2", intVariable2); | |
* json.Add("Integer3", intVariable3); | |
* return json.toString(); | |
* | |
* Changelog: | |
* 26/07/2017 - Created by MC | |
* | |
* references: | |
* | |
*/ | |
using System; | |
using System.Text; | |
namespace CaptiveReality.Utils | |
{ | |
/// <summary> | |
/// Very fast Json builder utility. | |
/// Builds JSON only (eg, Cannot Parse Json) | |
/// </summary> | |
public class Json | |
{ | |
StringBuilder _json = new StringBuilder(); | |
/// <summary> | |
/// Constructor | |
/// </summary> | |
public Json() | |
{ | |
} | |
/// <summary> | |
/// Add a string value | |
/// </summary> | |
/// <param name="name"></param> | |
/// <param name="value"></param> | |
public void AddJson(string name, string value) | |
{ | |
if (_json.Length != 0) | |
{ | |
_json.Append(","); | |
} | |
_json.Append("\"").Append(name).Append("\":").Append(value); | |
} | |
public void Append(string jsonToAppend) | |
{ | |
if (_json.Length != 0) | |
{ | |
_json.Append(","); | |
} | |
_json.Append(jsonToAppend); | |
} | |
/// <summary> | |
/// Merge a json string with our existing json. | |
/// </summary> | |
/// <param name="jsonToMerge"></param> | |
public void Merge(string jsonToMerge) | |
{ | |
if (_json.Length != 0) | |
{ | |
_json.Append(","); | |
} | |
_json.Append(jsonToMerge.TrimStart('{').TrimEnd('}')); | |
} | |
/// <summary> | |
/// Add a float | |
/// Converts floats using zero decimal places. Possibly not what is wanted for most normal use, but it is what I want for memory bytes. | |
/// </summary> | |
/// <param name="name"></param> | |
/// <param name="value"></param> | |
public void Add(string name, float value) | |
{ | |
if (_json.Length != 0) | |
{ | |
_json.Append(","); | |
} | |
_json.Append("\"").Append(name).Append("\":").Append(value.ToString("{0:0.#######}")); | |
} | |
/// <summary> | |
/// Add an integer value | |
/// </summary> | |
/// <param name="name"></param> | |
/// <param name="value"></param> | |
public void Add(string name, int value) | |
{ | |
if (_json.Length != 0) | |
{ | |
_json.Append(","); | |
} | |
_json.Append("\"").Append(name).Append("\":").Append(value.ToString()); | |
} | |
/// <summary> | |
/// Add Json | |
/// </summary> | |
/// <param name="name"></param> | |
/// <param name="value"></param> | |
public void Add(string name, Json value) | |
{ | |
if (_json.Length != 0) | |
{ | |
_json.Append(","); | |
} | |
_json.Append("\"").Append(name).Append("\":").Append(value.toString()); | |
} | |
/// <summary> | |
/// Add string with auto escaping | |
/// </summary> | |
/// <param name="name"></param> | |
/// <param name="value"></param> | |
/// <param name="cleanForJson"></param> | |
public void Add(string name, string value, bool cleanForJson = true) | |
{ | |
if (_json.Length != 0) | |
{ | |
_json.Append(","); | |
} | |
_json.Append("\"").Append(name).Append("\":").Append("\"").Append((cleanForJson ? escapeForJson(value) : value)).Append("\""); | |
} | |
/// <summary> | |
/// Add a bool | |
/// </summary> | |
/// <param name="name"></param> | |
/// <param name="value"></param> | |
public void Add(string name, bool value) | |
{ | |
if (_json.Length != 0) | |
{ | |
_json.Append(","); | |
} | |
_json.Append("\"").Append(name).Append("\":").Append((value ? "true" : "false")); | |
} | |
/// <summary> | |
/// Clear everything | |
/// </summary> | |
public void Clear() | |
{ | |
_json = new StringBuilder(); | |
} | |
/// <summary> | |
/// Convert to a string | |
/// </summary> | |
/// <returns></returns> | |
public string toString() | |
{ | |
return "{" + _json.ToString() + "}"; | |
} | |
/// <summary> | |
/// Return the string builder representation | |
/// </summary> | |
/// <returns></returns> | |
public StringBuilder toStringBuilder() | |
{ | |
return _json; | |
} | |
/// <summary> | |
/// Append | |
/// </summary> | |
/// <param name="jsonToAppend"></param> | |
public void Append(StringBuilder jsonToAppend) | |
{ | |
if (_json.Length != 0) | |
{ | |
_json.Append(","); | |
} | |
_json.Append(jsonToAppend); | |
} | |
/// <summary> | |
/// Auto string escaping | |
/// </summary> | |
/// <param name="s"></param> | |
/// <returns></returns> | |
public static string escapeForJson(string s) | |
{ | |
if (s == null || s.Length == 0) | |
{ | |
return ""; | |
} | |
char c = '\0'; | |
int i; | |
int len = s.Length; | |
StringBuilder sb = new StringBuilder(len + 4); | |
string t; | |
for (i = 0; i < len; i += 1) | |
{ | |
c = s[i]; | |
switch (c) | |
{ | |
case '\\': | |
case '"': | |
sb.Append('\\'); | |
sb.Append(c); | |
break; | |
case '/': | |
sb.Append('\\'); | |
sb.Append(c); | |
break; | |
case '\b': | |
sb.Append("\\b"); | |
break; | |
case '\t': | |
sb.Append("\\t"); | |
break; | |
case '\n': | |
sb.Append("\\n"); | |
break; | |
case '\f': | |
sb.Append("\\f"); | |
break; | |
case '\r': | |
sb.Append("\\r"); | |
break; | |
default: | |
if (c < ' ') | |
{ | |
t = "000" + String.Format("X", c); | |
sb.Append("\\u" + t.Substring(t.Length - 4)); | |
} | |
else | |
{ | |
sb.Append(c); | |
} | |
break; | |
} | |
} | |
return sb.ToString(); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment