public void ConstructionWithTail() { ObjectConstructor ctor = new ObjectConstructor(typeof(Point)); ImportContext context = JsonConvert.CreateImportContext(); const string json = "{ y: 456, z: 789, x: 123 }"; ObjectConstructionResult result = ctor.CreateObject(context, JsonText.CreateReader(json)); Point point = (Point)result.Object; Assert.AreEqual(123, point.X); Assert.AreEqual(456, point.Y); NamedJsonBuffer[] tail = JsonBuffer.From(result.TailReader).GetMembersArray(); Assert.AreEqual(1, tail.Length); NamedJsonBuffer z = tail[0]; Assert.AreEqual("z", z.Name); Assert.AreEqual(789, z.Buffer.GetNumber().ToInt32()); }
private static int FindMember(NamedJsonBuffer[] members, string name) { for (int i = 0; i < members.Length; i++) { NamedJsonBuffer member = members[i]; if (member.IsEmpty) { throw new ArgumentException(null, "members"); } if (0 == CultureInfo.InvariantCulture.CompareInfo.Compare(name, member.Name, CompareOptions.IgnoreCase)) { return(i); } } return(-1); }
public ObjectConstructionResult CreateObject(ImportContext context, NamedJsonBuffer[] members) { if (context == null) { throw new ArgumentNullException("context"); } if (members == null) { throw new ArgumentNullException("members"); } if (_ctors.Length > 0) { foreach (ConstructorInfo ctor in _ctors) { ObjectConstructionResult result = TryCreateObject(context, ctor, members); if (result != null) { return(result); } } } if (_type.IsValueType) { // // Value types always have a default constructor available // but one which does not show up in reflection. If no other // constructors matched then just use the default one. // object obj = Activator.CreateInstance(_type); JsonReader tail = NamedJsonBuffer.ToObject(members).CreateReader(); return(new ObjectConstructionResult(obj, tail)); } throw new JsonException(string.Format("None constructor could be used to create {0} object from JSON.", _ctors[0].DeclaringType)); }
private static ObjectConstructionResult TryCreateObject(ImportContext context, ConstructorInfo ctor, NamedJsonBuffer[] members) { Debug.Assert(context != null); Debug.Assert(ctor != null); Debug.Assert(members != null); ParameterInfo[] parameters = ctor.GetParameters(); if (parameters.Length > members.Length) { return(null); } int[] bindings = Bind(context, parameters, members); int argc = 0; object[] args = null; JsonBufferWriter tailw = null; for (int i = 0; i < bindings.Length; i++) { int binding = bindings[i] - 1; if (binding >= 0) { if (args == null) { args = new object[parameters.Length]; } Type type = parameters[binding].ParameterType; JsonBuffer arg = members[i].Buffer; args[binding] = context.Import(type, arg.CreateReader()); argc++; } else { if (tailw == null) { tailw = new JsonBufferWriter(); tailw.WriteStartObject(); } NamedJsonBuffer member = members[i]; tailw.WriteMember(member.Name); tailw.WriteFromReader(member.Buffer.CreateReader()); } } if (tailw != null) { tailw.WriteEndObject(); } if (argc != parameters.Length) { return(null); } object obj = ctor.Invoke(args); JsonBuffer tail = tailw != null ? tailw.GetBuffer() : StockJsonBuffers.EmptyObject; return(new ObjectConstructionResult(obj, tail.CreateReader())); }
public ObjectConstructionResult CreateObject(ImportContext context, NamedJsonBuffer[] members) { if (context == null) throw new ArgumentNullException("context"); if (members == null) throw new ArgumentNullException("members"); if (_ctors.Length > 0) { foreach (ConstructorInfo ctor in _ctors) { ObjectConstructionResult result = TryCreateObject(context, ctor, members); if (result != null) return result; } } if (_type.IsValueType) { // // Value types always have a default constructor available // but one which does not show up in reflection. If no other // constructors matched then just use the default one. // object obj = Activator.CreateInstance(_type); JsonReader tail = NamedJsonBuffer.ToObject(members).CreateReader(); return new ObjectConstructionResult(obj, tail); } throw new JsonException(string.Format("None constructor could be used to create {0} object from JSON.", _ctors[0].DeclaringType)); }
private static int FindMember(NamedJsonBuffer[] members, string name) { for (int i = 0; i < members.Length; i++) { NamedJsonBuffer member = members[i]; if (member.IsEmpty) throw new ArgumentException(null, "members"); if (0 == CultureInfo.InvariantCulture.CompareInfo.Compare(name, member.Name, CompareOptions.IgnoreCase)) return i; } return -1; }
/// <remarks> /// Bound indicies returned in the resulting array are one-based /// therefore zero means unbound. /// </remarks> private static int[] Bind(ImportContext context, ParameterInfo[] parameters, NamedJsonBuffer[] members) { if (context == null) throw new ArgumentNullException("context"); if (parameters == null) throw new ArgumentNullException("parameters"); if (members == null) throw new ArgumentNullException("members"); int[] bindings = new int[members.Length]; for (int i = 0; i < parameters.Length; i++) { ParameterInfo parameter = parameters[i]; if (parameter == null) throw new ArgumentException(null, "parameters"); int mi = FindMember(members, parameter.Name); if (mi >= 0) bindings[mi] = i + 1; } return bindings; }
private static ObjectConstructionResult TryCreateObject(ImportContext context, ConstructorInfo ctor, NamedJsonBuffer[] members) { Debug.Assert(context != null); Debug.Assert(ctor != null); Debug.Assert(members != null); ParameterInfo[] parameters = ctor.GetParameters(); if (parameters.Length > members.Length) return null; int[] bindings = Bind(context, parameters, members); int argc = 0; object[] args = null; JsonBufferWriter tailw = null; for (int i = 0; i < bindings.Length; i++) { int binding = bindings[i] - 1; if (binding >= 0) { if (args == null) args = new object[parameters.Length]; Type type = parameters[binding].ParameterType; JsonBuffer arg = members[i].Buffer; args[binding] = context.Import(type, arg.CreateReader()); argc++; } else { if (tailw == null) { tailw = new JsonBufferWriter(); tailw.WriteStartObject(); } NamedJsonBuffer member = members[i]; tailw.WriteMember(member.Name); tailw.WriteFromReader(member.Buffer.CreateReader()); } } if (tailw != null) tailw.WriteEndObject(); if (argc != parameters.Length) return null; object obj = ctor.Invoke(args); JsonBuffer tail = tailw != null ? tailw.GetBuffer() : StockJsonBuffers.EmptyObject; return new ObjectConstructionResult(obj, tail.CreateReader()); }