public static object Parse(Type tupleType, string value) { var index = 0; Serializer.EatMapStartChar(value, ref index); if (JsonTypeSerializer.IsEmptyMap(value, index)) { return(Activator.CreateInstance(tupleType)); } var genericArgs = tupleType.GetGenericArguments(); var argValues = new object[genericArgs.Length]; var valueLength = value.Length; while (index < valueLength) { var keyValue = Serializer.EatMapKey(value, ref index); Serializer.EatMapKeySeperator(value, ref index); var elementValue = Serializer.EatValue(value, ref index); if (keyValue == null) { continue; } var keyIndex = int.Parse(keyValue.Substring(4)) - 1; argValues[keyIndex] = Serializer.GetParseFn(genericArgs[keyIndex]).Invoke(elementValue); Serializer.EatItemSeperatorOrMapEndChar(value, ref index); } return(tupleType.GetConstructors().First(x => x.GetParameters().Length == genericArgs.Length).Invoke(argValues)); }
private static int VerifyAndGetStartIndex(ReadOnlySpan <char> value, Type createMapType) { var index = 0; if (!Serializer.EatMapStartChar(value, ref index)) { //Don't throw ex because some KeyValueDataContractDeserializer don't have '{}' Tracer.Instance.WriteDebug("WARN: Map definitions should start with a '{0}', expecting serialized type '{1}', got string starting with: {2}", JsWriter.MapStartChar, createMapType != null ? createMapType.Name : "Dictionary<,>", value.Substring(0, value.Length < 50 ? value.Length : 50)); } return(index); }
private static object StringToType(Type type, string strType, EmptyCtorDelegate ctorFn, IDictionary <string, SetPropertyDelegate> setterMap, IDictionary <string, ParseStringDelegate> parseStringFnMap) { var index = 0; if (!Serializer.EatMapStartChar(strType, ref index)) { throw new SerializationException(string.Format( "Type definitions should start with a '{0}', expecting serialized type '{1}', got string starting with: {2}", JsWriter.MapStartChar, type.Name, strType.Substring(0, strType.Length < 50 ? strType.Length : 50))); } var instance = ctorFn(); string propertyName; ParseStringDelegate parseStringFn; SetPropertyDelegate setterFn; if (strType == JsWriter.EmptyMap) { return(instance); } var strTypeLength = strType.Length; while (index < strTypeLength) { propertyName = Serializer.EatMapKey(strType, ref index); Serializer.EatMapKeySeperator(strType, ref index); var propertyValueString = Serializer.EatValue(strType, ref index); parseStringFnMap.TryGetValue(propertyName, out parseStringFn); if (parseStringFn != null) { var propertyValue = parseStringFn(propertyValueString); setterMap.TryGetValue(propertyName, out setterFn); if (setterFn != null) { setterFn(instance, propertyValue); } } Serializer.EatItemSeperatorOrMapEndChar(strType, ref index); } return(instance); }
private static int VerifyAndGetStartIndex(string value, Type createMapType) { var index = 0; if (Serializer.EatListStartChar(value, ref index)) { throw new InvalidOperationException(String.Format("Map definitions are not expected to be lists.")); } if (!Serializer.EatMapStartChar(value, ref index)) { //Don't throw ex because some KeyValueDataContractDeserializer don't have '{}' Tracer.Instance.WriteDebug("WARN: Map definitions should start with a '{0}', expecting serialized type '{1}', got string starting with: {2}", JsWriter.MapStartChar, createMapType != null ? createMapType.Name : "Dictionary<,>", value.Substring(0, value.Length < 50 ? value.Length : 50)); } return(index); }
public static object ParseTuple(Type tupleType, StringSegment value) { var index = 0; Serializer.EatMapStartChar(value, ref index); if (JsonTypeSerializer.IsEmptyMap(value, index)) { //return tupleType.CreateInstance(); return(ActivatorUtils.FastCreateInstance(tupleType)); } var genericArgs = tupleType.GetGenericArguments(); var argValues = new object[genericArgs.Length]; var valueLength = value.Length; while (index < valueLength) { var keyValue = Serializer.EatMapKey(value, ref index); Serializer.EatMapKeySeperator(value, ref index); var elementValue = Serializer.EatValue(value, ref index); if (!keyValue.HasValue) { continue; } var keyIndex = keyValue.Substring("Item".Length).ToInt() - 1; var parseFn = Serializer.GetParseStringSegmentFn(genericArgs[keyIndex]); argValues[keyIndex] = parseFn(elementValue); Serializer.EatItemSeperatorOrMapEndChar(value, ref index); } var ctor = tupleType.GetConstructors() .First(x => x.GetParameters().Length == genericArgs.Length); return(ctor.Invoke(argValues)); }
/// <summary> /// Parses the tuple. /// </summary> /// <param name="tupleType">Type of the tuple.</param> /// <param name="value">The value.</param> /// <returns>System.Object.</returns> public static object ParseTuple(Type tupleType, ReadOnlySpan <char> value) { var index = 0; Serializer.EatMapStartChar(value, ref index); if (JsonTypeSerializer.IsEmptyMap(value, index)) { return(tupleType.CreateInstance()); } var genericArgs = tupleType.GetGenericArguments(); var argValues = new object[genericArgs.Length]; var valueLength = value.Length; while (index < valueLength) { var keyValue = Serializer.EatMapKey(value, ref index); Serializer.EatMapKeySeperator(value, ref index); var elementValue = Serializer.EatValue(value, ref index); if (keyValue.IsEmpty) { continue; } var keyIndex = keyValue.Slice("Item".Length).ParseInt32() - 1; var parseFn = Serializer.GetParseStringSpanFn(genericArgs[keyIndex]); argValues[keyIndex] = parseFn(elementValue); Serializer.EatItemSeperatorOrMapEndChar(value, ref index); } var ctor = tupleType.GetConstructors() .First(x => x.GetParameters().Length == genericArgs.Length); return(ctor.Invoke(argValues)); }
private static object StringToType(Type type, string strType, EmptyCtorDelegate ctorFn, IDictionary <string, SetPropertyDelegate> setterMap, IDictionary <string, ParseStringDelegate> parseStringFnMap) { var index = 0; if (strType == null) { return(null); } if (!Serializer.EatMapStartChar(strType, ref index)) { throw new SerializationException(string.Format( "Type definitions should start with a '{0}', expecting serialized type '{1}', got string starting with: {2}", JsWriter.MapStartChar, type.Name, strType.Substring(0, strType.Length < 50 ? strType.Length : 50))); } if (strType == JsWriter.EmptyMap) { return(ctorFn()); } object instance = null; string propertyName; ParseStringDelegate parseStringFn; SetPropertyDelegate setterFn; var strTypeLength = strType.Length; while (index < strTypeLength) { propertyName = Serializer.EatMapKey(strType, ref index); Serializer.EatMapKeySeperator(strType, ref index); var propertyValueString = Serializer.EatValue(strType, ref index); if (propertyName == JsWriter.TypeAttr) { var typeName = Serializer.ParseString(propertyValueString); instance = ReflectionExtensions.CreateInstance(typeName); if (instance == null) { Tracer.Instance.WriteWarning("Could not find type: " + propertyValueString); } else { //If __type info doesn't match, ignore it. if (!type.IsAssignableFrom(instance.GetType())) { instance = null; } } Serializer.EatItemSeperatorOrMapEndChar(strType, ref index); continue; } if (instance == null) { instance = ctorFn(); } var propType = ExtractType(propertyValueString); if (propType != null) { try { var parseFn = Serializer.GetParseFn(propType); var propertyValue = parseFn(propertyValueString); setterMap.TryGetValue(propertyName, out setterFn); if (setterFn != null) { setterFn(instance, propertyValue); } Serializer.EatItemSeperatorOrMapEndChar(strType, ref index); continue; } catch (Exception) { Tracer.Instance.WriteWarning("WARN: failed to set dynamic property {0} with: {1}", propertyName, propertyValueString); } } parseStringFnMap.TryGetValue(propertyName, out parseStringFn); if (parseStringFn != null) { try { var propertyValue = parseStringFn(propertyValueString); setterMap.TryGetValue(propertyName, out setterFn); if (setterFn != null) { setterFn(instance, propertyValue); } } catch (Exception) { Tracer.Instance.WriteWarning("WARN: failed to set property {0} with: {1}", propertyName, propertyValueString); } } Serializer.EatItemSeperatorOrMapEndChar(strType, ref index); } return(instance); }