Esempio n. 1
0
        /// <summary>
        /// Creates a JSON serializer specialized for objects of the specified type <typeparamref name="T"/>.
        /// </summary>
        /// <typeparam name="T">The type of the objects to serialize.</typeparam>
        /// <param name="provider">Name provider used to determine JSON object keys for properties and fields.</param>
        /// <param name="settings">The settings to configure the resulting serializer.</param>
        /// <returns>A fast JSON serializer specified for objects of the specified type <typeparamref name="T"/>.</returns>
        public static IFastJsonSerializer <T> CreateSerializer <T>(INameProvider provider, FastJsonSerializerSettings settings)
        {
            if (settings == null)
            {
                throw new ArgumentNullException(nameof(settings));
            }

            if (provider == null)
            {
                provider = DefaultNameProvider.Instance;
            }

            //
            // CONSIDER: Caching of serializers per type in a ConditionalWeakTable. However, we have to ensure different configurations
            //           don't get mixed up (e.g. based on providers).
            //
            // CONSIDER: Adding support for registration of custom serializers for given types. These would follow the EmitAction delegate
            //           and append an object of the given type to the StringBuilder.
            //

            var builderString = new EmitterStringBuilder(provider);
            var emitterString = builderString.Build <T>();

#if !NO_IO
            var builderWriter = new EmitterWriterBuilder(provider);
            var emitterWriter = builderWriter.Build <T>();

            if (settings.ConcurrencyMode == FastJsonConcurrencyMode.SingleThreaded)
            {
                return(new Serializer <T>(emitterString, builderString, emitterWriter, builderWriter));
            }
            else
            {
                return(new SafeSerializer <T>(emitterString, builderString, emitterWriter, builderWriter));
            }
#else
            if (settings.ConcurrencyMode == FastJsonConcurrencyMode.SingleThreaded)
            {
                return(new Serializer <T>(emitterString, builderString));
            }
            else
            {
                return(new SafeSerializer <T>(emitterString, builderString));
            }
#endif
        }
Esempio n. 2
0
        /// <summary>
        /// Creates a JSON deserializer specialized for objects of the specified type <typeparamref name="T"/>.
        /// </summary>
        /// <typeparam name="T">The type of the objects to deserialize.</typeparam>
        /// <param name="resolver">Name resolver used to find JSON object keys for properties and fields.</param>
        /// <param name="settings">The settings to configure the resulting deserializer.</param>
        /// <returns>A fast JSON deserializer specified for objects of the specified type <typeparamref name="T"/>.</returns>
        public static IFastJsonDeserializer <T> CreateDeserializer <T>(INameResolver resolver, FastJsonSerializerSettings settings)
        {
            if (settings == null)
            {
                throw new ArgumentNullException(nameof(settings));
            }

            if (resolver == null)
            {
                resolver = DefaultNameResolver.Instance;
            }

            //
            // CONSIDER: Caching of deserializers per type in a ConditionalWeakTable. However, we have to ensure different configurations
            //           don't get mixed up (e.g. based on resolvers).
            //
            // CONSIDER: Adding support for registration of custom deserializers for given types. These would accept a "natural" representation
            //           of a JSON primitive and perform conversions on them, e.g. take a String and return an instance of type T. There's a
            //           couple of options to support this:
            //
            //           1. Accept a Func<string, T>, allocate a string containing a JSON decoded string, and hand it to the extension. This
            //              approach requires allocations but is useful if the string has to be copied anyway, e.g. for a Uri.
            //
            //           2. Accept a Func<string, T>, scan for the length of a JSON decoded string, grab an instance from the pool, and hand
            //              it to the extension. This avoids allocations but assumes the callback doesn't extend the lifetime of the string
            //              beyond the synchronous invocation. It is useful for things such as TNumeric.Parse.
            //
            //           3. Accept a Func<TryLexChar, T>, where TryLexChar is a delegate with signature TryFunc<char>, i.e. returning a Char
            //              in an output parameter and returning a Boolean to indicate whether a value is available. The lex function stops
            //              yielding characters upon encountering the closing " of the string literal, and decodes the JSON characters as
            //              it's lexing. If we want to avoid allocations of delegates and closures, we need to assume that the callback does
            //              not extend the lifetime of the lex function beyond the synchronous invocation. This would be useful for things
            //              such as parsing a version number.
            //

            var builderString = new ParserStringBuilder(resolver);
            var parseString   = builderString.Build <T>();

#if !NO_IO
            var builderReader = new ParserReaderBuilder(resolver);
            var parseReader   = builderReader.Build <T>();

            if (settings.ConcurrencyMode == FastJsonConcurrencyMode.SingleThreaded)
            {
                return(new Deserializer <T>(parseString, parseReader));
            }
            else
            {
                return(new SafeDeserializer <T>(parseString, parseReader));
            }
#else
            if (settings.ConcurrencyMode == FastJsonConcurrencyMode.SingleThreaded)
            {
                return(new Deserializer <T>(parseString));
            }
            else
            {
                return(new SafeDeserializer <T>(parseString));
            }
#endif
        }