diff --git a/README.md b/README.md
index f3c5ffc..73ebe6f 100644
--- a/README.md
+++ b/README.md
@@ -25,6 +25,7 @@ Install-Package SimpleJson
* Windows Phone 7.1 (Mango)
* Windows Phone 8
* Portable Class Libraries (PCL)
+* Unity
**Note:** By default SimpleJson expects `System.Linq`. If you are targeting older version of .NET framework (.net < 3.0 or WP7.0) you will need to add `#define SIMPLE_JSON_NO_LINQ_EXPRESSION`.
diff --git a/src/SimpleJson.sln b/src/SimpleJson.sln
index f7eaf8f..27c883d 100644
--- a/src/SimpleJson.sln
+++ b/src/SimpleJson.sln
@@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2013
-VisualStudioVersion = 12.0.20827.3
+VisualStudioVersion = 12.0.31101.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{AEDAD4B4-9F2C-4992-8CD6-A43DFDFF7172}"
EndProject
@@ -42,6 +42,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SimleJson.Tests-WindowsStor
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SimpleJson-Portable-WP8WinStoreNet45", "SimpleJson\SimpleJson-Portable-WP8WinStoreNet45.csproj", "{EC52A094-1CDB-4F5D-8A8A-86F501FC601C}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SimpleJson-Unity", "SimpleJson\SimpleJson-Unity.csproj", "{B6DF8C2D-A8F8-4FDB-B0E5-DFEEAA76CFE6}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -288,6 +290,20 @@ Global
{EC52A094-1CDB-4F5D-8A8A-86F501FC601C}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{EC52A094-1CDB-4F5D-8A8A-86F501FC601C}.Release|x64.ActiveCfg = Release|Any CPU
{EC52A094-1CDB-4F5D-8A8A-86F501FC601C}.Release|x86.ActiveCfg = Release|Any CPU
+ {B6DF8C2D-A8F8-4FDB-B0E5-DFEEAA76CFE6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {B6DF8C2D-A8F8-4FDB-B0E5-DFEEAA76CFE6}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {B6DF8C2D-A8F8-4FDB-B0E5-DFEEAA76CFE6}.Debug|ARM.ActiveCfg = Debug|Any CPU
+ {B6DF8C2D-A8F8-4FDB-B0E5-DFEEAA76CFE6}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+ {B6DF8C2D-A8F8-4FDB-B0E5-DFEEAA76CFE6}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {B6DF8C2D-A8F8-4FDB-B0E5-DFEEAA76CFE6}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {B6DF8C2D-A8F8-4FDB-B0E5-DFEEAA76CFE6}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {B6DF8C2D-A8F8-4FDB-B0E5-DFEEAA76CFE6}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {B6DF8C2D-A8F8-4FDB-B0E5-DFEEAA76CFE6}.Release|Any CPU.Build.0 = Release|Any CPU
+ {B6DF8C2D-A8F8-4FDB-B0E5-DFEEAA76CFE6}.Release|ARM.ActiveCfg = Release|Any CPU
+ {B6DF8C2D-A8F8-4FDB-B0E5-DFEEAA76CFE6}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {B6DF8C2D-A8F8-4FDB-B0E5-DFEEAA76CFE6}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+ {B6DF8C2D-A8F8-4FDB-B0E5-DFEEAA76CFE6}.Release|x64.ActiveCfg = Release|Any CPU
+ {B6DF8C2D-A8F8-4FDB-B0E5-DFEEAA76CFE6}.Release|x86.ActiveCfg = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/src/SimpleJson/SimpleJson-Unity.csproj b/src/SimpleJson/SimpleJson-Unity.csproj
new file mode 100644
index 0000000..323b575
--- /dev/null
+++ b/src/SimpleJson/SimpleJson-Unity.csproj
@@ -0,0 +1,49 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {B6DF8C2D-A8F8-4FDB-B0E5-DFEEAA76CFE6}
+ Library
+ Properties
+ SimpleJson
+ SimpleJson
+ v3.5
+ 512
+
+
+
+ true
+ full
+ false
+ ..\..\bin\Unity\Debug\
+ TRACE;DEBUG;SIMPLE_JSON_NO_LINQ_EXPRESSION;SIMPLE_JSON_DATACONTRACT;
+ prompt
+ 4
+
+
+ pdbonly
+ true
+ ..\..\bin\Unity\Release\
+ TRACE;SIMPLE_JSON_NO_LINQ_EXPRESSION;SIMPLE_JSON_DATACONTRACT;
+ prompt
+ 4
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/SimpleJson/SimpleJson.cs b/src/SimpleJson/SimpleJson.cs
index 2ab9742..e15e653 100644
--- a/src/SimpleJson/SimpleJson.cs
+++ b/src/SimpleJson/SimpleJson.cs
@@ -579,7 +579,25 @@ public static object DeserializeObject(string json, Type type, IJsonSerializerSt
? jsonObject
: (jsonSerializerStrategy ?? CurrentJsonSerializerStrategy).DeserializeObject(jsonObject, type);
}
-
+#if SIMPLE_JSON_NO_LINQ_EXPRESSION
+ public static object DeserializeObject(ref object target,string json, Type type, IJsonSerializerStrategy jsonSerializerStrategy)
+ {
+ object jsonObject = DeserializeObject(json);
+ return type == null || jsonObject != null && ReflectionUtils.IsAssignableFrom(jsonObject.GetType(), type)
+ ? jsonObject
+ : (jsonSerializerStrategy ?? CurrentJsonSerializerStrategy).DeserializeObject(ref target, jsonObject,
+ type);
+ }
+#else
+ public static object DeserializeObject(object target, string json, Type type, IJsonSerializerStrategy jsonSerializerStrategy)
+ {
+ object jsonObject = DeserializeObject(json);
+ return type == null || jsonObject != null && ReflectionUtils.IsAssignableFrom(jsonObject.GetType(), type)
+ ? jsonObject
+ : (jsonSerializerStrategy ?? CurrentJsonSerializerStrategy).DeserializeObject(target, jsonObject,
+ type);
+ }
+#endif
public static object DeserializeObject(string json, Type type)
{
return DeserializeObject(json, type, null);
@@ -594,7 +612,14 @@ public static T DeserializeObject(string json)
{
return (T)DeserializeObject(json, typeof(T), null);
}
-
+ public static T DeserializeObject(object target,string json)
+ {
+#if SIMPLE_JSON_NO_LINQ_EXPRESSION
+ return (T)DeserializeObject(ref target, json, typeof(T), null);
+#else
+ return (T)DeserializeObject(target, json, typeof(T), null);
+#endif
+ }
///
/// Converts a IDictionary<string,object> / IList<object> object into a JSON string
///
@@ -613,6 +638,20 @@ public static string SerializeObject(object json)
return SerializeObject(json, CurrentJsonSerializerStrategy);
}
+ ///
+ /// ±ÜÃâ¶ÑÄÚ´æ·ÖÅäµÄ½âÎö·½Ê½
+ /// Modify By ZhangMinglin
+ ///
+ public static StringBuilder SerializeObject(object json, StringBuilder builder)
+ {
+ if (builder == null)
+ {
+ return null;
+ }
+ bool success = SerializeValue(CurrentJsonSerializerStrategy, json, builder);
+ return (success ? builder : null);
+ }
+
public static string EscapeToJavascriptString(string jsonString)
{
if (string.IsNullOrEmpty(jsonString))
@@ -786,9 +825,26 @@ static object ParseValue(char[] json, ref int index, ref bool success)
return null;
}
+ [ThreadStatic]
+ static StringBuilder tempStringBuilder;
static string ParseString(char[] json, ref int index, ref bool success)
{
- StringBuilder s = new StringBuilder(BUILDER_CAPACITY);
+ ///ÐÞ¸ÄΪʹÓÃÒ»¸ö¾²Ì¬»º´æStringBuilder,¼õÉÙ¶ÑÄÚ´æ·ÖÅ䣬²»¹ý´Ë´¦»áÒýÆðÒ»¸ö³¤×¤µÄ¶ÑÄÚ´æ
+ ///Modify by ZhangMinglin
+ ///
+ /// Old:
+ ///StringBuilder s = new StringBuilder(BUILDER_CAPACITY);
+ /// Now:
+ if(tempStringBuilder == null)
+ {
+ tempStringBuilder = new StringBuilder(BUILDER_CAPACITY);
+ }
+ else
+ {
+ tempStringBuilder.Length = 0;
+ }
+ StringBuilder s = tempStringBuilder;
+
char c;
EatWhitespace(json, ref index);
@@ -907,9 +963,18 @@ static object ParseNumber(char[] json, ref int index, ref bool success)
}
else
{
+ //Modify by xtqqksszml@163.com
+ //Support uint, ulong
long number;
success = long.TryParse(new string(json, index, charLength), NumberStyles.Any, CultureInfo.InvariantCulture, out number);
- returnNumber = number;
+ if (success)
+ returnNumber = number;
+ else
+ {
+ ulong unsign_number;
+ success = ulong.TryParse(str, NumberStyles.Any, CultureInfo.InvariantCulture, out unsign_number);
+ returnNumber = unsign_number;
+ }
}
index = lastIndex + 1;
return returnNumber;
@@ -1234,6 +1299,12 @@ interface IJsonSerializerStrategy
[SuppressMessage("Microsoft.Design", "CA1007:UseGenericsWhereAppropriate", Justification="Need to support .NET 2")]
bool TrySerializeNonPrimitiveObject(object input, out object output);
object DeserializeObject(object value, Type type);
+#if SIMPLE_JSON_NO_LINQ_EXPRESSION
+ object DeserializeObject(ref object target, object value, Type type);
+#else
+ object DeserializeObject(object target,object value, Type type);
+#endif
+
}
[GeneratedCode("simple-json", "1.0.0")]
@@ -1379,14 +1450,17 @@ public virtual object DeserializeObject(object value, Type type)
}
else if (value is bool)
return value;
-
+
+ //Modify by xtqqksszml@163.com
+ //Support uint, ulong
bool valueIsLong = value is long;
+ bool valueIsULong = value is ulong;
bool valueIsDouble = value is double;
- if ((valueIsLong && type == typeof(long)) || (valueIsDouble && type == typeof(double)))
+ if ((valueIsLong && type == typeof(long)) || (valueIsDouble && type == typeof(double)) || (valueIsULong && type == typeof(ulong)))
return value;
- if ((valueIsDouble && type != typeof(double)) || (valueIsLong && type != typeof(long)))
+ if ((valueIsDouble && type != typeof(double)) || (valueIsLong && type != typeof(long)) || (valueIsULong && type != typeof(ulong)))
{
- obj = type == typeof(int) || type == typeof(long) || type == typeof(double) || type == typeof(float) || type == typeof(bool) || type == typeof(decimal) || type == typeof(byte) || type == typeof(short)
+ obj = type == typeof(int) || type == typeof(long) || type == typeof(uint) || type == typeof(ulong) || type == typeof(double) || type == typeof(float) || type == typeof(bool) || type == typeof(decimal) || type == typeof(byte) || type == typeof(short)
? Convert.ChangeType(value, type, CultureInfo.InvariantCulture)
: value;
}
@@ -1408,8 +1482,10 @@ public virtual object DeserializeObject(object value, Type type)
IDictionary dict = (IDictionary)ConstructorCache[genericType]();
+ // Modify by xtqqksszml@163.com
+ // Key support the other types
foreach (KeyValuePair kvp in jsonObject)
- dict.Add(kvp.Key, DeserializeObject(kvp.Value, valueType));
+ dict.Add(DeserializeObject(kvp.Key, keyType), DeserializeObject(kvp.Value, valueType));
obj = dict;
}
@@ -1419,14 +1495,21 @@ public virtual object DeserializeObject(object value, Type type)
obj = value;
else
{
- obj = ConstructorCache[type]();
+ if(type.IsClass)
+ obj = ConstructorCache[type]();
+ else
+ obj = Activator.CreateInstance(type);
foreach (KeyValuePair> setter in SetCache[type])
{
object jsonValue;
if (jsonObject.TryGetValue(setter.Key, out jsonValue))
{
jsonValue = DeserializeObject(jsonValue, setter.Value.Key);
+#if SIMPLE_JSON_NO_LINQ_EXPRESSION
+ setter.Value.Value(ref obj, jsonValue);
+#else
setter.Value.Value(obj, jsonValue);
+#endif
}
}
}
@@ -1450,11 +1533,40 @@ public virtual object DeserializeObject(object value, Type type)
else if (ReflectionUtils.IsTypeGenericeCollectionInterface(type) || ReflectionUtils.IsAssignableFrom(typeof(IList), type))
{
Type innerType = ReflectionUtils.GetGenericListElementType(type);
+ //Modify by xtqqksszml@163.com
+#if SIMPLE_JSON_NO_LINQ_EXPRESSION
+ list = (IList)(ConstructorCache[type] ?? ConstructorCache[typeof(List<>).MakeGenericType(innerType)])();
+#else
list = (IList)(ConstructorCache[type] ?? ConstructorCache[typeof(List<>).MakeGenericType(innerType)])(jsonObject.Count);
+#endif
foreach (object o in jsonObject)
list.Add(DeserializeObject(o, innerType));
}
obj = list;
+
+ //Modify by xtqqksszml@163.com
+ //Support Dictionary Formats([{"Key":?,"Value":?},])
+ if (ReflectionUtils.IsTypeDictionary(type))
+ {
+ Type[] types = ReflectionUtils.GetGenericTypeArguments(type);
+ Type keyType = types[0];
+ Type valueType = types[1];
+
+ Type genericType = typeof(Dictionary<,>).MakeGenericType(keyType, valueType);
+
+ IDictionary dict = (IDictionary)ConstructorCache[genericType]();
+
+ foreach (object o in jsonObject)
+ {
+ IDictionary element = o as IDictionary;
+ if (element != null)
+ {
+ dict.Add(DeserializeObject(element["Key"], keyType)
+ , DeserializeObject(element["Value"], valueType));
+ }
+ }
+ obj = dict;
+ }
}
}
return obj;
@@ -1463,7 +1575,197 @@ public virtual object DeserializeObject(object value, Type type)
return ReflectionUtils.ToNullableType(obj, type);
return obj;
}
+ [SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")]
+#if SIMPLE_JSON_NO_LINQ_EXPRESSION
+ public virtual object DeserializeObject(ref object target, object value, Type type)
+#else
+ public virtual object DeserializeObject(object target, object value, Type type)
+#endif
+ {
+ if (type == null) throw new ArgumentNullException("type");
+ string str = value as string;
+
+ if (type == typeof(Guid) && string.IsNullOrEmpty(str))
+ return default(Guid);
+
+ if (value == null)
+ return null;
+
+ object obj = null;
+
+ if (str != null)
+ {
+ if (str.Length != 0) // We know it can't be null now.
+ {
+ if (type == typeof(DateTime) || (ReflectionUtils.IsNullableType(type) && Nullable.GetUnderlyingType(type) == typeof(DateTime)))
+ return DateTime.ParseExact(str, Iso8601Format, CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal | DateTimeStyles.AdjustToUniversal);
+ if (type == typeof(DateTimeOffset) || (ReflectionUtils.IsNullableType(type) && Nullable.GetUnderlyingType(type) == typeof(DateTimeOffset)))
+ return DateTimeOffset.ParseExact(str, Iso8601Format, CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal | DateTimeStyles.AdjustToUniversal);
+ if (type == typeof(Guid) || (ReflectionUtils.IsNullableType(type) && Nullable.GetUnderlyingType(type) == typeof(Guid)))
+ return new Guid(str);
+ if (type == typeof(Uri))
+ {
+ bool isValid = Uri.IsWellFormedUriString(str, UriKind.RelativeOrAbsolute);
+
+ Uri result;
+ if (isValid && Uri.TryCreate(str, UriKind.RelativeOrAbsolute, out result))
+ return result;
+
+ return null;
+ }
+
+ if (type == typeof(string))
+ return str;
+
+ return Convert.ChangeType(str, type, CultureInfo.InvariantCulture);
+ }
+ else
+ {
+ if (type == typeof(Guid))
+ obj = default(Guid);
+ else if (ReflectionUtils.IsNullableType(type) && Nullable.GetUnderlyingType(type) == typeof(Guid))
+ obj = null;
+ else
+ obj = str;
+ }
+ // Empty string case
+ if (!ReflectionUtils.IsNullableType(type) && Nullable.GetUnderlyingType(type) == typeof(Guid))
+ return str;
+ }
+ else if (value is bool)
+ return value;
+
+ //Modify by xtqqksszml@163.com
+ //Support uint, ulong
+ bool valueIsLong = value is long;
+ bool valueIsULong = value is ulong;
+ bool valueIsDouble = value is double;
+ if ((valueIsLong && type == typeof(long)) || (valueIsDouble && type == typeof(double)) || (valueIsULong && type == typeof(ulong)))
+ return value;
+ if ((valueIsDouble && type != typeof(double)) || (valueIsLong && type != typeof(long)) || (valueIsULong && type != typeof(ulong)))
+ {
+ obj = type == typeof(int) || type == typeof(long) || type == typeof(uint) || type == typeof(ulong) || type == typeof(double) || type == typeof(float) || type == typeof(bool) || type == typeof(decimal) || type == typeof(byte) || type == typeof(short)
+ ? Convert.ChangeType(value, type, CultureInfo.InvariantCulture)
+ : value;
+ }
+ else
+ {
+ IDictionary objects = value as IDictionary;
+ if (objects != null)
+ {
+ IDictionary jsonObject = objects;
+
+ if (ReflectionUtils.IsTypeDictionary(type))
+ {
+ // if dictionary then
+ Type[] types = ReflectionUtils.GetGenericTypeArguments(type);
+ Type keyType = types[0];
+ Type valueType = types[1];
+
+ Type genericType = typeof(Dictionary<,>).MakeGenericType(keyType, valueType);
+
+ IDictionary dict = (IDictionary)ConstructorCache[genericType]();
+
+ // Modify by xtqqksszml@163.com
+ // Key support the other types
+ foreach (KeyValuePair kvp in jsonObject)
+ dict.Add(DeserializeObject(kvp.Key, keyType), DeserializeObject(kvp.Value, valueType));
+
+ obj = dict;
+ }
+ else
+ {
+ if (type == typeof(object))
+ obj = value;
+ else
+ {
+
+ if (target.GetType() == type && target != null)
+ obj = target;
+ else
+ {
+ if (type.IsClass)
+ obj = ConstructorCache[type]();
+ else
+ obj = Activator.CreateInstance(type);
+ }
+
+ foreach (KeyValuePair> setter in SetCache[type])
+ {
+ object jsonValue;
+ if (jsonObject.TryGetValue(setter.Key, out jsonValue))
+ {
+ jsonValue = DeserializeObject(jsonValue, setter.Value.Key);
+#if SIMPLE_JSON_NO_LINQ_EXPRESSION
+ setter.Value.Value(ref obj, jsonValue);
+#else
+ setter.Value.Value(obj, jsonValue);
+#endif
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ IList