diff --git a/Assets/Plugins/UnityJSON/Deserializer.cs b/Assets/Plugins/UnityJSON/Deserializer.cs
index 0e747a8..142107b 100644
--- a/Assets/Plugins/UnityJSON/Deserializer.cs
+++ b/Assets/Plugins/UnityJSON/Deserializer.cs
@@ -65,6 +65,10 @@ public Instantiater instantiater {
}
}
+ protected Deserializer ()
+ {
+ }
+
///
/// Tries to deserialize the JSON node onto the given object. It is guaranteed
/// that the object is not null. This will be called before trying any other
@@ -1360,12 +1364,17 @@ private Dictionary> _GetDeserializedClassMembers (
out MemberInfo extrasMember,
out JSONExtrasAttribute extrasAttribute)
{
- JSONObjectAttribute classAttribute = Util.GetAttribute (classType);
+ JSONObjectAttribute objectAttribute = Util.GetAttribute (classType);
Dictionary> members = new Dictionary> ();
var flags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance;
- if (classAttribute != null && !classAttribute.options.ShouldIgnoreStatic ()) {
- flags |= BindingFlags.Static;
+ if (objectAttribute != null) {
+ if (!objectAttribute.options.ShouldIgnoreStatic ()) {
+ flags |= BindingFlags.Static;
+ }
+ if (objectAttribute.options.ShouldUseTupleFormat ()) {
+ throw new ArgumentException ("Cannot deserialize on a tuple formatted object.");
+ }
}
extrasMember = null;
@@ -1392,7 +1401,7 @@ private Dictionary> _GetDeserializedClassMembers (
}
}
- if (classAttribute == null || !classAttribute.options.ShouldIgnoreProperties ()) {
+ if (objectAttribute == null || !objectAttribute.options.ShouldIgnoreProperties ()) {
foreach (var propertyInfo in classType.GetProperties(flags)) {
if (extrasMember == null) {
if (Util.IsJSONExtrasMember (propertyInfo, out extrasAttribute)) {
diff --git a/Assets/Plugins/UnityJSON/Enums.cs b/Assets/Plugins/UnityJSON/Enums.cs
index 0b16345..a77ed86 100644
--- a/Assets/Plugins/UnityJSON/Enums.cs
+++ b/Assets/Plugins/UnityJSON/Enums.cs
@@ -116,7 +116,20 @@ public enum ObjectOptions
/// keys, then an exception is thrown. This option prevents the
/// deserializer from throwing that exception.
///
- IgnoreUnknownKey = 1 << 2
+ IgnoreUnknownKey = 1 << 2,
+
+ ///
+ /// The class or the struct is handled as a tuple (JSON array) rather
+ /// than a dictionary. This automatically ignores properties both for
+ /// serialization and deserialization. For serialization, the fields are
+ /// serialized in the order they are defined in an array without keys.
+ /// As for deserialization, the elements are passed to the constructor
+ /// in the order they are defined. Deserialization does not take place
+ /// for other fields and properties.
+ ///
+ /// Tuple formatted classes and structs do not support JSON extras.
+ ///
+ TupleFormat = 1 << 3 | IgnoreProperties,
}
///
@@ -225,7 +238,7 @@ public static bool IsDeserialized (this NodeOptions options)
///
public static bool ShouldSerializeNull (this NodeOptions options)
{
- return (options & NodeOptions.SerializeNull) != 0;
+ return (options & NodeOptions.SerializeNull) == NodeOptions.SerializeNull;
}
///
@@ -233,7 +246,7 @@ public static bool ShouldSerializeNull (this NodeOptions options)
///
public static bool ShouldIgnoreTypeMismatch (this NodeOptions options)
{
- return (options & NodeOptions.IgnoreTypeMismatch) != 0;
+ return (options & NodeOptions.IgnoreTypeMismatch) == NodeOptions.IgnoreTypeMismatch;
}
///
@@ -241,7 +254,7 @@ public static bool ShouldIgnoreTypeMismatch (this NodeOptions options)
///
public static bool ShouldIgnoreUnknownType (this NodeOptions options)
{
- return (options & NodeOptions.IgnoreInstantiationError) != 0;
+ return (options & NodeOptions.IgnoreInstantiationError) == NodeOptions.IgnoreInstantiationError;
}
///
@@ -257,7 +270,7 @@ public static bool ShouldAssignNull (this NodeOptions options)
///
public static bool ShouldReplaceWithDeserialized (this NodeOptions options)
{
- return (options & NodeOptions.ReplaceDeserialized) != 0;
+ return (options & NodeOptions.ReplaceDeserialized) == NodeOptions.ReplaceDeserialized;
}
///
@@ -265,7 +278,7 @@ public static bool ShouldReplaceWithDeserialized (this NodeOptions options)
///
public static bool ShouldIgnoreProperties (this ObjectOptions options)
{
- return (options & ObjectOptions.IgnoreProperties) != 0;
+ return (options & ObjectOptions.IgnoreProperties) == ObjectOptions.IgnoreProperties;
}
///
@@ -284,12 +297,20 @@ public static bool ShouldThrowAtUnknownKey (this ObjectOptions options)
return (options & ObjectOptions.IgnoreUnknownKey) == 0;
}
+ ///
+ /// Returns true if ObjectOptions.TupleFormat is not set.
+ ///
+ public static bool ShouldUseTupleFormat (this ObjectOptions options)
+ {
+ return (options & ObjectOptions.TupleFormat) == ObjectOptions.TupleFormat;
+ }
+
///
/// Returns true if ObjectTypes.String is set.
///
public static bool SupportsString (this ObjectTypes types)
{
- return (types & ObjectTypes.String) != 0;
+ return (types & ObjectTypes.String) == ObjectTypes.String;
}
///
@@ -297,7 +318,7 @@ public static bool SupportsString (this ObjectTypes types)
///
public static bool SupportsBool (this ObjectTypes types)
{
- return (types & ObjectTypes.Bool) != 0;
+ return (types & ObjectTypes.Bool) == ObjectTypes.Bool;
}
///
@@ -305,7 +326,7 @@ public static bool SupportsBool (this ObjectTypes types)
///
public static bool SupportsNumber (this ObjectTypes types)
{
- return (types & ObjectTypes.Number) != 0;
+ return (types & ObjectTypes.Number) == ObjectTypes.Number;
}
///
@@ -313,7 +334,7 @@ public static bool SupportsNumber (this ObjectTypes types)
///
public static bool SupportsArray (this ObjectTypes types)
{
- return (types & ObjectTypes.Array) != 0;
+ return (types & ObjectTypes.Array) == ObjectTypes.Array;
}
///
@@ -321,7 +342,7 @@ public static bool SupportsArray (this ObjectTypes types)
///
public static bool SupportsDictionary (this ObjectTypes types)
{
- return (types & ObjectTypes.Dictionary) != 0;
+ return (types & ObjectTypes.Dictionary) == ObjectTypes.Dictionary;
}
///
@@ -329,7 +350,7 @@ public static bool SupportsDictionary (this ObjectTypes types)
///
public static bool SupportsCustom (this ObjectTypes types)
{
- return (types & ObjectTypes.Custom) != 0;
+ return (types & ObjectTypes.Custom) == ObjectTypes.Custom;
}
}
}
diff --git a/Assets/Plugins/UnityJSON/Instantiater.cs b/Assets/Plugins/UnityJSON/Instantiater.cs
index 6f8ec68..5b4b0a3 100644
--- a/Assets/Plugins/UnityJSON/Instantiater.cs
+++ b/Assets/Plugins/UnityJSON/Instantiater.cs
@@ -75,6 +75,10 @@ public class Instantiater
{
public static readonly Instantiater Default = new Instantiater ();
+ protected Instantiater ()
+ {
+ }
+
///
/// Instantiates an instance of a type. First, TryInstantiate method is
/// called for custom instantiation. If that fails, then the class is queried for
@@ -252,22 +256,28 @@ private InstantiationData _Instantiate (
return instantiationData;
}
+ if (node.IsNull || node.Tag == JSONNodeType.None) {
+ return InstantiationData.Null;
+ }
+
if (referingType != targetType) {
- var conditionalAttributes = targetType
- .GetCustomAttributes (typeof(ConditionalInstantiationAttribute), false);
- foreach (object attribute in conditionalAttributes) {
- var condition = attribute as ConditionalInstantiationAttribute;
- if (Equals (node [condition.key].Value, condition.value.ToString ())) {
- instantiationData = _Instantiate (
- node,
- condition.referenceType,
- targetType,
- options,
- deserializer);
- if (condition.ignoreConditionKey) {
- instantiationData.ignoredKeys = new HashSet () { condition.key };
+ if (node.IsObject) {
+ var conditionalAttributes = targetType
+ .GetCustomAttributes (typeof(ConditionalInstantiationAttribute), false);
+ foreach (object attribute in conditionalAttributes) {
+ var condition = attribute as ConditionalInstantiationAttribute;
+ if (Equals (node [condition.key].Value, condition.value.ToString ())) {
+ instantiationData = _Instantiate (
+ node,
+ condition.referenceType,
+ targetType,
+ options,
+ deserializer);
+ if (condition.ignoreConditionKey) {
+ instantiationData.ignoredKeys = new HashSet () { condition.key };
+ }
+ return instantiationData;
}
- return instantiationData;
}
}
@@ -295,6 +305,19 @@ private InstantiationData _InstantiateWithConstructor (
NodeOptions options,
Deserializer deserializer)
{
+ if (node.IsNull || node.Tag == JSONNodeType.None) {
+ return InstantiationData.Null;
+ }
+
+ JSONObjectAttribute objectAttribute = Util.GetAttribute (targetType);
+ bool useTupleFormat = objectAttribute != null
+ ? objectAttribute.options.ShouldUseTupleFormat () : false;
+ if (useTupleFormat && !node.IsArray) {
+ throw new InstantiationException ("Expected JSON array, found " + node.Tag);
+ } else if (!useTupleFormat && !node.IsObject) {
+ throw new InstantiationException ("Expected JSON object, found " + node.Tag);
+ }
+
ConstructorInfo[] constructors = targetType.GetConstructors (
BindingFlags.Instance |
BindingFlags.Public |
@@ -302,12 +325,12 @@ private InstantiationData _InstantiateWithConstructor (
foreach (ConstructorInfo constructorInfo in constructors) {
var constructorAttribute = Util.GetAttribute (constructorInfo);
if (constructorAttribute != null) {
- return _InstantiateWithConstructor (node, constructorInfo, deserializer);
+ return _InstantiateWithConstructor (node, constructorInfo, deserializer, useTupleFormat);
}
}
try {
- InstantiationData instantiationData = new InstantiationData();
+ InstantiationData instantiationData = new InstantiationData ();
instantiationData.instantiatedObject = Activator.CreateInstance (targetType);
instantiationData.needsDeserialization = node.Count != 0;
return instantiationData;
@@ -320,7 +343,8 @@ private InstantiationData _InstantiateWithConstructor (
private InstantiationData _InstantiateWithConstructor (
JSONNode node,
ConstructorInfo constructorInfo,
- Deserializer deserializer)
+ Deserializer deserializer,
+ bool useTupleFormat)
{
ParameterInfo[] parameters = constructorInfo.GetParameters ();
object[] parameterValues = new object[parameters.Length];
@@ -332,23 +356,27 @@ private InstantiationData _InstantiateWithConstructor (
string key = nodeAttribute != null && nodeAttribute.key != null
? nodeAttribute.key : parameters [i].Name;
+ JSONNode parameterNode = useTupleFormat ? node [i] : node [key];
+
ObjectTypes restrictedTypes = restrictAttribute == null
? ObjectTypes.JSON : restrictAttribute.types;
Type[] customTypes = restrictAttribute == null ? null : restrictAttribute.customTypes;
parameterValues [i] = deserializer.Deserialize (
- node [key],
+ parameterNode,
parameters [i].ParameterType,
nodeAttribute == null ? NodeOptions.Default : nodeAttribute.options,
restrictedTypes,
customTypes);
- ignoredKeys.Add (key);
+ if (!useTupleFormat) {
+ ignoredKeys.Add (key);
+ }
}
- InstantiationData instantiationData = new InstantiationData();
+ InstantiationData instantiationData = new InstantiationData ();
instantiationData.instantiatedObject = constructorInfo.Invoke (parameterValues);
- instantiationData.needsDeserialization = ignoredKeys.Count != node.Count;
+ instantiationData.needsDeserialization = !useTupleFormat && ignoredKeys.Count != node.Count;
instantiationData.ignoredKeys = ignoredKeys;
return instantiationData;
}
diff --git a/Assets/Plugins/UnityJSON/JSON.cs b/Assets/Plugins/UnityJSON/JSON.cs
index 8605035..44c1fd8 100644
--- a/Assets/Plugins/UnityJSON/JSON.cs
+++ b/Assets/Plugins/UnityJSON/JSON.cs
@@ -30,6 +30,26 @@ public static string Serialize (
return serializer.Serialize (obj, options);
}
+ ///
+ /// Serializes the given object into JSON string. Throws an
+ /// error if the object is null.
+ ///
+ /// Object to be serialized.
+ /// Custom serializer. Throws an error if
+ /// null.
+ public static string Serialize (
+ object obj,
+ Serializer serializer)
+ {
+ if (obj == null) {
+ throw new ArgumentNullException ("obj");
+ }
+ if (serializer == null) {
+ throw new ArgumentNullException ("serializer");
+ }
+ return serializer.Serialize (obj);
+ }
+
///
/// Serializes the object into JSON string.
///
@@ -45,6 +65,19 @@ public static string ToJSONString (
return Serialize (obj, options, serializer);
}
+ ///
+ /// Serializes the object into JSON string.
+ ///
+ /// Object to be serialized.
+ /// Custom serializer. Throws an error if
+ /// null.
+ public static string ToJSONString (
+ this object obj,
+ Serializer serializer)
+ {
+ return Serialize (obj, serializer);
+ }
+
///
/// Deserializes an object of the generic type from
/// the given JSON string. Throws an exception if the string
@@ -74,6 +107,33 @@ public static T Deserialize (
return (T)deserializer.Deserialize (node, typeof(T), options);
}
+ ///
+ /// Deserializes an object of the generic type from
+ /// the given JSON string. Throws an exception if the string
+ /// is null or not a valid JSON string.
+ ///
+ /// The JSON string to deserialize from.
+ /// Custom deserializer. Throws an error if
+ /// null.
+ /// The type of object to deserialize.
+ public static T Deserialize (
+ string jsonString,
+ Deserializer deserializer)
+ {
+ if (jsonString == null) {
+ throw new ArgumentNullException ("jsonString");
+ }
+ if (deserializer == null) {
+ throw new ArgumentNullException ("deserializer");
+ }
+
+ SimpleJSON.JSONNode node = SimpleJSON.JSON.Parse (jsonString);
+ if (node == null) {
+ throw new ArgumentException ("Argument is not a valid JSON string: " + jsonString);
+ }
+ return (T)deserializer.Deserialize (node, typeof(T));
+ }
+
///
/// Deserializes a JSON string on a previously existing object.
/// Throws an exception if the string is null or not a valid JSON string.
@@ -106,6 +166,36 @@ public static void DeserializeOn (
deserializer.DeserializeOn (obj, node, options);
}
+ ///
+ /// Deserializes a JSON string on a previously existing object.
+ /// Throws an exception if the string is null or not a valid JSON string.
+ ///
+ /// Object to deserialize on.
+ /// The JSON string to deserialize from.
+ /// Custom deserializer. Throws an error if
+ /// null.
+ public static void DeserializeOn (
+ object obj,
+ string jsonString,
+ Deserializer deserializer)
+ {
+ if (obj == null) {
+ throw new ArgumentNullException ("obj");
+ }
+ if (jsonString == null) {
+ throw new ArgumentNullException ("jsonString");
+ }
+ if (deserializer == null) {
+ throw new ArgumentNullException ("deserializer");
+ }
+
+ SimpleJSON.JSONNode node = SimpleJSON.JSON.Parse (jsonString);
+ if (node == null) {
+ throw new ArgumentException ("Argument is not a valid JSON string: " + jsonString);
+ }
+ deserializer.DeserializeOn (obj, node);
+ }
+
///
/// Deserializes a JSON string on the previously existing object.
/// Throws an exception if the string is null or not a valid JSON string.
@@ -123,5 +213,21 @@ public static void FeedJSON (
{
DeserializeOn (obj, jsonString, options, deserializer);
}
+
+ ///
+ /// Deserializes a JSON string on the previously existing object.
+ /// Throws an exception if the string is null or not a valid JSON string.
+ ///
+ /// Object to deserialize on.
+ /// The JSON string to deserialize from.
+ /// Custom deserializer. Throws an error if
+ /// null.
+ public static void FeedJSON (
+ this object obj,
+ string jsonString,
+ Deserializer deserializer)
+ {
+ DeserializeOn (obj, jsonString, deserializer);
+ }
}
}
diff --git a/Assets/Plugins/UnityJSON/Serializer.cs b/Assets/Plugins/UnityJSON/Serializer.cs
index fd4a286..8966a84 100644
--- a/Assets/Plugins/UnityJSON/Serializer.cs
+++ b/Assets/Plugins/UnityJSON/Serializer.cs
@@ -18,7 +18,7 @@ public class Serializer
private const string _kTrue = "true";
private const string _kFalse = "false";
- private static Serializer _default = new Serializer();
+ private static Serializer _default = new Serializer ();
///
/// The default serializer to be used when no serializer is given.
@@ -46,7 +46,7 @@ public static Serializer Default {
///
public bool useUndefinedForNull = false;
- private Serializer ()
+ protected Serializer ()
{
}
@@ -278,13 +278,19 @@ public string SerializeBounds (Bounds bounds)
///
/// Serializes an object by its fields and properties. This will
/// ignore custom serializations of the object (see Serializer.TrySerialize
- /// and ISerializable.Serialize).
+ /// and ISerializable.Serialize). This will throw an argument exception if
+ /// the object is a non-struct value type (primitives and enums).
///
public string SerializeByParts (object obj, NodeOptions options = NodeOptions.Default)
{
if (obj == null) {
return SerializeNull (options);
}
+ Type type = obj.GetType ();
+ if (type.IsPrimitive || type.IsEnum) {
+ throw new ArgumentException ("Cannot serialize non-struct value types by parts.");
+ }
+
return _SerializeCustom (obj, options);
}
@@ -382,29 +388,35 @@ private string _SerializeCustom (object obj, NodeOptions options)
};
Type type = obj.GetType ();
- JSONObjectAttribute classAttribute = Util.GetAttribute (type);
+ JSONObjectAttribute objectAttribute = Util.GetAttribute (type);
var flags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance;
- if (classAttribute != null && !classAttribute.options.ShouldIgnoreStatic ()) {
- flags |= BindingFlags.Static;
+ bool useTupleFormat = false;
+ if (objectAttribute != null) {
+ if (!objectAttribute.options.ShouldIgnoreStatic ()) {
+ flags |= BindingFlags.Static;
+ }
+ if (objectAttribute.options.ShouldUseTupleFormat ()) {
+ useTupleFormat = true;
+ }
}
enumerable = enumerable.Concat (
from f in type.GetFields (flags)
where isNotExtras (f) && _IsValidFieldInfo (f)
- select _SerializeCustomField (obj, f));
+ select _SerializeCustomField (obj, f, useTupleFormat));
- if (classAttribute == null || !classAttribute.options.ShouldIgnoreProperties ()) {
+ if (objectAttribute == null || !objectAttribute.options.ShouldIgnoreProperties ()) {
enumerable = enumerable.Concat (
from p in type.GetProperties (flags)
where isNotExtras (p) && _IsValidPropertyInfo (p)
- select _SerializeCustomProperty (obj, p));
+ select _SerializeCustomProperty (obj, p, useTupleFormat));
}
// Serialize all properties and fields.
var result = _Join (enumerable, o => o as string);
// Serialize the extras if there are any.
- if (extrasMember != null) {
+ if (!useTupleFormat && extrasMember != null) {
var extras = Util.GetMemberValue (extrasMember, obj) as IEnumerable;
if (extras != null) {
result += (result == "" ? "" : ",")
@@ -415,8 +427,12 @@ where isNotExtras (p) && _IsValidPropertyInfo (p)
if (listener != null) {
listener.OnSerializationSucceeded (this);
}
- return "{" + result + "}";
- ;
+
+ if (useTupleFormat) {
+ return "[" + result + "]";
+ } else {
+ return "{" + result + "}";
+ }
} catch (Exception exception) {
if (listener != null) {
listener.OnSerializationFailed (this);
@@ -471,17 +487,17 @@ private string _Join (IEnumerable enumerable, Func