public static Hashtable ParseHashtable(string value) { var index = VerifyAndGetStartIndex(value, typeof(Hashtable)); var result = new Hashtable(); if (JsonTypeSerializer.IsEmptyMap(value, index)) { return(result); } 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 mapKey = keyValue; var mapValue = elementValue; result[mapKey] = mapValue; Serializer.EatItemSeperatorOrMapEndChar(value, ref index); } return(result); }
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)); }
public static JsonObject ParseJsonObject(StringSegment value) { var index = VerifyAndGetStartIndex(value, typeof(JsonObject)); var result = new JsonObject(); if (JsonTypeSerializer.IsEmptyMap(value, index)) { return(result); } 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 mapKey = keyValue.Value; var mapValue = elementValue.Value; result[mapKey] = mapValue; Serializer.EatItemSeperatorOrMapEndChar(value, ref index); } return(result); }
public static Dictionary <string, string> ParseStringDictionary(string value) { var index = VerifyAndGetStartIndex(value, typeof(Dictionary <string, string>)); var result = new Dictionary <string, string>(); if (JsonTypeSerializer.IsEmptyMap(value, index)) { return(result); } 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 mapKey = Serializer.UnescapeString(keyValue); var mapValue = Serializer.UnescapeString(elementValue); result[mapKey] = mapValue; Serializer.EatItemSeperatorOrMapEndChar(value, ref index); } return(result); }
static AotConfig() { jsonSerializer = new JsonTypeSerializer(); jsvSerializer = new JsvTypeSerializer(); jsonReader = new JsReader <JsonTypeSerializer>(); jsonWriter = new JsWriter <JsonTypeSerializer>(); jsvReader = new JsReader <JsvTypeSerializer>(); jsvWriter = new JsWriter <JsvTypeSerializer>(); }
public static IDictionary ParseIDictionary(StringSegment value, Type dictType) { if (!value.HasValue) { return(null); } var index = VerifyAndGetStartIndex(value, dictType); var valueParseMethod = Serializer.GetParseStringSegmentFn(typeof(object)); if (valueParseMethod == null) { return(null); } //var to = (IDictionary)dictType.CreateInstance(); var to = ActivatorUtils.FastCreateInstance <IDictionary>(dictType); if (JsonTypeSerializer.IsEmptyMap(value, index)) { return(to); } var valueLength = value.Length; while (index < valueLength) { var keyValue = Serializer.EatMapKey(value, ref index); Serializer.EatMapKeySeperator(value, ref index); var elementStartIndex = index; var elementValue = Serializer.EatTypeValue(value, ref index); if (!keyValue.HasValue) { continue; } var mapKey = valueParseMethod(keyValue); if (elementStartIndex < valueLength) { Serializer.EatWhitespace(value, ref elementStartIndex); to[mapKey] = DeserializeType <TSerializer> .ParsePrimitive(elementValue.Value, value.GetChar(elementStartIndex)); } else { to[mapKey] = valueParseMethod(elementValue); } Serializer.EatItemSeperatorOrMapEndChar(value, ref index); } return(to); }
public static object parseSpan(ReadOnlySpan <char> json) { if (json.Length == 0) { return(null); } var firstChar = json[0]; bool isEscapedJsonString(ReadOnlySpan <char> js) => js.StartsWith(@"{\") || js.StartsWith(@"[{\"); if (firstChar >= '0' && firstChar <= '9') { try { var longValue = MemoryProvider.Instance.ParseInt64(json); return(longValue >= int.MinValue && longValue <= int.MaxValue ? (int)longValue : longValue); } catch {} if (json.TryParseDouble(out var doubleValue)) { return(doubleValue); } } else if (firstChar == '{' || firstChar == '[' && !isEscapedJsonString(json.TrimStart())) { json.ParseJsToken(out var token); return(token.Evaluate(JS.CreateScope())); } else if (json.Length == 4) { if (firstChar == 't' && json[1] == 'r' && json[2] == 'u' && json[3] == 'e') { return(true); } if (firstChar == 'n' && json[1] == 'u' && json[2] == 'l' && json[3] == 'l') { return(null); } } else if (json.Length == 5 && firstChar == 'f' && json[1] == 'a' && json[2] == 'l' && json[3] == 's' && json[4] == 'e') { return(false); } var unescapedString = JsonTypeSerializer.Unescape(json); return(unescapedString.ToString()); }
public static IDynamicMetaObjectProvider ParseDynamic(StringSegment value) { var index = VerifyAndGetStartIndex(value, typeof(ExpandoObject)); var result = new ExpandoObject(); if (JsonTypeSerializer.IsEmptyMap(value)) { return(result); } var container = (IDictionary <string, object>)result; var tryToParsePrimitiveTypes = JsConfig.TryToParsePrimitiveTypeValues; 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); var mapKey = Serializer.UnescapeString(keyValue).Value; if (JsonUtils.IsJsObject(elementValue)) { container[mapKey] = ParseDynamic(elementValue); } else if (JsonUtils.IsJsArray(elementValue)) { container[mapKey] = DeserializeList <List <object>, TSerializer> .ParseStringSegment(elementValue); } else if (tryToParsePrimitiveTypes) { container[mapKey] = DeserializeType <TSerializer> .ParsePrimitive(elementValue) ?? Serializer.UnescapeString(elementValue); } else { container[mapKey] = Serializer.UnescapeString(elementValue); } Serializer.EatItemSeperatorOrMapEndChar(value, ref index); } return(result); }
public static object ParseKeyValuePair <TKey, TValue>( ReadOnlySpan <char> value, Type createMapType, ParseStringSpanDelegate parseKeyFn, ParseStringSpanDelegate parseValueFn) { if (value.IsEmpty) { return(default(KeyValuePair <TKey, TValue>)); } var index = VerifyAndGetStartIndex(value, createMapType); if (JsonTypeSerializer.IsEmptyMap(value, index)) { return(new KeyValuePair <TKey, TValue>()); } var keyValue = default(TKey); var valueValue = default(TValue); var valueLength = value.Length; while (index < valueLength) { var key = Serializer.EatMapKey(value, ref index); Serializer.EatMapKeySeperator(value, ref index); var keyElementValue = Serializer.EatTypeValue(value, ref index); if (key.CompareIgnoreCase("key".AsSpan())) { keyValue = (TKey)parseKeyFn(keyElementValue); } else if (key.CompareIgnoreCase("value".AsSpan())) { valueValue = (TValue)parseValueFn(keyElementValue); } else { throw new SerializationException("Incorrect KeyValuePair property: " + key.ToString()); } Serializer.EatItemSeperatorOrMapEndChar(value, ref index); } return(new KeyValuePair <TKey, TValue>(keyValue, valueValue)); }
public static object ParseKeyValuePair <TKey, TValue>( string value, Type createMapType, ParseStringDelegate parseKeyFn, ParseStringDelegate parseValueFn) { if (value == null) { return(default(KeyValuePair <TKey, TValue>)); } var index = 1; if (JsonTypeSerializer.IsEmptyMap(value)) { return(new KeyValuePair <TKey, TValue>()); } var keyValue = default(TKey); var valueValue = default(TValue); var valueLength = value.Length; while (index < valueLength) { var key = Serializer.EatMapKey(value, ref index); Serializer.EatMapKeySeperator(value, ref index); var keyElementValue = Serializer.EatTypeValue(value, ref index); if (string.Compare(key, "key", StringComparison.InvariantCultureIgnoreCase) == 0) { keyValue = (TKey)parseKeyFn(keyElementValue); } else if (string.Compare(key, "value", StringComparison.InvariantCultureIgnoreCase) == 0) { valueValue = (TValue)parseValueFn(keyElementValue); } else { throw new SerializationException("Incorrect KeyValuePair property: " + key); } Serializer.EatItemSeperatorOrMapEndChar(value, ref index); } return(new KeyValuePair <TKey, TValue>(keyValue, valueValue)); }
/// <summary> /// Serializes using custom methods (JsonAdaptor, IJsonable, Type serializer). /// </summary> private void SerializeCustomData(object data) { Type dataType = data.GetType(); JsonObject serializedData = null; // Serialize objects registered to adaptor. serializedData = JsonAdaptor.Serialize(dataType, data); if (serializedData != null) { SerializeObject(serializedData); return; } // Serialize jsonable objects IJsonable jsonableObject = data as IJsonable; if (jsonableObject != null) { serializedData = jsonableObject.ToJsonObject(); if (serializedData != null) { SerializeObject(jsonableObject.ToJsonObject()); return; } } // Use reflection. serializedData = JsonTypeSerializer.Serialize(dataType, data); if (serializedData != null) { SerializeObject(serializedData); return; } //This is when all the above methods fail. //Just return the stringified data. sb.Append('"'); AppendEscapedString(data.ToString()); sb.Append('"'); }
public static T ParseInheritedJsonObject <T>(ReadOnlySpan <char> value) where T : JsonObject, new() { if (value.Length == 0) { return(null); } var index = VerifyAndGetStartIndex(value, typeof(T)); var result = new T(); if (JsonTypeSerializer.IsEmptyMap(value, index)) { return(result); } 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 mapKey = keyValue.ToString(); var mapValue = elementValue.Value(); result[mapKey] = mapValue; Serializer.EatItemSeperatorOrMapEndChar(value, ref index); } return(result); }
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)); }
public static IDictionary <TKey, TValue> ParseDictionary <TKey, TValue>( StringSegment value, Type createMapType, ParseStringSegmentDelegate parseKeyFn, ParseStringSegmentDelegate parseValueFn) { if (!value.HasValue) { return(null); } var tryToParseItemsAsDictionaries = JsConfig.ConvertObjectTypesIntoStringDictionary && typeof(TValue) == typeof(object); var tryToParseItemsAsPrimitiveTypes = JsConfig.TryToParsePrimitiveTypeValues && typeof(TValue) == typeof(object); var index = VerifyAndGetStartIndex(value, createMapType); var to = createMapType == null ? new Dictionary <TKey, TValue>() : (IDictionary <TKey, TValue>)createMapType.CreateInstance(); if (JsonTypeSerializer.IsEmptyMap(value, index)) { return(to); } var valueLength = value.Length; while (index < valueLength) { var keyValue = Serializer.EatMapKey(value, ref index); Serializer.EatMapKeySeperator(value, ref index); var elementStartIndex = index; var elementValue = Serializer.EatTypeValue(value, ref index); if (!keyValue.HasValue) { continue; } var mapKey = (TKey)parseKeyFn(keyValue); if (tryToParseItemsAsDictionaries) { Serializer.EatWhitespace(value, ref elementStartIndex); if (elementStartIndex < valueLength && value.GetChar(elementStartIndex) == JsWriter.MapStartChar) { var tmpMap = ParseDictionary <TKey, TValue>(elementValue, createMapType, parseKeyFn, parseValueFn); if (tmpMap != null && tmpMap.Count > 0) { to[mapKey] = (TValue)tmpMap; } } else if (elementStartIndex < valueLength && value.GetChar(elementStartIndex) == JsWriter.ListStartChar) { to[mapKey] = (TValue)DeserializeList <List <object>, TSerializer> .ParseStringSegment(elementValue); } else { to[mapKey] = (TValue)(tryToParseItemsAsPrimitiveTypes && elementStartIndex < valueLength ? DeserializeType <TSerializer> .ParsePrimitive(elementValue.Value, value.GetChar(elementStartIndex)) : parseValueFn(elementValue)); } } else { if (tryToParseItemsAsPrimitiveTypes && elementStartIndex < valueLength) { Serializer.EatWhitespace(value, ref elementStartIndex); to[mapKey] = (TValue)DeserializeType <TSerializer> .ParsePrimitive(elementValue.Value, value.GetChar(elementStartIndex)); } else { to[mapKey] = (TValue)parseValueFn(elementValue); } } Serializer.EatItemSeperatorOrMapEndChar(value, ref index); } return(to); }
internal static object StringToType( TypeConfig typeConfig, StringSegment strType, EmptyCtorDelegate ctorFn, Dictionary <HashedStringSegment, TypeAccessor> typeAccessorMap) { var index = 0; var type = typeConfig.Type; if (!strType.HasValue) { return(null); } var buffer = strType.Buffer; var offset = strType.Offset; var strTypeLength = strType.Length; //if (!Serializer.EatMapStartChar(strType, ref index)) for (; index < strTypeLength; index++) { if (!JsonUtils.IsWhiteSpace(buffer[offset + index])) { break; } } //Whitespace inline if (buffer[offset + index] != JsWriter.MapStartChar) { throw DeserializeTypeRef.CreateSerializationError(type, strType.Value); } index++; if (JsonTypeSerializer.IsEmptyMap(strType, index)) { return(ctorFn()); } object instance = null; var propertyResolver = JsConfig.PropertyConvention == PropertyConvention.Lenient ? ParseUtils.LenientPropertyNameResolver : ParseUtils.DefaultPropertyNameResolver; while (index < strTypeLength) { var propertyName = JsonTypeSerializer.ParseJsonString(strType, ref index); //Serializer.EatMapKeySeperator(strType, ref index); for (; index < strTypeLength; index++) { if (!JsonUtils.IsWhiteSpace(buffer[offset + index])) { break; } } //Whitespace inline if (strTypeLength != index) { index++; } var propertyValueStr = Serializer.EatValue(strType, ref index); var possibleTypeInfo = propertyValueStr != null && propertyValueStr.Length > 1; //if we already have an instance don't check type info, because then we will have a half deserialized object //we could throw here or just use the existing instance. if (instance == null && possibleTypeInfo && propertyName == typeAttr) { var explicitTypeName = Serializer.ParseString(propertyValueStr); var explicitType = JsConfig.TypeFinder(explicitTypeName); if (explicitType == null || explicitType.IsInterface || explicitType.IsAbstract) { Tracer.Instance.WriteWarning("Could not find type: " + propertyValueStr); } else if (!type.IsAssignableFrom(explicitType)) { Tracer.Instance.WriteWarning("Could not assign type: " + propertyValueStr); } else { JsWriter.AssertAllowedRuntimeType(explicitType); instance = explicitType.CreateInstance(); } if (instance != null) { //If __type info doesn't match, ignore it. if (!type.IsInstanceOfType(instance)) { instance = null; } else { var derivedType = instance.GetType(); if (derivedType != type) { var derivedTypeConfig = new TypeConfig(derivedType); var map = DeserializeTypeRef.GetTypeAccessorMap(derivedTypeConfig, Serializer); if (map != null) { typeAccessorMap = map; } } } } Serializer.EatItemSeperatorOrMapEndChar(strType, ref index); continue; } if (instance == null) { instance = ctorFn(); } var typeAccessor = propertyResolver.GetTypeAccessorForProperty(propertyName, typeAccessorMap); var propType = possibleTypeInfo && propertyValueStr.GetChar(0) == '_' ? TypeAccessor.ExtractType(Serializer, propertyValueStr) : null; if (propType != null) { try { if (typeAccessor != null) { //var parseFn = Serializer.GetParseFn(propType); var parseFn = JsonReader.GetParseStringSegmentFn(propType); var propertyValue = parseFn(propertyValueStr); if (typeConfig.OnDeserializing != null) { propertyValue = typeConfig.OnDeserializing(instance, propertyName.Value, propertyValue); } typeAccessor.SetProperty(instance, propertyValue); } //Serializer.EatItemSeperatorOrMapEndChar(strType, ref index); for (; index < strTypeLength; index++) { if (!JsonUtils.IsWhiteSpace(buffer[offset + index])) { break; } } //Whitespace inline if (index != strTypeLength) { var success = buffer[offset + index] == JsWriter.ItemSeperator || buffer[offset + index] == JsWriter.MapEndChar; index++; if (success) { for (; index < strTypeLength; index++) { if (!JsonUtils.IsWhiteSpace(buffer[offset + index])) { break; } } //Whitespace inline } } continue; } catch (Exception e) { JsConfig.OnDeserializationError?.Invoke(instance, propType, propertyName.Value, propertyValueStr.Value, e); if (JsConfig.ThrowOnDeserializationError) { throw DeserializeTypeRef.GetSerializationException(propertyName.Value, propertyValueStr.Value, propType, e); } else { Tracer.Instance.WriteWarning("WARN: failed to set dynamic property {0} with: {1}", propertyName, propertyValueStr.Value); } } } if (typeAccessor?.GetProperty != null && typeAccessor.SetProperty != null) { try { var propertyValue = typeAccessor.GetProperty(propertyValueStr); if (typeConfig.OnDeserializing != null) { propertyValue = typeConfig.OnDeserializing(instance, propertyName.Value, propertyValue); } typeAccessor.SetProperty(instance, propertyValue); } catch (NotSupportedException) { throw; } catch (Exception e) { JsConfig.OnDeserializationError?.Invoke(instance, propType ?? typeAccessor.PropertyType, propertyName.Value, propertyValueStr.Value, e); if (JsConfig.ThrowOnDeserializationError) { throw DeserializeTypeRef.GetSerializationException(propertyName.Value, propertyValueStr.Value, typeAccessor.PropertyType, e); } else { Tracer.Instance.WriteWarning("WARN: failed to set property {0} with: {1}", propertyName, propertyValueStr.Value); } } } else { // the property is not known by the DTO typeConfig.OnDeserializing?.Invoke(instance, propertyName.Value, propertyValueStr.Value); } //Serializer.EatItemSeperatorOrMapEndChar(strType, ref index); for (; index < strTypeLength; index++) { if (!JsonUtils.IsWhiteSpace(buffer[offset + index])) { break; } } //Whitespace inline if (index != strType.Length) { var success = buffer[offset + index] == JsWriter.ItemSeperator || buffer[offset + index] == JsWriter.MapEndChar; index++; if (success) { for (; index < strTypeLength; index++) { if (!JsonUtils.IsWhiteSpace(buffer[offset + index])) { break; } } //Whitespace inline } } } return(instance); }
public void Import_from_UserVoice() { string oauthKey = Environment.GetEnvironmentVariable("USERVOICE_KEY"); //required to get emails const int resultsPerPage = 20; var i = 0; List <object> suggestions = null; var client = new JsonServiceClient("http://localhost:16325") { BearerToken = Environment.GetEnvironmentVariable("TECHSTACKS_DEVELOPMENT_TOKEN") }; do { var url = $"https://servicestack.uservoice.com/api/v1/forums/176786/suggestions.json?per_page={resultsPerPage}&page={++i}&oauth_consumer_key={oauthKey}"; var json = url.GetJsonFromUrl(req => req.AddBearerToken(oauthKey)); var response = (Dictionary <string, object>)JSON.parse(json); suggestions = (List <object>)response["suggestions"]; var userVoiceUsers = new Dictionary <string, UserVoiceUser>(StringComparer.OrdinalIgnoreCase); var techstacksUsers = new Dictionary <string, UserRef>(StringComparer.OrdinalIgnoreCase); UserVoiceUser toUser(object oUser) { if (!(oUser is Dictionary <string, object> user)) { return(null); } if (!user.TryGetValue("email", out var oEmail)) { "EMAIL NOT FOUND:".Print(); user.PrintDump(); return(null); } var email = (string)oEmail; if (!userVoiceUsers.ContainsKey("user")) { return(new UserVoiceUser { Id = (int)user["id"], Name = (string)user["name"], Email = email, AvatarUrl = (string)user["avatar_url"], CreatedAt = user["created_at"].ToString().ConvertTo <DateTime>(), UpdatedAt = user["updated_at"].ToString().ConvertTo <DateTime>(), }); } return(null); } foreach (var oSuggestion in suggestions) { var request = new ImportUserVoiceSuggestion { OrganizationId = 1, }; try { if (oSuggestion is Dictionary <string, object> suggestion) { request.Url = (string)suggestion["url"]; request.Id = (int)suggestion["id"]; request.State = (string)suggestion["state"]; request.Title = (string)suggestion["title"]; //Can be null and just have title request.Text = suggestion["text"] as string; if (request.Text != null) { request.Text = JsonTypeSerializer.Unescape(request.Text); } request.FormattedText = suggestion["formatted_text"] as string; if (request.FormattedText != null) { request.FormattedText = JsonTypeSerializer.Unescape(request.FormattedText); } request.VoteCount = (int)suggestion["vote_count"]; request.CreatedAt = suggestion["created_at"].ToString().ConvertTo <DateTime>(); request.UpdatedAt = suggestion["updated_at"].ToString().ConvertTo <DateTime>(); if (suggestion.TryGetValue("category", out var category)) { request.Category = category as string; } if (suggestion.TryGetValue("topic", out var oTopic) && oTopic is Dictionary <string, object> topic) { request.TopicId = (int)topic["id"]; } if (suggestion.TryGetValue("creator", out var creator)) { request.Creator = toUser(creator); } if (suggestion.TryGetValue("closed_at", out var oClosedAt) && oClosedAt is string closeAt) { request.ClosedAt = oClosedAt.ConvertTo <DateTime>(); } if (suggestion.TryGetValue("status_changed_by", out var statusUser)) { request.StatusChangedBy = toUser(statusUser); } if (suggestion.TryGetValue("status", out var oStatus) && oStatus is Dictionary <string, object> status) { var statusKey = (string)status["key"]; if (statusKey != "published") { request.StatusKey = statusKey; request.StatusHexColor = (string)status["hex_color"]; } } if (suggestion.TryGetValue("response", out var statusResponse) && statusResponse is Dictionary <string, object> oStatusResponse) { request.Response = new UserVoiceComment { Text = (string)oStatusResponse["text"], FormattedText = (string)oStatusResponse["formatted_text"], CreatedAt = oStatusResponse["created_at"].ToString().ConvertTo <DateTime>(), }; if (request.Response.Text != null) { request.Response.Text = JsonTypeSerializer.Unescape(request.Response.Text); } if (request.Response.FormattedText != null) { request.Response.FormattedText = JsonTypeSerializer.Unescape(request.Response.FormattedText); } if (oStatusResponse.TryGetValue("creator", out var responseCreator)) { request.Response.Creator = toUser(responseCreator); } } $"Importing Suggestion {request.Id}: {request.Title}".Print(); var newPost = client.Post(request); $"Imported Post {newPost.PostId}: {newPost.PostSlug}".Print(); } } catch (Exception ex) { $"Could not import suggestion: {ex.Message}\n{ex.StackTrace}".Print(); oSuggestion.PrintDump(); } } } while (suggestions.Count >= resultsPerPage); }
internal static object StringToType( Type type, string strType, EmptyCtorDelegate ctorFn, Dictionary <string, TypeAccessor> typeAccessorMap) { var index = 0; if (strType == null) { return(null); } //if (!Serializer.EatMapStartChar(strType, ref index)) for (; index < strType.Length; index++) { var c = strType[index]; if (c >= JsonTypeSerializer.WhiteSpaceFlags.Length || !JsonTypeSerializer.WhiteSpaceFlags[c]) { break; } } //Whitespace inline if (strType[index++] != JsWriter.MapStartChar) { throw DeserializeTypeRef.CreateSerializationError(type, strType); } if (JsonTypeSerializer.IsEmptyMap(strType)) { return(ctorFn()); } object instance = null; var strTypeLength = strType.Length; while (index < strTypeLength) { var propertyName = JsonTypeSerializer.ParseJsonString(strType, ref index); //Serializer.EatMapKeySeperator(strType, ref index); for (; index < strType.Length; index++) { var c = strType[index]; if (c >= JsonTypeSerializer.WhiteSpaceFlags.Length || !JsonTypeSerializer.WhiteSpaceFlags[c]) { break; } } //Whitespace inline if (strType.Length != index) { index++; } var propertyValueStr = Serializer.EatValue(strType, ref index); var possibleTypeInfo = propertyValueStr != null && propertyValueStr.Length > 1; if (possibleTypeInfo && propertyName == JsWriter.TypeAttr) { var explicitTypeName = Serializer.ParseString(propertyValueStr); var explicitType = Type.GetType(explicitTypeName); if (explicitType != null && !explicitType.IsInterface && !explicitType.IsAbstract) { instance = explicitType.CreateInstance(); } if (instance == null) { Tracer.Instance.WriteWarning("Could not find type: " + propertyValueStr); } else { //If __type info doesn't match, ignore it. if (!type.IsInstanceOfType(instance)) { instance = null; } else { var derivedType = instance.GetType(); if (derivedType != type) { var derivedTypeConfig = new TypeConfig(derivedType); var map = DeserializeTypeRef.GetTypeAccessorMap(derivedTypeConfig, Serializer); if (map != null) { typeAccessorMap = map; } } } } Serializer.EatItemSeperatorOrMapEndChar(strType, ref index); continue; } if (instance == null) { instance = ctorFn(); } TypeAccessor typeAccessor; typeAccessorMap.TryGetValue(propertyName, out typeAccessor); var propType = possibleTypeInfo && propertyValueStr[0] == '_' ? TypeAccessor.ExtractType(Serializer, propertyValueStr) : null; if (propType != null) { try { if (typeAccessor != null) { //var parseFn = Serializer.GetParseFn(propType); var parseFn = JsonReader.GetParseFn(propType); var propertyValue = parseFn(propertyValueStr); typeAccessor.SetProperty(instance, propertyValue); } //Serializer.EatItemSeperatorOrMapEndChar(strType, ref index); for (; index < strType.Length; index++) { var c = strType[index]; if (c >= JsonTypeSerializer.WhiteSpaceFlags.Length || !JsonTypeSerializer.WhiteSpaceFlags[c]) { break; } } //Whitespace inline if (index != strType.Length) { var success = strType[index] == JsWriter.ItemSeperator || strType[index] == JsWriter.MapEndChar; index++; if (success) { for (; index < strType.Length; index++) { var c = strType[index]; if (c >= JsonTypeSerializer.WhiteSpaceFlags.Length || !JsonTypeSerializer.WhiteSpaceFlags[c]) { break; } } //Whitespace inline } } continue; } catch (Exception e) { if (JsConfig.ThrowOnDeserializationError) { throw DeserializeTypeRef.GetSerializationException(propertyName, propertyValueStr, propType, e); } else { Tracer.Instance.WriteWarning("WARN: failed to set dynamic property {0} with: {1}", propertyName, propertyValueStr); } } } if (typeAccessor != null && typeAccessor.GetProperty != null && typeAccessor.SetProperty != null) { try { var propertyValue = typeAccessor.GetProperty(propertyValueStr); typeAccessor.SetProperty(instance, propertyValue); } catch (Exception e) { if (JsConfig.ThrowOnDeserializationError) { throw DeserializeTypeRef.GetSerializationException(propertyName, propertyValueStr, typeAccessor.PropertyType, e); } else { Tracer.Instance.WriteWarning("WARN: failed to set property {0} with: {1}", propertyName, propertyValueStr); } } } //Serializer.EatItemSeperatorOrMapEndChar(strType, ref index); for (; index < strType.Length; index++) { var c = strType[index]; if (c >= JsonTypeSerializer.WhiteSpaceFlags.Length || !JsonTypeSerializer.WhiteSpaceFlags[c]) { break; } } //Whitespace inline if (index != strType.Length) { var success = strType[index] == JsWriter.ItemSeperator || strType[index] == JsWriter.MapEndChar; index++; if (success) { for (; index < strType.Length; index++) { var c = strType[index]; if (c >= JsonTypeSerializer.WhiteSpaceFlags.Length || !JsonTypeSerializer.WhiteSpaceFlags[c]) { break; } } //Whitespace inline } } } return(instance); }
static JsonAotConfig() { serializer = new JsonTypeSerializer(); reader = new JsReader <JsonTypeSerializer>(); writer = new JsWriter <JsonTypeSerializer>(); }
internal static object StringToType( TypeConfig typeConfig, string strType, EmptyCtorDelegate ctorFn, Dictionary <string, TypeAccessor> typeAccessorMap) { var index = 0; var type = typeConfig.Type; if (strType == null) { return(null); } //if (!Serializer.EatMapStartChar(strType, ref index)) if (strType[index++] != JsWriter.MapStartChar) { throw DeserializeTypeRef.CreateSerializationError(type, strType); } if (JsonTypeSerializer.IsEmptyMap(strType)) { return(ctorFn()); } object instance = null; var strTypeLength = strType.Length; while (index < strTypeLength) { var propertyName = Serializer.EatMapKey(strType, ref index); //Serializer.EatMapKeySeperator(strType, ref index); index++; var propertyValueStr = Serializer.EatValue(strType, ref index); var possibleTypeInfo = propertyValueStr != null && propertyValueStr.Length > 1; if (possibleTypeInfo && propertyName == JsWriter.TypeAttr) { var explicitTypeName = Serializer.ParseString(propertyValueStr); var explicitType = AssemblyUtils.FindType(explicitTypeName); if (explicitType == null || explicitType.IsInterface() || explicitType.IsAbstract()) { Tracer.Instance.WriteWarning("Could not find type: " + propertyValueStr); } else if (!type.IsAssignableFrom(explicitType)) { Tracer.Instance.WriteWarning("Could not assign type: " + propertyValueStr); } else { instance = explicitType.CreateInstance(); } if (instance != null) { var derivedType = instance.GetType(); if (derivedType != type) { var derivedTypeConfig = new TypeConfig(derivedType); var map = DeserializeTypeRef.GetTypeAccessorMap(derivedTypeConfig, Serializer); if (map != null) { typeAccessorMap = map; } } } //Serializer.EatItemSeperatorOrMapEndChar(strType, ref index); if (index != strType.Length) { index++; } continue; } if (instance == null) { instance = ctorFn(); } TypeAccessor typeAccessor; typeAccessorMap.TryGetValue(propertyName, out typeAccessor); var propType = possibleTypeInfo && propertyValueStr[0] == '_' ? TypeAccessor.ExtractType(Serializer, propertyValueStr) : null; if (propType != null) { try { if (typeAccessor != null) { var parseFn = Serializer.GetParseFn(propType); var propertyValue = parseFn(propertyValueStr); if (typeConfig.OnDeserializing != null) { propertyValue = typeConfig.OnDeserializing(instance, propertyName, propertyValue); } typeAccessor.SetProperty(instance, propertyValue); } //Serializer.EatItemSeperatorOrMapEndChar(strType, ref index); if (index != strType.Length) { index++; } continue; } catch (Exception e) { if (JsConfig.HasOnDeserializationErrorHandler) { JsConfig.OnDeserializationError(instance, propType, propertyName, propertyValueStr, e); } if (JsConfig.ThrowOnDeserializationError) { throw DeserializeTypeRef.GetSerializationException(propertyName, propertyValueStr, propType, e); } Tracer.Instance.WriteWarning("WARN: failed to set dynamic property {0} with: {1}", propertyName, propertyValueStr); } } if (typeAccessor != null && typeAccessor.GetProperty != null && typeAccessor.SetProperty != null) { try { var propertyValue = typeAccessor.GetProperty(propertyValueStr); if (typeConfig.OnDeserializing != null) { propertyValue = typeConfig.OnDeserializing(instance, propertyName, propertyValue); } typeAccessor.SetProperty(instance, propertyValue); } catch (Exception e) { if (JsConfig.HasOnDeserializationErrorHandler) { JsConfig.OnDeserializationError(instance, typeAccessor.PropertyType, propertyName, propertyValueStr, e); } if (JsConfig.ThrowOnDeserializationError) { throw DeserializeTypeRef.GetSerializationException(propertyName, propertyValueStr, typeAccessor.PropertyType, e); } Tracer.Instance.WriteWarning("WARN: failed to set property {0} with: {1}", propertyName, propertyValueStr); } } else if (typeConfig.OnDeserializing != null) { // the property is not known by the DTO typeConfig.OnDeserializing(instance, propertyName, propertyValueStr); } //Serializer.EatItemSeperatorOrMapEndChar(strType, ref index); if (index != strType.Length) { index++; } } return(instance); }
internal static object StringToType(ReadOnlySpan <char> strType, TypeConfig typeConfig, EmptyCtorDelegate ctorFn, KeyValuePair <string, TypeAccessor>[] typeAccessors) { var index = 0; var type = typeConfig.Type; if (strType.IsEmpty) { return(null); } //if (!Serializer.EatMapStartChar(strType, ref index)) if (strType[index++] != JsWriter.MapStartChar) { throw DeserializeTypeRef.CreateSerializationError(type, strType.ToString()); } if (JsonTypeSerializer.IsEmptyMap(strType)) { return(ctorFn()); } var config = JsConfig.GetConfig(); object instance = null; var lenient = config.PropertyConvention == PropertyConvention.Lenient; var strTypeLength = strType.Length; while (index < strTypeLength) { var propertyName = Serializer.EatMapKey(strType, ref index).Trim(); //Serializer.EatMapKeySeperator(strType, ref index); index++; var propertyValueStr = Serializer.EatValue(strType, ref index); var possibleTypeInfo = propertyValueStr != null && propertyValueStr.Length > 1; if (possibleTypeInfo && propertyName.Equals(typeAttr.Span, StringComparison.OrdinalIgnoreCase)) { var explicitTypeName = Serializer.ParseString(propertyValueStr); var explicitType = config.TypeFinder(explicitTypeName); if (explicitType == null || explicitType.IsInterface || explicitType.IsAbstract) { Tracer.Instance.WriteWarning("Could not find type: " + propertyValueStr.ToString()); } else if (!type.IsAssignableFrom(explicitType)) { Tracer.Instance.WriteWarning("Could not assign type: " + propertyValueStr.ToString()); } else { JsWriter.AssertAllowedRuntimeType(explicitType); instance = ActivatorUtils.FastCreateInstance(explicitType); } if (instance != null) { //If __type info doesn't match, ignore it. if (!type.IsInstanceOfType(instance)) { instance = null; } else { var derivedType = instance.GetType(); if (derivedType != type) { var map = DeserializeTypeRef.GetCachedTypeAccessors(derivedType, Serializer); if (map != null) { typeAccessors = map; } } } } //Serializer.EatItemSeperatorOrMapEndChar(strType, ref index); if (index != strType.Length) { index++; } continue; } if (instance == null) { instance = ctorFn(); } var typeAccessor = typeAccessors.Get(propertyName, lenient); var propType = possibleTypeInfo && propertyValueStr[0] == '_' ? TypeAccessor.ExtractType(Serializer, propertyValueStr) : null; if (propType != null) { try { if (typeAccessor != null) { var parseFn = Serializer.GetParseStringSpanFn(propType); var propertyValue = parseFn(propertyValueStr); if (typeConfig.OnDeserializing != null) { propertyValue = typeConfig.OnDeserializing(instance, propertyName.ToString(), propertyValue); } typeAccessor.SetProperty(instance, propertyValue); } //Serializer.EatItemSeperatorOrMapEndChar(strType, ref index); if (index != strType.Length) { index++; } continue; } catch (Exception e) { config.OnDeserializationError?.Invoke(instance, propType, propertyName.ToString(), propertyValueStr.ToString(), e); if (config.ThrowOnError) { throw DeserializeTypeRef.GetSerializationException(propertyName.ToString(), propertyValueStr.ToString(), propType, e); } else { Tracer.Instance.WriteWarning("WARN: failed to set dynamic property {0} with: {1}", propertyName.ToString(), propertyValueStr.ToString()); } } } if (typeAccessor?.GetProperty != null && typeAccessor.SetProperty != null) { try { var propertyValue = typeAccessor.GetProperty(propertyValueStr); if (typeConfig.OnDeserializing != null) { propertyValue = typeConfig.OnDeserializing(instance, propertyName.ToString(), propertyValue); } typeAccessor.SetProperty(instance, propertyValue); } catch (NotSupportedException) { throw; } catch (Exception e) { config.OnDeserializationError?.Invoke(instance, propType ?? typeAccessor.PropertyType, propertyName.ToString(), propertyValueStr.ToString(), e); if (config.ThrowOnError) { throw DeserializeTypeRef.GetSerializationException(propertyName.ToString(), propertyValueStr.ToString(), propType, e); } else { Tracer.Instance.WriteWarning("WARN: failed to set property {0} with: {1}", propertyName.ToString(), propertyValueStr.ToString()); } } } else { // the property is not known by the DTO typeConfig.OnDeserializing?.Invoke(instance, propertyName.ToString(), propertyValueStr.ToString()); } //Serializer.EatItemSeperatorOrMapEndChar(strType, ref index); if (index != strType.Length) { index++; } } return(instance); }
private static ParseStringSpanDelegate GetParseStringSpanFn() { var nullableType = Nullable.GetUnderlyingType(typeof(T)); if (nullableType == null) { var typeCode = typeof(T).GetTypeCode(); switch (typeCode) { case TypeCode.Boolean: return(value => value.ParseBoolean()); case TypeCode.SByte: return(SignedInteger <sbyte> .ParseObject); case TypeCode.Byte: return(UnsignedInteger <byte> .ParseObject); case TypeCode.Int16: return(SignedInteger <short> .ParseObject); case TypeCode.UInt16: return(UnsignedInteger <ushort> .ParseObject); case TypeCode.Int32: return(SignedInteger <int> .ParseObject); case TypeCode.UInt32: return(UnsignedInteger <uint> .ParseObject); case TypeCode.Int64: return(SignedInteger <long> .ParseObject); case TypeCode.UInt64: return(UnsignedInteger <ulong> .ParseObject); case TypeCode.Single: return(value => MemoryProvider.Instance.ParseFloat(value)); case TypeCode.Double: return(value => MemoryProvider.Instance.ParseDouble(value)); case TypeCode.Decimal: return(value => MemoryProvider.Instance.ParseDecimal(value)); case TypeCode.DateTime: return(value => DateTimeSerializer.ParseShortestXsdDateTime(value.ToString())); case TypeCode.Char: return(value => value.Length == 0 ? (char)0 : value.Length == 1 ? value[0] : JsonTypeSerializer.Unescape(value)[0]); } if (typeof(T) == typeof(Guid)) { return(value => value.ParseGuid()); } if (typeof(T) == typeof(DateTimeOffset)) { return(value => DateTimeSerializer.ParseDateTimeOffset(value.ToString())); } if (typeof(T) == typeof(TimeSpan)) { return(value => DateTimeSerializer.ParseTimeSpan(value.ToString())); } #if NET6_0 if (typeof(T) == typeof(DateOnly)) { return(value => DateOnly.FromDateTime(DateTimeSerializer.ParseShortestXsdDateTime(value.ToString()))); } if (typeof(T) == typeof(TimeOnly)) { return(value => TimeOnly.FromTimeSpan(DateTimeSerializer.ParseTimeSpan(value.ToString()))); } #endif } else { var typeCode = nullableType.GetTypeCode(); switch (typeCode) { case TypeCode.Boolean: return(value => value.IsNullOrEmpty() ? (bool?)null : value.ParseBoolean()); case TypeCode.SByte: return(SignedInteger <sbyte> .ParseNullableObject); case TypeCode.Byte: return(UnsignedInteger <byte> .ParseNullableObject); case TypeCode.Int16: return(SignedInteger <short> .ParseNullableObject); case TypeCode.UInt16: return(UnsignedInteger <ushort> .ParseNullableObject); case TypeCode.Int32: return(SignedInteger <int> .ParseNullableObject); case TypeCode.UInt32: return(UnsignedInteger <uint> .ParseNullableObject); case TypeCode.Int64: return(SignedInteger <long> .ParseNullableObject); case TypeCode.UInt64: return(UnsignedInteger <ulong> .ParseNullableObject); case TypeCode.Single: return(value => value.IsNullOrEmpty() ? (float?)null : value.ParseFloat()); case TypeCode.Double: return(value => value.IsNullOrEmpty() ? (double?)null : value.ParseDouble()); case TypeCode.Decimal: return(value => value.IsNullOrEmpty() ? (decimal?)null : value.ParseDecimal()); case TypeCode.DateTime: return(value => DateTimeSerializer.ParseShortestNullableXsdDateTime(value.ToString())); case TypeCode.Char: return(value => value.IsEmpty ? (char?)null : value.Length == 1 ? value[0] : JsonTypeSerializer.Unescape(value)[0]); } if (typeof(T) == typeof(TimeSpan?)) { return(value => DateTimeSerializer.ParseNullableTimeSpan(value.ToString())); } if (typeof(T) == typeof(Guid?)) { return(value => value.IsNullOrEmpty() ? (Guid?)null : value.ParseGuid()); } if (typeof(T) == typeof(DateTimeOffset?)) { return(value => DateTimeSerializer.ParseNullableDateTimeOffset(value.ToString())); } #if NET6_0 if (typeof(T) == typeof(DateOnly?)) { return(value => value.IsNullOrEmpty() ? default : DateOnly.FromDateTime(DateTimeSerializer.ParseShortestXsdDateTime(value.ToString()))); } if (typeof(T) == typeof(TimeOnly?)) { return(value => value.IsNullOrEmpty() ? default : TimeOnly.FromTimeSpan(DateTimeSerializer.ParseTimeSpan(value.ToString()))); } #endif } return(null); }
internal static object StringToType( Type type, string strType, EmptyCtorDelegate ctorFn, Dictionary <string, TypeAccessor> typeAccessorMap) { var index = 0; if (strType == null) { return(null); } //if (!Serializer.EatMapStartChar(strType, ref index)) if (strType[index++] != JsWriter.MapStartChar) { throw DeserializeTypeRef.CreateSerializationError(type, strType); } if (JsonTypeSerializer.IsEmptyMap(strType)) { return(ctorFn()); } object instance = null; var propertyResolver = JsConfig.PropertyConvention == PropertyConvention.Lenient ? ParseUtils.LenientPropertyNameResolver : ParseUtils.DefaultPropertyNameResolver; var strTypeLength = strType.Length; while (index < strTypeLength) { var propertyName = Serializer.EatMapKey(strType, ref index); //Serializer.EatMapKeySeperator(strType, ref index); index++; var propertyValueStr = Serializer.EatValue(strType, ref index); var possibleTypeInfo = propertyValueStr != null && propertyValueStr.Length > 1; if (possibleTypeInfo && propertyName == JsWriter.TypeAttr) { var explicitTypeName = Serializer.ParseString(propertyValueStr); var explicitType = JsConfig.TypeFinder(explicitTypeName); if (explicitType != null && !explicitType.IsInterface() && !explicitType.IsAbstract()) { instance = explicitType.CreateInstance(); } if (instance == null) { Tracer.Instance.WriteWarning("Could not find type: " + propertyValueStr); } else { //If __type info doesn't match, ignore it. if (!type.InstanceOfType(instance)) { instance = null; } else { var derivedType = instance.GetType(); if (derivedType != type) { var derivedTypeConfig = new TypeConfig(derivedType); var map = DeserializeTypeRef.GetTypeAccessorMap(derivedTypeConfig, Serializer); if (map != null) { typeAccessorMap = map; } } } } //Serializer.EatItemSeperatorOrMapEndChar(strType, ref index); if (index != strType.Length) { index++; } continue; } if (instance == null) { instance = ctorFn(); } var typeAccessor = propertyResolver.GetTypeAccessorForProperty(propertyName, typeAccessorMap); var propType = possibleTypeInfo && propertyValueStr[0] == '_' ? TypeAccessor.ExtractType(Serializer, propertyValueStr) : null; if (propType != null) { try { if (typeAccessor != null) { var parseFn = Serializer.GetParseFn(propType); var propertyValue = parseFn(propertyValueStr); typeAccessor.SetProperty(instance, propertyValue); } //Serializer.EatItemSeperatorOrMapEndChar(strType, ref index); if (index != strType.Length) { index++; } continue; } catch (Exception e) { if (JsConfig.ThrowOnDeserializationError) { throw DeserializeTypeRef.GetSerializationException(propertyName, propertyValueStr, propType, e); } else { Tracer.Instance.WriteWarning("WARN: failed to set dynamic property {0} with: {1}", propertyName, propertyValueStr); } } } if (typeAccessor != null && typeAccessor.GetProperty != null && typeAccessor.SetProperty != null) { try { var propertyValue = typeAccessor.GetProperty(propertyValueStr); typeAccessor.SetProperty(instance, propertyValue); } catch (Exception e) { if (JsConfig.ThrowOnDeserializationError) { throw DeserializeTypeRef.GetSerializationException(propertyName, propertyValueStr, propType, e); } else { Tracer.Instance.WriteWarning("WARN: failed to set property {0} with: {1}", propertyName, propertyValueStr); } } } //Serializer.EatItemSeperatorOrMapEndChar(strType, ref index); if (index != strType.Length) { index++; } } return(instance); }
internal static object StringToType( TypeConfig typeConfig, string strType, EmptyCtorDelegate ctorFn, Dictionary <string, TypeAccessor> typeAccessorMap) { var index = 0; var type = typeConfig.Type; if (strType == null) { return(null); } //if (!Serializer.EatMapStartChar(strType, ref index)) for (; index < strType.Length; index++) { var c = strType[index]; if (c >= JsonTypeSerializer.WhiteSpaceFlags.Length || !JsonTypeSerializer.WhiteSpaceFlags[c]) { break; } } //Whitespace inline if (strType[index++] != JsWriter.MapStartChar) { throw DeserializeTypeRef.CreateSerializationError(type, strType); } if (JsonTypeSerializer.IsEmptyMap(strType, index)) { return(ctorFn()); } object instance = null; var strTypeLength = strType.Length; while (index < strTypeLength) { var propertyName = JsonTypeSerializer.ParseJsonString(strType, ref index); //Serializer.EatMapKeySeperator(strType, ref index); for (; index < strType.Length; index++) { var c = strType[index]; if (c >= JsonTypeSerializer.WhiteSpaceFlags.Length || !JsonTypeSerializer.WhiteSpaceFlags[c]) { break; } } //Whitespace inline if (strType.Length != index) { index++; } var propertyValueStr = Serializer.EatValue(strType, ref index); var possibleTypeInfo = propertyValueStr != null && propertyValueStr.Length > 1; //if we already have an instance don't check type info, because then we will have a half deserialized object //we could throw here or just use the existing instance. if (instance == null && possibleTypeInfo && propertyName == JsWriter.TypeAttr) { var explicitTypeName = Serializer.ParseString(propertyValueStr); var explicitType = AssemblyUtils.FindType(explicitTypeName); // let's do the type safety checks first before we even attempt to create // a type instance if (explicitType == null || explicitType.IsInterface() || explicitType.IsAbstract()) { Tracer.Instance.WriteWarning("Could not find type: " + propertyValueStr); } else if (!type.IsAssignableFrom(explicitType)) { Tracer.Instance.WriteWarning("Could not assign type: " + propertyValueStr); } else { instance = explicitType.CreateInstance(); } if (instance != null) { var derivedType = instance.GetType(); if (derivedType != type) { var derivedTypeConfig = new TypeConfig(derivedType); var map = DeserializeTypeRef.GetTypeAccessorMap(derivedTypeConfig, Serializer); if (map != null) { typeAccessorMap = map; } } } Serializer.EatItemSeperatorOrMapEndChar(strType, ref index); continue; } if (instance == null) { instance = ctorFn(); } var typeAccessor = PropertyNameResolver.GetTypeAccessorForProperty(propertyName, typeAccessorMap); var propType = possibleTypeInfo && propertyValueStr[0] == '_' ? TypeAccessor.ExtractType(Serializer, propertyValueStr) : null; if (propType != null) { try { if (typeAccessor != null) { //var parseFn = Serializer.GetParseFn(propType); var parseFn = JsonReader.GetParseFn(propType); var propertyValue = parseFn(propertyValueStr); if (typeConfig.OnDeserializing != null) { propertyValue = typeConfig.OnDeserializing(instance, propertyName, propertyValue); } typeAccessor.SetProperty(instance, propertyValue); } //Serializer.EatItemSeperatorOrMapEndChar(strType, ref index); for (; index < strType.Length; index++) { var c = strType[index]; if (c >= JsonTypeSerializer.WhiteSpaceFlags.Length || !JsonTypeSerializer.WhiteSpaceFlags[c]) { break; } } //Whitespace inline if (index != strType.Length) { var success = strType[index] == JsWriter.ItemSeperator || strType[index] == JsWriter.MapEndChar; index++; if (success) { for (; index < strType.Length; index++) { var c = strType[index]; if (c >= JsonTypeSerializer.WhiteSpaceFlags.Length || !JsonTypeSerializer.WhiteSpaceFlags[c]) { break; } } //Whitespace inline } } continue; } catch (Exception e) { if (JsConfig.HasOnDeserializationErrorHandler) { JsConfig.OnDeserializationError(instance, propType, propertyName, propertyValueStr, e); } if (JsConfig.ThrowOnDeserializationError) { throw DeserializeTypeRef.GetSerializationException(propertyName, propertyValueStr, propType, e); } Tracer.Instance.WriteWarning("WARN: failed to set dynamic property {0} with: {1}", propertyName, propertyValueStr); } } if (typeAccessor != null && typeAccessor.GetProperty != null && typeAccessor.SetProperty != null) { try { var propertyValue = typeAccessor.GetProperty(propertyValueStr); if (typeConfig.OnDeserializing != null) { propertyValue = typeConfig.OnDeserializing(instance, propertyName, propertyValue); } typeAccessor.SetProperty(instance, propertyValue); } catch (Exception e) { if (JsConfig.HasOnDeserializationErrorHandler) { JsConfig.OnDeserializationError(instance, typeAccessor.PropertyType, propertyName, propertyValueStr, e); } if (JsConfig.ThrowOnDeserializationError) { throw DeserializeTypeRef.GetSerializationException(propertyName, propertyValueStr, typeAccessor.PropertyType, e); } Tracer.Instance.WriteWarning("WARN: failed to set property {0} with: {1}", propertyName, propertyValueStr); } } else if (typeConfig.OnDeserializing != null) { // the property is not known by the DTO typeConfig.OnDeserializing(instance, propertyName, propertyValueStr); } //Serializer.EatItemSeperatorOrMapEndChar(strType, ref index); for (; index < strType.Length; index++) { var c = strType[index]; if (c >= JsonTypeSerializer.WhiteSpaceFlags.Length || !JsonTypeSerializer.WhiteSpaceFlags[c]) { break; } } //Whitespace inline if (index != strType.Length) { var success = strType[index] == JsWriter.ItemSeperator || strType[index] == JsWriter.MapEndChar; index++; if (success) { for (; index < strType.Length; index++) { var c = strType[index]; if (c >= JsonTypeSerializer.WhiteSpaceFlags.Length || !JsonTypeSerializer.WhiteSpaceFlags[c]) { break; } } //Whitespace inline } } } return(instance); }
internal static object StringToType( TypeConfig typeConfig, StringSegment strType, EmptyCtorDelegate ctorFn, Dictionary <HashedStringSegment, TypeAccessor> typeAccessorMap) { var index = 0; var type = typeConfig.Type; if (!strType.HasValue) { return(null); } // if (!Serializer.EatMapStartChar(strType, ref index)) if (strType.GetChar(index++) != JsWriter.MapStartChar) { throw DeserializeTypeRef.CreateSerializationError(type, strType.Value); } if (JsonTypeSerializer.IsEmptyMap(strType)) { return(ctorFn()); } object instance = null; var propertyResolver = JsConfig.PropertyConvention == PropertyConvention.Lenient ? ParseUtils.LenientPropertyNameResolver : ParseUtils.DefaultPropertyNameResolver; var strTypeLength = strType.Length; while (index < strTypeLength) { var propertyName = Serializer.EatMapKey(strType, ref index); // Serializer.EatMapKeySeperator(strType, ref index); index++; var propertyValueStr = Serializer.EatValue(strType, ref index); var possibleTypeInfo = propertyValueStr != null && propertyValueStr.Length > 1; if (possibleTypeInfo && propertyName == new StringSegment(JsWriter.TypeAttr)) { var explicitTypeName = Serializer.ParseString(propertyValueStr); var explicitType = JsConfig.TypeFinder(explicitTypeName); if (explicitType == null || explicitType.IsInterface || explicitType.IsAbstract) { Tracer.Instance.WriteWarning($"Could not find type: {propertyValueStr}"); } else if (!type.IsAssignableFrom(explicitType)) { Tracer.Instance.WriteWarning($"Could not assign type: {propertyValueStr}"); } else { JsWriter.AssertAllowedRuntimeType(explicitType); instance = explicitType.CreateInstance(); } if (instance != null) { // If __type info doesn't match, ignore it. if (!type.IsInstanceOfType(instance)) { instance = null; } else { var derivedType = instance.GetType(); if (derivedType != type) { var derivedTypeConfig = new TypeConfig(derivedType); var map = DeserializeTypeRef.GetTypeAccessorMap(derivedTypeConfig, Serializer); if (map != null) { typeAccessorMap = map; } } } } // Serializer.EatItemSeperatorOrMapEndChar(strType, ref index); if (index != strType.Length) { index++; } continue; } if (instance == null) { instance = ctorFn(); } var typeAccessor = propertyResolver.GetTypeAccessorForProperty(propertyName, typeAccessorMap); var propType = possibleTypeInfo && propertyValueStr.GetChar(0) == '_' ? TypeAccessor.ExtractType(Serializer, propertyValueStr) : null; if (propType != null) { try { if (typeAccessor != null) { var parseFn = Serializer.GetParseStringSegmentFn(propType); var propertyValue = parseFn(propertyValueStr); if (typeConfig.OnDeserializing != null) { propertyValue = typeConfig.OnDeserializing(instance, propertyName.Value, propertyValue); } typeAccessor.SetProperty(instance, propertyValue); } // Serializer.EatItemSeperatorOrMapEndChar(strType, ref index); if (index != strType.Length) { index++; } continue; } catch (Exception e) { if (JsConfig.OnDeserializationError != null) { JsConfig.OnDeserializationError(instance, propType, propertyName.Value, propertyValueStr.Value, e); } if (JsConfig.ThrowOnDeserializationError) { throw DeserializeTypeRef.GetSerializationException(propertyName.Value, propertyValueStr.Value, propType, e); } else { Tracer.Instance.WriteWarning("WARN: failed to set dynamic property {0} with: {1}", propertyName, propertyValueStr); } } } if (typeAccessor?.GetProperty != null && typeAccessor.SetProperty != null) { try { var propertyValue = typeAccessor.GetProperty(propertyValueStr); if (typeConfig.OnDeserializing != null) { propertyValue = typeConfig.OnDeserializing(instance, propertyName.Value, propertyValue); } typeAccessor.SetProperty(instance, propertyValue); } catch (NotSupportedException) { throw; } catch (Exception e) { if (JsConfig.OnDeserializationError != null) { JsConfig.OnDeserializationError(instance, propType ?? typeAccessor.PropertyType, propertyName.Value, propertyValueStr.Value, e); } if (JsConfig.ThrowOnDeserializationError) { throw DeserializeTypeRef.GetSerializationException(propertyName.Value, propertyValueStr.Value, propType, e); } else { Tracer.Instance.WriteWarning("WARN: failed to set property {0} with: {1}", propertyName, propertyValueStr); } } } else { // the property is not known by the DTO typeConfig.OnDeserializing?.Invoke(instance, propertyName.Value, propertyValueStr); } // Serializer.EatItemSeperatorOrMapEndChar(strType, ref index); if (index != strType.Length) { index++; } } return(instance); }
internal static object StringToType(ReadOnlySpan <char> strType, TypeConfig typeConfig, EmptyCtorDelegate ctorFn, KeyValuePair <string, TypeAccessor>[] typeAccessors) { var index = 0; var type = typeConfig.Type; if (strType.IsEmpty) { return(null); } var buffer = strType; var strTypeLength = strType.Length; //if (!Serializer.EatMapStartChar(strType, ref index)) for (; index < strTypeLength; index++) { if (!JsonUtils.IsWhiteSpace(buffer[index])) { break; } } //Whitespace inline if (buffer[index] != JsWriter.MapStartChar) { throw DeserializeTypeRef.CreateSerializationError(type, strType.ToString()); } index++; if (JsonTypeSerializer.IsEmptyMap(strType, index)) { return(ctorFn()); } var config = JsConfig.GetConfig(); object instance = null; var lenient = config.PropertyConvention == PropertyConvention.Lenient; for (; index < strTypeLength; index++) { if (!JsonUtils.IsWhiteSpace(buffer[index])) { break; } } //Whitespace inline while (index < strTypeLength) { var propertyName = JsonTypeSerializer.UnescapeJsString(strType, JsonUtils.QuoteChar, removeQuotes: true, ref index); //Serializer.EatMapKeySeperator(strType, ref index); for (; index < strTypeLength; index++) { if (!JsonUtils.IsWhiteSpace(buffer[index])) { break; } } //Whitespace inline if (strTypeLength != index) { index++; } var propertyValueStr = Serializer.EatValue(strType, ref index); var possibleTypeInfo = propertyValueStr != null && propertyValueStr.Length > 1; //if we already have an instance don't check type info, because then we will have a half deserialized object //we could throw here or just use the existing instance. if (instance == null && possibleTypeInfo && propertyName.Equals(typeAttr.Span, StringComparison.OrdinalIgnoreCase)) { var explicitTypeName = Serializer.ParseString(propertyValueStr); var explicitType = config.TypeFinder(explicitTypeName); if (explicitType == null || explicitType.IsInterface || explicitType.IsAbstract) { Tracer.Instance.WriteWarning("Could not find type: " + propertyValueStr.ToString()); } else if (!type.IsAssignableFrom(explicitType)) { Tracer.Instance.WriteWarning("Could not assign type: " + propertyValueStr.ToString()); } else { JsWriter.AssertAllowedRuntimeType(explicitType); instance = explicitType.CreateInstance(); } if (instance != null) { //If __type info doesn't match, ignore it. if (!type.IsInstanceOfType(instance)) { instance = null; } else { var derivedType = instance.GetType(); if (derivedType != type) { var map = DeserializeTypeRef.GetCachedTypeAccessors(derivedType, Serializer); if (map != null) { typeAccessors = map; } } } } Serializer.EatItemSeperatorOrMapEndChar(strType, ref index); continue; } if (instance == null) { instance = ctorFn(); } var typeAccessor = typeAccessors.Get(propertyName, lenient); var propType = possibleTypeInfo && propertyValueStr[0] == '_' ? TypeAccessor.ExtractType(Serializer, propertyValueStr) : null; if (propType != null) { try { if (typeAccessor != null) { //var parseFn = Serializer.GetParseFn(propType); var parseFn = JsonReader.GetParseStringSpanFn(propType); var propertyValue = parseFn(propertyValueStr); if (typeConfig.OnDeserializing != null) { propertyValue = typeConfig.OnDeserializing(instance, propertyName.ToString(), propertyValue); } typeAccessor.SetProperty(instance, propertyValue); } //Serializer.EatItemSeperatorOrMapEndChar(strType, ref index); for (; index < strTypeLength; index++) { if (!JsonUtils.IsWhiteSpace(buffer[index])) { break; } } //Whitespace inline if (index != strTypeLength) { var success = buffer[index] == JsWriter.ItemSeperator || buffer[index] == JsWriter.MapEndChar; index++; if (success) { for (; index < strTypeLength; index++) { if (!JsonUtils.IsWhiteSpace(buffer[index])) { break; } } //Whitespace inline } } continue; } catch (Exception e) { config.OnDeserializationError?.Invoke(instance, propType, propertyName.ToString(), propertyValueStr.ToString(), e); if (config.ThrowOnError) { throw DeserializeTypeRef.GetSerializationException(propertyName.ToString(), propertyValueStr.ToString(), propType, e); } else { Tracer.Instance.WriteWarning("WARN: failed to set dynamic property {0} with: {1}", propertyName.ToString(), propertyValueStr.ToString()); } } } if (typeAccessor?.GetProperty != null && typeAccessor.SetProperty != null) { try { var propertyValue = typeAccessor.GetProperty(propertyValueStr); if (typeConfig.OnDeserializing != null) { propertyValue = typeConfig.OnDeserializing(instance, propertyName.ToString(), propertyValue); } typeAccessor.SetProperty(instance, propertyValue); } catch (NotSupportedException) { throw; } catch (Exception e) { config.OnDeserializationError?.Invoke(instance, propType ?? typeAccessor.PropertyType, propertyName.ToString(), propertyValueStr.ToString(), e); if (config.ThrowOnError) { throw DeserializeTypeRef.GetSerializationException(propertyName.ToString(), propertyValueStr.ToString(), typeAccessor.PropertyType, e); } else { Tracer.Instance.WriteWarning("WARN: failed to set property {0} with: {1}", propertyName.ToString(), propertyValueStr.ToString()); } } } else { // the property is not known by the DTO typeConfig.OnDeserializing?.Invoke(instance, propertyName.ToString(), propertyValueStr.ToString()); } //Serializer.EatItemSeperatorOrMapEndChar(strType, ref index); for (; index < strTypeLength; index++) { if (!JsonUtils.IsWhiteSpace(buffer[index])) { break; } } //Whitespace inline if (index != strType.Length) { var success = buffer[index] == JsWriter.ItemSeperator || buffer[index] == JsWriter.MapEndChar; index++; if (success) { for (; index < strTypeLength; index++) { if (!JsonUtils.IsWhiteSpace(buffer[index])) { break; } } //Whitespace inline } } } return(instance); }