public static Func <StringSegment, Type, ParseStringSegmentDelegate, object> GetListTypeParseStringSegmentFn( Type createListType, Type elementType, ParseStringSegmentDelegate parseFn) { ParseListDelegate parseDelegate; if (ParseDelegateCache.TryGetValue(elementType, out parseDelegate)) { return(parseDelegate.Invoke); } var genericType = typeof(DeserializeListWithElements <,>).GetCachedGenericType(elementType, typeof(TSerializer)); var mi = genericType.GetStaticMethod("ParseGenericList", signature); parseDelegate = (ParseListDelegate)mi.MakeDelegate(typeof(ParseListDelegate)); Dictionary <Type, ParseListDelegate> snapshot, newCache; do { snapshot = ParseDelegateCache; newCache = new Dictionary <Type, ParseListDelegate>(ParseDelegateCache); newCache[elementType] = parseDelegate; } while (!ReferenceEquals( Interlocked.CompareExchange(ref ParseDelegateCache, newCache, snapshot), snapshot)); return(parseDelegate.Invoke); }
public static object ParseDictionaryType(StringSegment value, Type createMapType, Type[] argTypes, ParseStringSegmentDelegate keyParseFn, ParseStringSegmentDelegate valueParseFn) { var key = new TypesKey(argTypes[0], argTypes[1]); if (ParseDelegateCache.TryGetValue(key, out var parseDelegate)) { return(parseDelegate(value, createMapType, keyParseFn, valueParseFn)); } var mi = typeof(DeserializeDictionary <TSerializer>).GetStaticMethod("ParseDictionary", signature); var genericMi = mi.MakeGenericMethod(argTypes); parseDelegate = (ParseDictionaryDelegate)genericMi.MakeDelegate(typeof(ParseDictionaryDelegate)); Dictionary <TypesKey, ParseDictionaryDelegate> snapshot, newCache; do { snapshot = ParseDelegateCache; newCache = new Dictionary <TypesKey, ParseDictionaryDelegate>(ParseDelegateCache); newCache[key] = parseDelegate; }while (!ReferenceEquals( Interlocked.CompareExchange(ref ParseDelegateCache, newCache, snapshot), snapshot)); return(parseDelegate(value, createMapType, keyParseFn, valueParseFn)); }
public static object ParseKeyValuePair <TKey, TValue>( StringSegment value, Type createMapType, ParseStringSegmentDelegate parseKeyFn, ParseStringSegmentDelegate parseValueFn) { if (!value.HasValue) { 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")) { keyValue = (TKey)parseKeyFn(keyElementValue); } else if (key.CompareIgnoreCase("value")) { valueValue = (TValue)parseValueFn(keyElementValue); } else { throw new SerializationException("Incorrect KeyValuePair property: " + key); } Serializer.EatItemSeperatorOrMapEndChar(value, ref index); } return(new KeyValuePair <TKey, TValue>(keyValue, valueValue)); }
public static ParseStringSegmentDelegate GetParseStringSegmentFn <T>(string parseMethod) { // Get the static Parse(string) method on the type supplied var parseMethodInfo = typeof(T).GetStaticMethod(parseMethod, new[] { typeof(string) }); if (parseMethodInfo == null) { return(null); } ParseStringSegmentDelegate parseDelegate = null; try { if (parseMethodInfo.ReturnType != typeof(T)) { parseDelegate = (ParseStringSegmentDelegate)parseMethodInfo.MakeDelegate(typeof(ParseStringSegmentDelegate), false); } if (parseDelegate == null) { // Try wrapping strongly-typed return with wrapper fn. var typedParseDelegate = (Func <StringSegment, T>)parseMethodInfo.MakeDelegate(typeof(Func <StringSegment, T>)); parseDelegate = x => typedParseDelegate(x); } } catch (ArgumentException) { Tracer.Instance.WriteDebug("Nonstandard Parse method on type {0}", typeof(T)); } if (parseDelegate != null) { return(value => parseDelegate(new StringSegment(value.Value.FromCsvField()))); } return(null); }
static DeserializeEnumerable() { CacheFn = GetParseStringSegmentFn(); }
static DeserializeList() { CacheFn = GetParseStringSegmentFn(); }
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); }
static DeserializeSpecializedCollections() { CacheFn = GetParseStringSegmentFn(); }
static DeserializeBuiltin() { CachedParseFn = GetParseStringSegmentFn(); }
static StaticParseRefTypeMethod() { Parse = ParseMethodUtilities.GetParseFn <T>(ParseMethod); ParseStringSegment = ParseMethodUtilities.GetParseStringSegmentFn <T>(ParseStringSegmentMethod); }
static DeserializeDynamic() { CachedParseFn = ParseDynamic; }
static StaticParseRefTypeMethod() { CacheFn = ParseMethodUtilities.GetParseFn <T>(ParseMethod); CacheStringSegmentFn = ParseMethodUtilities.GetParseStringSegmentFn <T>(ParseStringSegmentMethod); }
public static ICollection <T> ParseCollection <T>(StringSegment value, Type createType, ParseStringSegmentDelegate parseFn) { if (!value.HasValue) { return(null); } var items = DeserializeArrayWithElements <T, TSerializer> .ParseGenericArray(value, parseFn); return(CollectionExtensions.CreateAndPopulate(createType, items)); }
public static object ParseCollectionType(StringSegment value, Type createType, Type elementType, ParseStringSegmentDelegate parseFn) { if (ParseDelegateCache.TryGetValue(elementType, out var parseDelegate)) { return(parseDelegate(value, createType, parseFn)); } var mi = typeof(DeserializeCollection <TSerializer>).GetStaticMethod("ParseCollection", new[] { typeof(StringSegment), typeof(Type), typeof(ParseStringSegmentDelegate) }); var genericMi = mi.MakeGenericMethod(new[] { elementType }); parseDelegate = (ParseCollectionDelegate)genericMi.MakeDelegate(typeof(ParseCollectionDelegate)); Dictionary <Type, ParseCollectionDelegate> snapshot, newCache; do { snapshot = ParseDelegateCache; newCache = new Dictionary <Type, ParseCollectionDelegate>(ParseDelegateCache); newCache[elementType] = parseDelegate; } while (!ReferenceEquals( Interlocked.CompareExchange(ref ParseDelegateCache, newCache, snapshot), snapshot)); return(parseDelegate(value, createType, parseFn)); }