Ejemplo n.º 1
0
        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);
        }
Ejemplo n.º 2
0
        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));
        }
Ejemplo n.º 3
0
        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);
        }
Ejemplo n.º 4
0
        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);
        }
Ejemplo n.º 5
0
 static AotConfig()
 {
     jsonSerializer = new JsonTypeSerializer();
     jsvSerializer  = new JsvTypeSerializer();
     jsonReader     = new JsReader <JsonTypeSerializer>();
     jsonWriter     = new JsWriter <JsonTypeSerializer>();
     jsvReader      = new JsReader <JsvTypeSerializer>();
     jsvWriter      = new JsWriter <JsvTypeSerializer>();
 }
Ejemplo n.º 6
0
        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);
        }
Ejemplo n.º 7
0
        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());
        }
Ejemplo n.º 8
0
        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));
        }
Ejemplo n.º 10
0
        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));
        }
Ejemplo n.º 11
0
        /// <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('"');
        }
Ejemplo n.º 12
0
        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);
        }
Ejemplo n.º 13
0
        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));
        }
Ejemplo n.º 14
0
    /// <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));
    }
Ejemplo n.º 15
0
        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);
        }
Ejemplo n.º 16
0
        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);
        }
Ejemplo n.º 17
0
    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);
        }
Ejemplo n.º 19
0
 static JsonAotConfig()
 {
     serializer = new JsonTypeSerializer();
     reader     = new JsReader <JsonTypeSerializer>();
     writer     = new JsWriter <JsonTypeSerializer>();
 }
Ejemplo n.º 20
0
        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);
        }
Ejemplo n.º 22
0
        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);
        }
Ejemplo n.º 24
0
        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);
        }
Ejemplo n.º 25
0
        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);
        }
Ejemplo n.º 26
0
        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);
        }