public static ParseListDelegate GetListTypeParseStringSpanFn( Type createListType, Type elementType, ParseStringSpanDelegate parseFn) { if (ParseDelegateCache.TryGetValue(elementType, out var parseDelegate)) { return(parseDelegate.Invoke); } var genericType = typeof(DeserializeListWithElements <,>).MakeGenericType(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) { [elementType] = parseDelegate }; } while (!ReferenceEquals( Interlocked.CompareExchange(ref ParseDelegateCache, newCache, snapshot), snapshot)); return(parseDelegate.Invoke); }
public static object ParseKeyValuePairType(ReadOnlySpan <char> value, Type createMapType, Type[] argTypes, ParseStringSpanDelegate keyParseFn, ParseStringSpanDelegate valueParseFn) { var key = GetTypesKey(argTypes); if (ParseDelegateCache.TryGetValue(key, out var parseDelegate)) { return(parseDelegate(value, createMapType, keyParseFn, valueParseFn)); } var mi = typeof(DeserializeKeyValuePair <TSerializer>).GetStaticMethod("ParseKeyValuePair", signature); var genericMi = mi.MakeGenericMethod(argTypes); parseDelegate = (ParseKeyValuePairDelegate)genericMi.MakeDelegate(typeof(ParseKeyValuePairDelegate)); Dictionary <string, ParseKeyValuePairDelegate> snapshot, newCache; do { snapshot = ParseDelegateCache; newCache = new Dictionary <string, ParseKeyValuePairDelegate>(ParseDelegateCache); newCache[key] = parseDelegate; } while (!ReferenceEquals( Interlocked.CompareExchange(ref ParseDelegateCache, newCache, snapshot), snapshot)); return(parseDelegate(value, createMapType, keyParseFn, valueParseFn)); }
/// <summary> /// Parses the dictionary. /// </summary> /// <typeparam name="TKey">The type of the t key.</typeparam> /// <typeparam name="TValue">The type of the t value.</typeparam> /// <param name="value">The value.</param> /// <param name="createMapType">Type of the create map.</param> /// <param name="parseKeyFn">The parse key function.</param> /// <param name="parseValueFn">The parse value function.</param> /// <returns>IDictionary<TKey, TValue>.</returns> public static IDictionary <TKey, TValue> ParseDictionary <TKey, TValue>( ReadOnlySpan <char> value, Type createMapType, ParseStringSpanDelegate parseKeyFn, ParseStringSpanDelegate parseValueFn) { if (value.IsEmpty) { return(null); } var to = createMapType == null ? new Dictionary <TKey, TValue>() : (IDictionary <TKey, TValue>)createMapType.CreateInstance(); var objDeserializer = Json.JsonTypeSerializer.Instance.ObjectDeserializer; if (to is Dictionary <string, object> && objDeserializer != null && typeof(TSerializer) == typeof(Json.JsonTypeSerializer)) { return((IDictionary <TKey, TValue>)objDeserializer(value)); } var config = JsConfig.GetConfig(); var tryToParseItemsAsDictionaries = config.ConvertObjectTypesIntoStringDictionary && typeof(TValue) == typeof(object); var tryToParseItemsAsPrimitiveTypes = config.TryToParsePrimitiveTypeValues && typeof(TValue) == typeof(object); var index = VerifyAndGetStartIndex(value, createMapType); if (Json.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.IsNullOrEmpty()) { continue; } TKey mapKey = (TKey)parseKeyFn(keyValue); if (tryToParseItemsAsDictionaries) { Serializer.EatWhitespace(value, ref elementStartIndex); if (elementStartIndex < valueLength && value[elementStartIndex] == JsWriter.MapStartChar) { var tmpMap = ParseDictionary <TKey, TValue>(elementValue, createMapType, parseKeyFn, parseValueFn); if (tmpMap is { Count : > 0 })
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 ParseStringSpanDelegate GetParseStringSpanFn <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); } ParseStringSpanDelegate parseDelegate = null; try { if (parseMethodInfo.ReturnType != typeof(T)) { parseDelegate = (ParseStringSpanDelegate)parseMethodInfo.MakeDelegate(typeof(ParseStringSpanDelegate), false); } if (parseDelegate == null) { //Try wrapping strongly-typed return with wrapper fn. var typedParseDelegate = (ParseStringSpanGenericDelegate <T>)parseMethodInfo.MakeDelegate(typeof(ParseStringSpanGenericDelegate <T>)); parseDelegate = x => typedParseDelegate(x); } } catch (ArgumentException) { Tracer.Instance.WriteDebug("Nonstandard Parse method on type {0}", typeof(T)); } if (parseDelegate != null) { return(value => parseDelegate(value.ToString().FromCsvField().AsSpan())); } return(null); }
/// <summary> /// Parses the collection. /// </summary> /// <typeparam name="T"></typeparam> /// <param name="value">The value.</param> /// <param name="createType">Type of the create.</param> /// <param name="parseFn">The parse function.</param> /// <returns>ICollection<T>.</returns> public static ICollection <T> ParseCollection <T>(ReadOnlySpan <char> value, Type createType, ParseStringSpanDelegate parseFn) { if (value.IsEmpty) { return(null); } var items = DeserializeArrayWithElements <T, TSerializer> .ParseGenericArray(value, parseFn); return(CollectionExtensions.CreateAndPopulate(createType, items)); }
static StaticParseRefTypeMethod() { CacheFn = ParseMethodUtilities.GetParseFn <T>(ParseMethod); CacheStringSpanFn = ParseMethodUtilities.GetParseStringSpanFn <T>(ParseStringSpanMethod); }
/// <summary> /// Initializes static members of the <see cref="StaticParseMethod{T}" /> class. /// </summary> static StaticParseMethod() { Parse = ParseMethodUtilities.GetParseFn <T>(ParseMethod); ParseStringSpan = ParseMethodUtilities.GetParseStringSpanFn <T>(ParseMethod); }
static DeserializeSpecializedCollections() { CacheFn = GetParseStringSpanFn(); }
static DeserializeDynamic() { CachedParseFn = ParseDynamic; }
static DeserializeBuiltin() { CachedParseFn = GetParseStringSpanFn(); }
static StaticParseMethod() { CacheFn = ParseMethodUtilities.GetParseFn <T>(ParseMethod); CacheStringSpanFn = ParseMethodUtilities.GetParseStringSegmentFn <T>(ParseMethod); }
public static IDictionary <TKey, TValue> ParseDictionary <TKey, TValue>( ReadOnlySpan <char> value, Type createMapType, ParseStringSpanDelegate parseKeyFn, ParseStringSpanDelegate parseValueFn) { if (value.IsEmpty) { return(null); } var config = JsConfig.GetConfig(); var tryToParseItemsAsDictionaries = config.ConvertObjectTypesIntoStringDictionary && typeof(TValue) == typeof(object); var tryToParseItemsAsPrimitiveTypes = config.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.IsNullOrEmpty()) { continue; } TKey mapKey = (TKey)parseKeyFn(keyValue); if (tryToParseItemsAsDictionaries) { Serializer.EatWhitespace(value, ref elementStartIndex); if (elementStartIndex < valueLength && value[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[elementStartIndex] == JsWriter.ListStartChar) { to[mapKey] = (TValue)DeserializeList <List <object>, TSerializer> .ParseStringSpan(elementValue); } else { to[mapKey] = (TValue)(tryToParseItemsAsPrimitiveTypes && elementStartIndex < valueLength ? DeserializeType <TSerializer> .ParsePrimitive(elementValue.Value(), value[elementStartIndex]) : parseValueFn(elementValue)); } } else { if (tryToParseItemsAsPrimitiveTypes && elementStartIndex < valueLength) { Serializer.EatWhitespace(value, ref elementStartIndex); to[mapKey] = (TValue)DeserializeType <TSerializer> .ParsePrimitive(elementValue.Value(), value[elementStartIndex]); } else { to[mapKey] = (TValue)parseValueFn(elementValue); } } Serializer.EatItemSeperatorOrMapEndChar(value, ref index); } return(to); }
public static object ParseCollectionType(ReadOnlySpan <char> value, Type createType, Type elementType, ParseStringSpanDelegate parseFn) { if (ParseDelegateCache.TryGetValue(elementType, out var parseDelegate)) { return(parseDelegate(value, createType, parseFn)); } var mi = typeof(DeserializeCollection <TSerializer>).GetStaticMethod("ParseCollection", arguments); 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)); }