Insanely huge initial commit

This commit is contained in:
2026-02-21 17:04:05 -08:00
parent 9cdd36191a
commit 613d75914a
22525 changed files with 4035207 additions and 0 deletions

View File

@@ -0,0 +1,101 @@
// CreateStringRunner
using System;
using System.Text;
using UnityEngine;
namespace Leguar.TotalJSON.Internal {
class CreateStringRunner {
private CreateStringSettings settings;
private StringBuilder builder;
private string indentString;
private int currentIndent;
private string newLineString;
internal CreateStringRunner(CreateStringSettings settings) {
this.settings = settings;
builder=new StringBuilder();
if (settings.HumanReadable) {
if (settings.IndentUsingTab) {
indentString="\t";
} else {
indentString=new string(' ',settings.IndentSpaceCount);
}
currentIndent=0;
}
newLineString=getNewLineString();
}
internal void append(char chr) {
builder.Append(chr);
}
internal void append(char chr, bool space) {
builder.Append(chr);
if (space && settings.HumanReadable) {
builder.Append(' ');
}
}
internal void append(string str) {
builder.Append(str);
}
internal void append(char chr1, char chr2) {
builder.Append(chr1);
if (settings.HumanReadable) {
builder.Append(' ');
}
builder.Append(chr2);
}
internal void append(char chr, int indentChange) {
builder.Append(chr);
if (settings.HumanReadable) {
builder.Append(newLineString);
currentIndent += indentChange;
for (int n = 0; n<currentIndent; n++) {
builder.Append(indentString);
}
}
}
internal void append(int indentChange, char chr) {
if (settings.HumanReadable) {
builder.Append(newLineString);
currentIndent += indentChange;
for (int n = 0; n<currentIndent; n++) {
builder.Append(indentString);
}
}
builder.Append(chr);
}
internal bool isEscapeForwardSlashes() {
return settings.EscapeForwardSlashes;
}
internal string getFinalString() {
return builder.ToString();
}
private string getNewLineString() {
if (settings.NewLine==CreateStringSettings.NewLineTypes.EnvironmentDefault) {
return Environment.NewLine;
} else if (settings.NewLine==CreateStringSettings.NewLineTypes.LF) {
return "\n";
} else if (settings.NewLine==CreateStringSettings.NewLineTypes.CR_LF) {
return "\r\n";
} else {
Debug.LogError("Leguar.TotalJSON: CreateStringRunner.getNewLine(): Internal error: Unspecified new line type");
return Environment.NewLine;
}
}
}
}

View File

@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 69184000601c75749b791c0d9be41e44
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 9f2fdab21a6aeaf41956a4d04ddf4dd2
folderAsset: yes
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,204 @@
// JSONRuntimeDebug
using UnityEngine;
using UnityEditor;
using System.Collections.Generic;
namespace Leguar.TotalJSON.Internal {
public class JSONRuntimeDebug : EditorWindow {
private static int selected=0;
private static List<DebugObject> latestObjects;
private static bool previousWasPlaying = false;
[MenuItem("Window/Total JSON/JSON Runtime Debug")]
static void Init() {
JSONRuntimeDebug window=(JSONRuntimeDebug)(GetWindow(typeof(JSONRuntimeDebug)));
#if UNITY_5 || UNITY_2017
window.titleContent = new GUIContent("JSON Runtime Debug");
#else
Texture2D icon = (Texture2D)(AssetDatabase.LoadAssetAtPath("Assets/TotalJSON/Internal/Editor/window-icon.png", typeof(Texture2D)));
window.titleContent = new GUIContent("JSON Runtime Debug",icon);
#endif
}
void OnGUI() {
GUILayout.Space(15);
if (!Application.isPlaying) {
if (latestObjects==null) {
GUILayout.Label("Application is not running. This debug is available only when application is running and some JSON/Jarray object is added to debug.");
} else {
GUILayout.Label("Application is not running. Below is last state of JSON/Jarray objects from previous run.");
if (previousWasPlaying) {
foreach (DebugObject latestObject in latestObjects) {
latestObject.refresh();
}
}
outputLatestContent();
}
previousWasPlaying=false;
return;
} else {
previousWasPlaying=true;
}
JSONRuntimeDebugContainer jsonRuntimeDebugContainer=null;
GameObject jsonDebugObject=GameObject.Find("TotalJSON_DebugObject");
if (jsonDebugObject!=null) {
jsonRuntimeDebugContainer=jsonDebugObject.GetComponent<JSONRuntimeDebugContainer>();
}
if (jsonRuntimeDebugContainer==null) {
GUILayout.Label("Application is running but no JSON objects are added to debug.");
latestObjects=null;
return;
}
GUILayout.Label("Application is running, choose object below to show.");
if (latestObjects==null) {
latestObjects=new List<DebugObject>();
}
Dictionary<string,JValue> currentContent=jsonRuntimeDebugContainer.getContent();
foreach (string key in currentContent.Keys) {
int listIndex=getDebugObjectIndex(key);
if (listIndex>=0) {
if (latestObjects[listIndex].getValue()!=currentContent[key]) {
latestObjects[listIndex].replace(currentContent[key]);
}
} else {
latestObjects.Add(new DebugObject(key,currentContent[key]));
}
}
outputLatestContent();
}
private int getDebugObjectIndex(string key) {
for (int n=0; n<latestObjects.Count; n++) {
if (latestObjects[n].getKey().Equals(key)) {
return n;
}
}
return -1;
}
private void outputLatestContent() {
GUILayout.Space(10);
int count=latestObjects.Count;
string[] keys=new string[latestObjects.Count];
for (int n=0; n<count; n++) {
keys[n]=latestObjects[n].getKey();
}
int newSelected=GUILayout.Toolbar(selected,keys);
if (newSelected!=selected) {
selected=newSelected;
GUIUtility.keyboardControl=0;
GUIUtility.hotControl=0;
}
GUILayout.Space(10);
EditorGUILayout.BeginHorizontal();
GUILayout.Label(latestObjects[selected].getInfoString());
if (Application.isPlaying) {
GUILayout.FlexibleSpace();
if (GUILayout.Button("Refresh")) {
latestObjects[selected].refresh();
Repaint();
}
}
EditorGUILayout.EndHorizontal();
GUILayout.Space(5);
latestObjects[selected].scrollPos = EditorGUILayout.BeginScrollView(latestObjects[selected].scrollPos);
EditorGUILayout.TextArea(latestObjects[selected].getContentString(),GUILayout.ExpandHeight(true));
EditorGUILayout.EndScrollView();
}
private class DebugObject {
private string key;
private JValue value;
internal Vector2 scrollPos;
private string infoString;
private string contentString;
internal DebugObject(string key, JValue value) {
this.key=key;
this.value=value;
refresh();
}
internal void replace(JValue value) {
this.value=value;
refresh();
}
internal void refresh() {
scrollPos=Vector2.zero;
infoString=null;
contentString=null;
}
internal string getKey() {
return key;
}
internal JValue getValue() {
return value;
}
internal string getInfoString() {
if (infoString==null) {
infoString=value.ToString();
if (isProtected()) {
infoString+=" -- This object is set protected (read only)";
}
}
return infoString;
}
internal string getContentString() {
if (contentString==null) {
contentString=value.CreateString(new CreateStringSettings() { HumanReadable=true });
}
return contentString;
}
private bool isProtected() {
if (value is JSON) {
return ((JSON)(value)).IsProtected();
}
if (value is JArray) {
return ((JArray)(value)).IsProtected();
}
return false;
}
}
}
}

View File

@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: dd472f7a2d8907c4fa13cc27c68a39f4
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,192 @@
// JSONValidator
using UnityEngine;
using UnityEditor;
using System;
using System.Text;
using Leguar.TotalJSON;
namespace Leguar.TotalJSON.Internal {
public class JSONValidator : EditorWindow {
private string editorAreaText="Write or copy&paste JSON object or JSON array to this text area. Example JSON:\n\n{\"name\":\"Player\",\"lastLogin\":123456789012,\"achievements\":[42,1337,1703],\"imageUrl\":null,\"have_bought\":true,\"levels\":[{\"passed\":true,\"score\":12345},{\"passed\":false}]}\n\nExtra texts like this before or after JSON object will be removed when clicking button below.";
private string message="";
private string tightJSON="";
private string escapedJSON="";
private Vector2 scrollPos;
private float lineHeight=EditorGUIUtility.singleLineHeight;
[MenuItem("Window/Total JSON/JSON Validator")]
static void Init() {
JSONValidator window=(JSONValidator)(GetWindow(typeof(JSONValidator)));
#if UNITY_5 || UNITY_2017
window.titleContent = new GUIContent("JSON Validator");
#else
Texture2D icon = (Texture2D)(AssetDatabase.LoadAssetAtPath("Assets/TotalJSON/Internal/Editor/window-icon.png", typeof(Texture2D)));
window.titleContent = new GUIContent("JSON Validator",icon);
#endif
}
void OnGUI() {
GUILayout.Space(20);
scrollPos = EditorGUILayout.BeginScrollView(scrollPos);
EditorGUI.BeginChangeCheck();
editorAreaText = EditorGUILayout.TextArea(editorAreaText,GUILayout.ExpandHeight(true));
bool changes = EditorGUI.EndChangeCheck();
EditorGUILayout.EndScrollView();
if (changes) {
message = "";
tightJSON = "";
escapedJSON = "";
}
GUILayout.Space(10);
if (GUILayout.Button("Trim, validate and prettify above JSON object or array")) {
string trimmedEditorText=editorAreaText.Trim();
if (trimmedEditorText.Length<editorAreaText.Length) {
editorAreaText=trimmedEditorText; // Needed in case of errors, so that line numbers will match
GUIUtility.keyboardControl=0;
GUIUtility.hotControl=0;
EditorUtility.SetDirty(this);
}
if (string.IsNullOrEmpty(trimmedEditorText)) {
message = "Input is empty";
tightJSON = "";
escapedJSON = "";
} else {
object objectOrError = findAndGetJSONOrJArray(trimmedEditorText);
if (objectOrError==null) {
message = "Can't find JSON start from input";
tightJSON = "";
escapedJSON = "";
} else if (objectOrError is string) {
message = "Invalid input: "+((string)(objectOrError));
tightJSON = "";
escapedJSON = "";
} else {
CreateStringSettings prettySettings=new CreateStringSettings() {
HumanReadable=true,
IndentUsingTab=true,
NewLine=CreateStringSettings.NewLineTypes.LF // \r characters (may be part of environment default) seem to be problem in editor textarea, causing invisible linefeeds, so using plain \n
};
if (objectOrError is JSON[]) {
JSON[] jsons = (JSON[])(objectOrError);
if (jsons.Length==1) {
message = "JSON is valid. Top level JSON key/value pair count = "+jsons[0].Count;
editorAreaText = jsons[0].CreateString(prettySettings)+"\n";
tightJSON = jsons[0].CreateString(new CreateStringSettings() { HumanReadable = false });
escapedJSON = "\""+getEscapedString(tightJSON)+"\"";
} else {
message = "JSONs are valid. JSON object count = "+jsons.Length;
editorAreaText = "";
tightJSON = "";
for (int n = 0; n<jsons.Length; n++) {
editorAreaText += jsons[n].CreateString(prettySettings)+"\n";
if (n<jsons.Length-1) {
editorAreaText += '\n';
}
tightJSON += jsons[n].CreateString(new CreateStringSettings() { HumanReadable = false });
}
escapedJSON = "\""+getEscapedString(tightJSON)+"\"";
}
} else {
JArray jArray = (JArray)(objectOrError);
message = "JSON Array is valid. Top level array length = "+jArray.Length;
editorAreaText = jArray.CreateString(prettySettings)+"\n";
tightJSON = jArray.CreateString(new CreateStringSettings() { HumanReadable = false });
escapedJSON = "\""+getEscapedString(tightJSON)+"\"";
}
GUIUtility.keyboardControl=0;
GUIUtility.hotControl=0;
EditorUtility.SetDirty(this);
}
}
}
GUILayout.Space(20);
GUILayout.Label(message);
GUILayout.Space(20);
EditorGUI.BeginDisabledGroup(tightJSON.Length==0);
GUILayout.Label("JSON formatted and encoded string ("+tightJSON.Length+" bytes):");
GUILayout.Space(5);
EditorGUILayout.SelectableLabel(tightJSON,EditorStyles.textField,GUILayout.Height(lineHeight+2));
GUILayout.Space(15);
GUILayout.Label("Above string with escapes (to be used for example directly in c# source code):");
GUILayout.Space(5);
EditorGUILayout.SelectableLabel(escapedJSON,EditorStyles.textField,GUILayout.Height(lineHeight+2));
GUILayout.Space(20);
EditorGUI.EndDisabledGroup();
}
private object findAndGetJSONOrJArray(string dirtySourceString) {
// Remove any heading "trash", for example in case that JSON is pasted from Unity Console
int jsonStartIndex=dirtySourceString.IndexOf('{');
int jArrayStartIndex=dirtySourceString.IndexOf('[');
// Debug.Log("jsonStartIndex = "+jsonStartIndex);
// Debug.Log("jArrayStartIndex = "+jArrayStartIndex);
// Nothing?
if (jsonStartIndex<0 && jArrayStartIndex<0) {
return null;
}
// Try parse array
if (jArrayStartIndex>=0 && (jArrayStartIndex<jsonStartIndex || jsonStartIndex<0)) {
try {
return JArray.ParseString(dirtySourceString,new ParseStringSettings(){ ParseStartIndex=jArrayStartIndex, AllowNonWhiteCharactersAfterObject=true });
}
catch (ParseException e) {
if (jsonStartIndex<0) {
return e.Message;
}
}
}
// Parse one or more JSONs
try {
return JSON.ParseStringToMultiple(dirtySourceString,new ParseStringSettings(){ ParseStartIndex=jsonStartIndex, AllowNonWhiteCharactersAfterObject=true });
}
catch (ParseException e) {
return e.Message;
}
}
private static string getEscapedString(string source) {
int length=source.Length;
StringBuilder sb=new StringBuilder(length);
for (int n=0; n<length; n++) {
if (source[n]=='"') {
sb.Append('\\');
sb.Append('"');
} else if (source[n]=='\\') {
sb.Append('\\');
sb.Append('\\');
} else {
sb.Append(source[n]);
}
}
return sb.ToString();
}
}
}

View File

@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 9a3e3d053758ae04d8a800e805da99ba
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

After

Width:  |  Height:  |  Size: 271 B

View File

@@ -0,0 +1,123 @@
fileFormatVersion: 2
guid: 7de077ad9b723ed40b5ae6d8a8320274
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 12
mipmaps:
mipMapMode: 0
enableMipMap: 1
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
vTOnly: 0
ignoreMasterTextureLimit: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: -3
maxTextureSize: 32
textureSettings:
serializedVersion: 2
filterMode: 1
aniso: 16
mipBias: 0
wrapU: 1
wrapV: 1
wrapW: 1
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 1
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 8
textureShape: 1
singleChannelComponent: 0
flipbookRows: 1
flipbookColumns: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
ignorePngGamma: 0
applyGammaDecoding: 1
cookieLightType: 1
platformSettings:
- serializedVersion: 3
buildTarget: DefaultTexturePlatform
maxTextureSize: 32
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 0
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Standalone
maxTextureSize: 32
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 0
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Server
maxTextureSize: 32
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 0
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID: 5e97eb03825dee720800000000000000
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
nameFileIdTable: {}
spritePackingTag:
pSDRemoveMatte: 0
pSDShowRemoveMatteOption: 0
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,353 @@
// InternalTools
using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.Reflection;
#if UNITY_EDITOR
using UnityEngine;
#endif
namespace Leguar.TotalJSON.Internal {
class InternalTools {
internal static JValue objectAsJValue(object value) {
List<object> stack = new List<object>();
return objectAsJValue(value, stack);
}
private static JValue objectAsJValue(object value, List<object> stack) {
// Single object?
JValue jValue=singleObjectAsJValue(value);
if (jValue!=null) {
return jValue;
}
// Dictionary
if (value is IDictionary) {
return dictionaryToJSON((IDictionary)(value), new JSON(), stack);
}
// List/array
if (value is IList) {
return listToJArray((IList)(value), new JArray(), stack);
}
// Unknown, handled by caller
return null;
}
internal static JSON dictionaryToJSON(IDictionary sourceDictionary, JSON targetJSON, List<object> stack) {
stack.Add(sourceDictionary);
foreach (object objectKey in sourceDictionary.Keys) {
if (objectKey==null) { // Dictionary can't have null keys though because calculating hash wouldn't work? No harm to check anyway
throw (new JArgumentException("Dictionary 'key' can not be null", "sourceDictionary"));
}
if (!(objectKey is string)) {
throw (new JArgumentException("Key have to be string in JSON.<init>(IDictionary) constructor", "sourceDictionary"));
}
string stringKey = (string)(objectKey);
object objectValue = sourceDictionary[objectKey];
if (stack.Contains(objectValue)) {
throw (new JArgumentException("Dictionary value is referring to earlier object. This would cause circular JSON.", "sourceDictionary[\""+stringKey+"\"]"));
}
JValue jValue = InternalTools.objectAsJValue(objectValue, stack);
if (jValue==null) {
throw (new UnknownObjectTypeException(objectValue, "sourceDictionary[\""+stringKey+"\"]"));
}
targetJSON.Add(stringKey, jValue);
}
stack.Remove(sourceDictionary);
return targetJSON;
}
internal static JArray listToJArray(IList sourceList, JArray targetJArray, List<object> stack) {
stack.Add(sourceList);
for (int n = 0; n<sourceList.Count; n++) {
object listItem = sourceList[n];
if (stack.Contains(listItem)) {
throw (new JArgumentException("List item is referring to earlier object. This would cause circular JSON.", "sourceList["+n+"]"));
}
JValue jValue = InternalTools.objectAsJValue(listItem, stack);
if (jValue==null) {
throw (new UnknownObjectTypeException(listItem, "sourceList["+n+"]"));
}
targetJArray.Add(jValue);
}
stack.Remove(sourceList);
return targetJArray;
}
internal static JValue serializeObject(object obj, SerializeSettings serializeSettings) {
List<object> stack = new List<object>();
return serializeObject(obj, serializeSettings, stack);
}
// This never returns null
private static JValue serializeObject(object obj, SerializeSettings serializeSettings, List<object> stack) {
JValue singleValue=singleObjectAsJValue(obj);
if (singleValue!=null) {
return singleValue;
}
if (obj is IList) {
JArray jArray = new JArray();
IList list = (IList)(obj);
stack.Add(obj);
for (int n=0; n<list.Count; n++) {
object listItem = list[n];
if (stack.Contains(listItem)) {
throw (new SerializeException("List item is referring to earlier object. This would cause circular JSON.", listItem));
}
JValue jValue=serializeObject(listItem, serializeSettings, stack);
if (jValue==null) {
throw (new SerializeException("List item is type that can't be serialized", listItem));
}
jArray.Add(jValue);
}
stack.Remove(obj);
return jArray;
}
Type type = obj.GetType();
if (type.IsGenericType) {
if (type.GetGenericTypeDefinition()==typeof(Dictionary<,>)) {
JSON json = new JSON();
Type[] dictTypes = type.GetGenericArguments();
bool dictKeyIsString = (dictTypes[0]==typeof(string));
if (!serializeSettings.AllowNonStringDictionaryKeys && !dictKeyIsString) {
throw (new SerializeException("Dictionary key is type ('"+dictTypes[0]+"') that can't be serialized. Dictionary keys must be strings, or allow more loose options using SerializeSettings"));
}
IDictionary dict = (IDictionary)(obj);
stack.Add(obj);
foreach (object objectKey in dict.Keys) {
object dictionaryValue = dict[objectKey];
if (stack.Contains(dictionaryValue)) {
throw (new SerializeException("Dictionary value is referring to earlier object. This would cause circular JSON.", dictionaryValue));
}
JValue jValue = serializeObject(dictionaryValue, serializeSettings, stack);
if (jValue==null) {
throw (new SerializeException("Dictionary item is type that can't be serialized", dictionaryValue));
}
string stringKey;
if (dictKeyIsString) {
stringKey = (string)(objectKey);
} else {
stringKey = objectKey.ToString();
}
json.Add(stringKey, jValue);
}
stack.Remove(obj);
return json;
}
}
JSON jsonSer = new JSON();
FieldInfo[] fieldInfos = obj.GetType().GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
stack.Add(obj);
foreach (FieldInfo fieldInfo in fieldInfos) {
if (isSerializing(fieldInfo, serializeSettings.IgnoreSystemAndUnitySerializeAttributes)) {
string fieldName = fieldInfo.Name;
object fieldToSerialize = fieldInfo.GetValue(obj);
if (stack.Contains(fieldToSerialize)) {
throw (new SerializeException("Class field is referring to earlier object. This would cause circular JSON.", fieldToSerialize));
}
JValue jValue = serializeObject(fieldToSerialize, serializeSettings, stack);
if (jValue==null) {
throw (new SerializeException("Field \""+fieldName+"\" is type that can't be serialized",fieldToSerialize));
}
jsonSer.Add(fieldName,jValue);
}
}
stack.Remove(obj);
return jsonSer;
}
internal static bool isSerializing(FieldInfo fieldInfo, bool ignoreNonJSONSpecificAttributes) {
object[] attributes = fieldInfo.GetCustomAttributes(false);
if (containsType(attributes,typeof(ExcludeFromJSONSerializeAttribute))) {
return false;
}
if (!ignoreNonJSONSpecificAttributes) {
if (containsType(attributes,typeof(System.NonSerializedAttribute))) {
return false;
}
}
if (fieldInfo.IsPublic && !fieldInfo.IsLiteral) {
return true;
}
if (containsType(attributes,typeof(IncludeToJSONSerializeAttribute))) {
return true;
}
if (!ignoreNonJSONSpecificAttributes) {
if (containsType(attributes,typeof(UnityEngine.SerializeField))) {
return true;
}
}
return false;
}
private static bool containsType(object[] attributes, Type type) {
foreach (object attribute in attributes) {
if (attribute.GetType()==type) {
return true;
}
}
return false;
}
private static JValue singleObjectAsJValue(object value) {
// Null
if (value==null) {
return (new JNull());
}
// JValue directly
if (value is JValue) {
return ((JValue)(value));
}
// Known numbers
if (value is float) {
return (new JNumber((float)(value)));
}
if (value is double) {
return (new JNumber((double)(value)));
}
if (value is decimal) {
return (new JNumber((decimal)(value)));
}
if (value is byte) {
return (new JNumber((byte)(value)));
}
if (value is sbyte) {
return (new JNumber((sbyte)(value)));
}
if (value is short) {
return (new JNumber((short)(value)));
}
if (value is ushort) {
return (new JNumber((ushort)(value)));
}
if (value is int) {
return (new JNumber((int)(value)));
}
if (value is uint) {
return (new JNumber((uint)(value)));
}
if (value is long) {
return (new JNumber((long)(value)));
}
if (value is ulong) {
return (new JNumber(((ulong)(value)).ToString(CultureInfo.InvariantCulture)));
}
// String
if (value is string) {
return (new JString((string)(value)));
}
// Bool
if (value is bool) {
return (new JBoolean((bool)(value)));
}
// Unknown, handled by caller
return null;
}
internal static object jValueAsSystemObject(JValue jValue) {
if (jValue is JSON) {
return ((JSON)(jValue)).AsDictionary();
} else if (jValue is JArray) {
return ((JArray)(jValue)).AsList();
} else if (jValue is JNumber) {
return ((JNumber)(jValue)).AsObject();
} else if (jValue is JString) {
return ((JString)(jValue)).AsString();
} else if (jValue is JBoolean) {
return ((JBoolean)(jValue)).AsBool();
} else { // JNull
return null;
}
}
internal static string getExceptionMessageTailForID(string debugIDForExceptions, string exceptionSource) {
if (debugIDForExceptions!=null) {
return (" - "+exceptionSource+" Debug ID: \""+debugIDForExceptions+"\"");
}
return "";
}
internal static string getCleanedStackTrace(string originalStackTrace) {
string cleanedStackTrace=originalStackTrace;
bool first=true;
do {
int lf=getLineFeedIndex(cleanedStackTrace);
if (lf<=0) {
if (first) {
// This is unexpected, just returning original stacktrace as fallback
return originalStackTrace;
} else {
return cleanedStackTrace;
}
}
first=false;
if (!isInternalStackTraceLine(cleanedStackTrace.Substring(0,lf))) {
return cleanedStackTrace;
}
cleanedStackTrace=cleanedStackTrace.Substring(lf+1);
} while (true);
}
private static int getLineFeedIndex(string source) {
int i=source.IndexOf('\n');
return i;
}
private static bool isInternalStackTraceLine(string str) {
int packegeName=str.IndexOf("Leguar.TotalJSON.");
if (packegeName<0) {
return false;
}
int i1=str.IndexOf('(');
if (i1>0 && i1<packegeName) {
return false;
}
int i2=str.IndexOf('<');
if (i2>0 && i2<packegeName) {
return false;
}
return true;
}
#if UNITY_EDITOR
internal static JSONRuntimeDebugContainer getDebugContainer() {
GameObject jsonDebugObject = GameObject.Find("TotalJSON_DebugObject");
if (jsonDebugObject==null) {
jsonDebugObject=new GameObject("TotalJSON_DebugObject");
jsonDebugObject.hideFlags=HideFlags.HideInHierarchy;
GameObject.DontDestroyOnLoad(jsonDebugObject);
}
JSONRuntimeDebugContainer jsonRuntimeDebugContainer = jsonDebugObject.GetComponent<JSONRuntimeDebugContainer>();
if (jsonRuntimeDebugContainer==null) {
jsonRuntimeDebugContainer=jsonDebugObject.AddComponent<JSONRuntimeDebugContainer>();
}
return jsonRuntimeDebugContainer;
}
#endif
}
}

View File

@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 0993856fabc941a488b888d8a2c47eeb
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,40 @@
// TotalJSON - JSONRuntimeDebugContainer
#if UNITY_EDITOR
using UnityEngine;
using System.Collections.Generic;
namespace Leguar.TotalJSON.Internal {
public class JSONRuntimeDebugContainer : MonoBehaviour {
private Dictionary<string,JValue> content;
internal JSONRuntimeDebugContainer() {
content=new Dictionary<string, JValue>();
}
internal void add(string debugName, JValue jValue) {
foreach (string key in content.Keys) {
if (content[key]==jValue) {
if (key.Equals(debugName)) {
return; // Adding same object with same name, all done
}
content.Remove(key); // Remove previous one so that same object is not in debug twice (but this allows "changing name" of debugged object)
break;
}
}
content[debugName]=jValue;
}
public Dictionary<string, JValue> getContent() {
return content;
}
}
}
#endif

View File

@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 13a924cf4cad1d74197dc64bf37f9ca7
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,75 @@
// ParseStringRunner
namespace Leguar.TotalJSON.Internal {
class ParseStringRunner {
private ParseStringSettings settings;
private StringPointer stringPointer;
internal ParseStringRunner(string sourceString, ParseStringSettings settings) {
if (settings==null) {
settings = new ParseStringSettings();
}
this.settings = settings;
stringPointer=new StringPointer(sourceString,settings.ParseStartIndex,this);
}
internal StringPointer getStringPointer() {
return stringPointer;
}
internal bool containsNonWhiteChars() {
return stringPointer.containsNonWhiteChars();
}
internal string getPossiblyFixedNumber(string originalNumber) {
if (settings.FixRoundedFloatingPointMinMaxValues) {
string testNumber = originalNumber.Replace('e','E');
if (testNumber.Equals("3.402823E+38")) { // Rounded float.MaxValue
return "3.40282347E+38"; // Exact float.MaxValue
}
if (testNumber.Equals("-3.402823E+38")) { // Rounded float.MinValue
return "-3.40282347E+38"; // Exact float.MinValue
}
if (testNumber.Equals("1.79769313486232E+308")) { // Rounded double.MaxValue
return "1.7976931348623157E+308"; // Exact double.MaxValue (that doesn't throw OverflowException if read as double)
}
if (testNumber.Equals("-1.79769313486232E+308")) { // Rounded double.MinValue
return "-1.7976931348623157E+308"; // Exact double.MinValue (that doesn't throw OverflowException if read as double)
}
}
return originalNumber;
}
internal bool isAllowNonWhiteCharactersAfterObject() {
return settings.AllowNonWhiteCharactersAfterObject;
}
internal JValue parseValue() {
char chr=stringPointer.getNextNonWhiteChar();
if (chr=='"') {
return JString.zParse(this,false);
} else if (chr=='-' || (chr>='0' && chr<='9')) {
return JNumber.zParse(this,chr);
} else if (chr=='{') {
return JSON.zParse(this,false,false,false);
} else if (chr=='[') {
return JArray.zParse(this,false);
} else if (chr=='t' || chr=='f') {
return JBoolean.zParse(this,(chr=='t'));
} else if (chr=='n') {
return JNull.zParse(this);
} else {
throw ParseException.forInvalidCharacter("Invalid character '"+chr+"' when expecting start of any value",this);
}
}
internal string getParseDebugIDForExceptions() {
return settings.DebugIDForExceptions;
}
}
}

View File

@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 5eed20d76b51c3046ac7d57011b161d7
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,144 @@
// StringPointer
using System.Text;
namespace Leguar.TotalJSON.Internal {
class StringPointer {
private string str;
private int strLength;
private int nextChar;
// For debugging
private ParseStringRunner psrForDebug;
private char lastChr;
private int line;
private int col;
// For stepping back
private char sbLastChr;
private int sbLine;
private int sbCol;
// internal StringPointer(string str) : this(str,0) {
// }
internal StringPointer(string str, int startIndex, ParseStringRunner psrForDebug) {
this.str=str;
strLength=str.Length;
nextChar=startIndex;
this.psrForDebug = psrForDebug;
lastChr='\0';
line=1;
col=0;
}
internal bool containsNonWhiteChars() {
foreach (char chr in str) {
if (!isWhiteChar(chr)) {
return true;
}
}
return false;
}
internal bool tryGetNextNonWhiteChar(out char chr) {
do {
if (nextChar>=strLength) {
chr=default(char);
return false;
}
chr=getNextChar();
} while (isWhiteChar(chr));
return true;
}
internal char getNextNonWhiteChar() {
char chr;
do {
chr=getNextChar();
} while (isWhiteChar(chr));
return chr;
}
internal char getNextChar() {
if (nextChar>=strLength) {
throw ParseException.forInvalidEnd(psrForDebug);
}
sbLastChr=lastChr;
sbLine=line;
sbCol=col;
char chr=str[nextChar];
nextChar++;
if (chr=='\n' || chr=='\r') {
if ((chr=='\n' && lastChr!='\r') || (chr=='\r' && lastChr!='\n')) {
line++;
col=0;
}
} else {
col++;
}
lastChr=chr;
return chr;
}
internal bool isNextChars(string sequence) {
foreach (char chr in sequence) {
if (getNextChar()!=chr) {
return false;
}
}
return true;
}
internal int getCurrentIndex() {
return nextChar;
}
internal void stepBack() {
nextChar--;
lastChr=sbLastChr;
line=sbLine;
col=sbCol;
}
internal string getSubStringStartingFrom(int start) {
return str.Substring(start,nextChar-start);
}
internal string getLineAndColumnForException() {
return ("line "+line+", col "+col);
}
internal string getSubStringForException(int count) {
int start=nextChar-count;
if (start<0) {
count+=start;
start=0;
}
if (start+count>strLength) {
count=strLength-start;
}
if (count==0) {
return "";
}
StringBuilder sb=new StringBuilder();
if (start>0) {
sb.Append("...");
}
sb.Append(str.Substring(start,count));
if (start+count<strLength) {
sb.Append("...");
}
return sb.ToString();
}
private bool isWhiteChar(char chr) {
return (chr==' ' || chr=='\t' || chr=='\n' || chr=='\r');
}
}
}

View File

@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 2077e5258f6b9ce43be7c1406c16aa4f
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: