private static object ParseAnonymousValue(string json) { if (json.Length == 0) { return(null); } if (json[0] == '{' && json[json.Length - 1] == '}') { var elems = JSONParser.Split(json); if (elems.Count % 2 != 0) { return(null); } var dict = new Dictionary <string, object>(elems.Count / 2); for (var i = 0; i < elems.Count; i += 2) { dict[elems[i].Substring(1, elems[i].Length - 2)] = JSONParser.ParseAnonymousValue(elems[i + 1]); } return(dict); } if (json[0] == '[' && json[json.Length - 1] == ']') { var items = JSONParser.Split(json); var finalList = new List <object>(items.Count); for (var i = 0; i < items.Count; i++) { finalList.Add(JSONParser.ParseAnonymousValue(items[i])); } return(finalList); } if (json[0] == '"' && json[json.Length - 1] == '"') { var str = json.Substring(1, json.Length - 2); return(str.Replace("\\", string.Empty)); } if (char.IsDigit(json[0]) || json[0] == '-') { if (json.Contains(".")) { double result; double.TryParse(json, System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out result); return(result); } else { int result; int.TryParse(json, out result); return(result); } } if (json == "true") { return(true); } if (json == "false") { return(false); } // handles json == "null" as well as invalid JSON return(null); }
internal static object ParseValue(Type type, string json) { { var resJson = json; if (resJson[0] == '"') { resJson = resJson.Substring(1, resJson.Length - 2); } foreach (var parser in ME.ECS.DataConfigGenerator.DataConfigGenerator.parsers) { if (parser.IsValid(type) == true) { try { if (parser.Parse(resJson, type, out var result) == true) { return(result); } //if (parser.Parse(data, componentType, fieldName, fieldType, out result) == true) return true; } catch (System.Exception ex) { UnityEngine.Debug.LogError($"Parser `{parser}` failed with exception: {ex.Message}"); } } } } if (type == typeof(string)) { if (json.Length <= 2) { return(string.Empty); } var parseStringBuilder = new StringBuilder(json.Length); for (var i = 1; i < json.Length - 1; ++i) { if (json[i] == '\\' && i + 1 < json.Length - 1) { var j = "\"\\nrtbf/".IndexOf(json[i + 1]); if (j >= 0) { parseStringBuilder.Append("\"\\\n\r\t\b\f/"[j]); ++i; continue; } if (json[i + 1] == 'u' && i + 5 < json.Length - 1) { UInt32 c = 0; if (UInt32.TryParse(json.Substring(i + 2, 4), System.Globalization.NumberStyles.AllowHexSpecifier, null, out c)) { parseStringBuilder.Append((char)c); i += 5; continue; } } } parseStringBuilder.Append(json[i]); } return(parseStringBuilder.ToString()); } if (type.IsPrimitive) { var result = Convert.ChangeType(json, type, System.Globalization.CultureInfo.InvariantCulture); return(result); } if (type == typeof(decimal)) { decimal result; decimal.TryParse(json, System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out result); return(result); } if (json == "null") { return(null); } if (type.IsEnum) { if (json[0] == '"') { json = json.Substring(1, json.Length - 2); } try { return(Enum.Parse(type, json, false)); } catch { return(0); } } if (type.IsArray) { var arrayType = type.GetElementType(); if (json[0] != '[' || json[json.Length - 1] != ']') { return(null); } var elems = JSONParser.Split(json); var newArray = Array.CreateInstance(arrayType, elems.Count); for (var i = 0; i < elems.Count; i++) { newArray.SetValue(JSONParser.ParseValue(arrayType, elems[i]), i); } JSONParser.splitArrayPool.Push(elems); return(newArray); } if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(List <>)) { var listType = type.GetGenericArguments()[0]; if (json[0] != '[' || json[json.Length - 1] != ']') { return(null); } var elems = JSONParser.Split(json); var list = (IList)type.GetConstructor(new Type[] { typeof(int) }).Invoke(new object[] { elems.Count }); for (var i = 0; i < elems.Count; i++) { list.Add(JSONParser.ParseValue(listType, elems[i])); } JSONParser.splitArrayPool.Push(elems); return(list); } if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Dictionary <,>)) { Type keyType, valueType; { var args = type.GetGenericArguments(); keyType = args[0]; valueType = args[1]; } //Refuse to parse dictionary keys that aren't of type string if (keyType != typeof(string)) { return(null); } //Must be a valid dictionary element if (json[0] != '{' || json[json.Length - 1] != '}') { return(null); } //The list is split into key/value pairs only, this means the split must be divisible by 2 to be valid JSON var elems = JSONParser.Split(json); if (elems.Count % 2 != 0) { return(null); } var dictionary = (IDictionary)type.GetConstructor(new Type[] { typeof(int) }).Invoke(new object[] { elems.Count / 2 }); for (var i = 0; i < elems.Count; i += 2) { if (elems[i].Length <= 2) { continue; } var keyValue = elems[i].Substring(1, elems[i].Length - 2); var val = JSONParser.ParseValue(valueType, elems[i + 1]); dictionary[keyValue] = val; } return(dictionary); } if (type == typeof(object)) { return(JSONParser.ParseAnonymousValue(json)); } if (json[0] == '{' && json[json.Length - 1] == '}') { return(JSONParser.ParseObject(type, json)); } return(null); }