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(); 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 void InitAot <T>() { var hold = DeserializeBuiltin <T> .Parse; hold = DeserializeArray <T[], TSerializer> .Parse; DeserializeType <TSerializer> .ExtractType(null); DeserializeArrayWithElements <T, TSerializer> .ParseGenericArray(null, null); DeserializeCollection <TSerializer> .ParseCollection <T>(null, null, null); DeserializeListWithElements <T, TSerializer> .ParseGenericList(null, null, null); }
private ParseStringSegmentDelegate GetCoreParseStringSegmentFn <T>() { var type = Nullable.GetUnderlyingType(typeof(T)) ?? typeof(T); if (JsConfig <T> .HasDeserializeFn) { return(value => JsConfig <T> .ParseFn(Serializer, value.Value)); } if (type.IsEnum) { return(x => ParseUtils.TryParseEnum(type, Serializer.UnescapeSafeString(x).Value)); } if (type == typeof(string)) { return(v => Serializer.UnescapeString(v).Value); } if (type == typeof(object)) { return(DeserializeType <TSerializer> .ObjectStringToType); } var specialParseFn = ParseUtils.GetSpecialParseMethod(type); if (specialParseFn != null) { return(v => specialParseFn(v.Value)); } if (type.IsArray) { return(DeserializeArray <T, TSerializer> .ParseStringSegment); } var builtInMethod = DeserializeBuiltin <T> .ParseStringSegment; if (builtInMethod != null) { return(value => builtInMethod(Serializer.UnescapeSafeString(value))); } if (type.HasGenericType()) { if (type.IsOrHasGenericInterfaceTypeOf(typeof(IList <>))) { return(DeserializeList <T, TSerializer> .ParseStringSegment); } if (type.IsOrHasGenericInterfaceTypeOf(typeof(IDictionary <,>))) { return(DeserializeDictionary <TSerializer> .GetParseStringSegmentMethod(type)); } if (type.IsOrHasGenericInterfaceTypeOf(typeof(ICollection <>))) { return(DeserializeCollection <TSerializer> .GetParseStringSegmentMethod(type)); } if (type.HasAnyTypeDefinitionsOf(typeof(Queue <>)) || type.HasAnyTypeDefinitionsOf(typeof(Stack <>))) { return(DeserializeSpecializedCollections <T, TSerializer> .ParseStringSegment); } if (type.IsOrHasGenericInterfaceTypeOf(typeof(KeyValuePair <,>))) { return(DeserializeKeyValuePair <TSerializer> .GetParseStringSegmentMethod(type)); } if (type.IsOrHasGenericInterfaceTypeOf(typeof(IEnumerable <>))) { return(DeserializeEnumerable <T, TSerializer> .ParseStringSegment); } var customFn = DeserializeCustomGenericType <TSerializer> .GetParseStringSegmentMethod(type); if (customFn != null) { return(customFn); } } var pclParseFn = PclExport.Instance.GetJsReaderParseStringSegmentMethod <TSerializer>(typeof(T)); if (pclParseFn != null) { return(pclParseFn); } var isDictionary = typeof(T) != typeof(IEnumerable) && typeof(T) != typeof(ICollection) && (typeof(T).IsAssignableFrom(typeof(IDictionary)) || typeof(T).HasInterface(typeof(IDictionary))); if (isDictionary) { return(DeserializeDictionary <TSerializer> .GetParseStringSegmentMethod(type)); } var isEnumerable = typeof(T).IsAssignableFrom(typeof(IEnumerable)) || typeof(T).HasInterface(typeof(IEnumerable)); if (isEnumerable) { var parseFn = DeserializeSpecializedCollections <T, TSerializer> .ParseStringSegment; if (parseFn != null) { return(parseFn); } } if (type.IsValueType) { //at first try to find more faster `ParseStringSegment` method var staticParseStringSegmentMethod = StaticParseMethod <T> .ParseStringSegment; if (staticParseStringSegmentMethod != null) { return(value => staticParseStringSegmentMethod(Serializer.UnescapeSafeString(value))); } //then try to find `Parse` method var staticParseMethod = StaticParseMethod <T> .Parse; if (staticParseMethod != null) { return(value => staticParseMethod(Serializer.UnescapeSafeString(value).Value)); } } else { var staticParseStringSegmentMethod = StaticParseRefTypeMethod <TSerializer, T> .ParseStringSegment; if (staticParseStringSegmentMethod != null) { return(value => staticParseStringSegmentMethod(Serializer.UnescapeSafeString(value))); } var staticParseMethod = StaticParseRefTypeMethod <TSerializer, T> .Parse; if (staticParseMethod != null) { return(value => staticParseMethod(Serializer.UnescapeSafeString(value).Value)); } } var typeConstructor = DeserializeType <TSerializer> .GetParseStringSegmentMethod(TypeConfig <T> .GetState()); if (typeConstructor != null) { return(typeConstructor); } var stringConstructor = DeserializeTypeUtils.GetParseStringSegmentMethod(type); if (stringConstructor != null) { return(stringConstructor); } return(DeserializeType <TSerializer> .ParseAbstractType <T>); }
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; } TKey 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); }