Ejemplo n.º 1
0
        public T DeserializeObject <T>(BinaryReader reader, DeserializeDelegate deserializeDelegate) where T : ISWCSerializable
        {
            var tag = ReadTag(reader);

            switch (tag)
            {
            case TagType.WRITEINSTANCEANDCACHEIT:
            {
                int key = reader.ReadInt32();
                var obj = deserializeDelegate(reader, this, serizlizedObjects, key);
                return((T)obj);
            }

            case TagType.INSTANCEATCACHE:
            {
                int index = reader.ReadInt32();

                //if (serizlizedObjects.ContainsKey(index))
                {
                    return((T)serizlizedObjects[index]);
                }
                //else
                //{
                //	serizlizedObjects.SetCallbacker(index, action);
                //	return default(T);
                //}
            }

            case TagType.NULLINSTANCE:
                return(default(T));

            default:
                throw new IOException("读取异常");
            }
        }
Ejemplo n.º 2
0
        public DynamicObjectFormatter(CerasSerializer serializer)
        {
            _ceras = serializer;

            var type = typeof(T);

            BannedTypes.ThrowIfNonspecific(type);

            var meta = _ceras.GetTypeMetaData(type);

            var typeConfig = _ceras.Config.GetTypeConfig(type);

            typeConfig.VerifyConstructionMethod();


            var schema = meta.PrimarySchema;

            if (schema.Members.Count > 0)
            {
                _dynamicSerializer   = GenerateSerializer(schema);
                _dynamicDeserializer = GenerateDeserializer(schema);
            }
            else
            {
                _dynamicSerializer   = (ref byte[] buffer, ref int offset, T value) => { };
                _dynamicDeserializer = (byte[] buffer, ref int offset, ref T value) => { };
            }
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Registers an artifact type with his serialization methods.
        /// </summary>
        /// <param name="name">The artifact extension.</param>
        /// <param name="serialize">The serialization method.</param>
        /// <param name="deserialize">The deserialization method.</param>
        /// <exception cref="System.ArgumentNullException">
        /// <paramref name="name"/>
        /// or
        /// <paramref name="serialize"/>
        /// or
        /// <paramref name="deserialize"/>
        /// </exception>
        /// <exception cref="System.ArgumentException">The specified artifact name is already registered.</exception>
        public void RegisterArtifactType(string name, SerializeDelegate serialize, DeserializeDelegate deserialize)
        {
            if (string.IsNullOrEmpty(name))
            {
                throw new ArgumentNullException("name");
            }
            if (serialize == null)
            {
                throw new ArgumentNullException("serialize");
            }
            if (deserialize == null)
            {
                throw new ArgumentNullException("deserialize");
            }

            if (!name.StartsWith("."))
            {
                name = "." + name;
            }

            if (artifactSerializers.ContainsKey(name))
            {
                throw new ArgumentException(@"The specified artifact name is already registered.", "name");
            }

            artifactSerializers.Add(name, new Serializer {
                Serialize   = serialize,
                Deserialize = deserialize
            });
        }
        private async Task <TReturn> GetAndMaybeReturnAsync <TReturn>(string key, DeserializeDelegate <TReturn> deserializeDelegate, TId id = default(TId), CancellationToken token = default(CancellationToken))
        {
            var byteArray = await Cache.GetAsync(key, token);

            if (byteArray == null)
            {
                return(default(TReturn));
            }
            var cacheEnvelope     = SerializingSupport.Deserialize <CacheEnvelope>(byteArray);
            var cacheItemStrategy = Equals(id, default(TId)) ? GetCacheItemStrategy(cacheEnvelope) : await GetCacheItemStrategyAsync(id, cacheEnvelope, token);

            switch (cacheItemStrategy)
            {
            case UseCacheStrategyEnum.Use:
                return(deserializeDelegate(cacheEnvelope));

            case UseCacheStrategyEnum.Ignore:
                return(default(TReturn));

            case UseCacheStrategyEnum.Remove:
                await Cache.RemoveAsync(key, token);

                return(default(TReturn));

            default:
                FulcrumAssert.Fail($"Unexpected value of {nameof(UseCacheStrategyEnum)} ({cacheItemStrategy}).");
                return(default(TReturn));
            }
        }
Ejemplo n.º 5
0
        public DynamicFormatter(CerasSerializer serializer, bool isStatic)
        {
            _ceras = serializer;

            var type = typeof(T);

            BannedTypes.ThrowIfNonspecific(type);

            var schema = isStatic
                                        ? _ceras.GetStaticTypeMetaData(type).PrimarySchema
                                        : _ceras.GetTypeMetaData(type).PrimarySchema;

            var typeConfig = _ceras.Config.GetTypeConfig(type, isStatic);

            typeConfig.VerifyConstructionMethod();

            if (!schema.IsPrimary)
            {
                throw new InvalidOperationException("Non-Primary Schema requires SchemaFormatter instead of DynamicFormatter!");
            }

            if (schema.Members.Count == 0)
            {
                _serializer   = (ref byte[] buffer, ref int offset, T value) => { };
                _deserializer = (byte[] buffer, ref int offset, ref T value) => { };
                return;
            }

            _serializer   = GenerateSerializer(_ceras, schema, false, isStatic).Compile();
            _deserializer = GenerateDeserializer(_ceras, schema, false, isStatic).Compile();
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Reads a format from the reader and deserializes the object
        /// </summary>
        /// <returns>The object.</returns>
        /// <param name="reader">Reader.</param>
        private static object DeserializeObject(BinaryReader reader)
        {
            byte format             = reader.ReadByte();
            DeserializeDelegate del = DeserializeTable [format];

            return(del(format, reader));
        }
 public BlobSerializerDelegate(SerializeDelegate serializeDelegate,
                               DeserializeDelegate deserializeDelegate,
                               CanSerializeDelegate canDeserializeDelegate)
 {
     this.serializeDelegate      = serializeDelegate;
     this.deserializeDelegate    = deserializeDelegate;
     this.canDeserializeDelegate = canDeserializeDelegate;
 }
Ejemplo n.º 8
0
        public TypeSchema Initialize(KnownSerializers serializers, TypeSchema targetSchema)
        {
            var schema = TypeSchema.FromType(typeof(T), serializers.RuntimeVersion, this.GetType(), Version);

            this.serializeImpl   = Generator.GenerateSerializeMethod <T>(il => Generator.EmitPrimitiveSerialize(typeof(T), il));
            this.deserializeImpl = Generator.GenerateDeserializeMethod <T>(il => Generator.EmitPrimitiveDeserialize(typeof(T), il));
            return(targetSchema ?? schema);
        }
 public BlobSerializerDelegate(SerializeDelegate serializeDelegate,
                               DeserializeDelegate deserializeDelegate,
                               CanSerializeDelegate canDeserializeDelegate)
 {
     _serializeDelegate      = serializeDelegate;
     _deserializeDelegate    = deserializeDelegate;
     _canDeserializeDelegate = canDeserializeDelegate;
 }
Ejemplo n.º 10
0
        public SchemaDynamicFormatter(CerasSerializer ceras, Schema schema)
        {
            _ceras  = ceras;
            _schema = schema;

            _serializer   = GenerateSerializer(schema);
            _deserializer = GenerateDeserializer(schema);
        }
Ejemplo n.º 11
0
        public TypeSchema Initialize(KnownSerializers serializers, TypeSchema targetSchema)
        {
            var runtimeSchema = TypeSchema.FromType(typeof(T), serializers.RuntimeVersion, this.GetType(), Version);
            var members       = runtimeSchema.GetCompatibleMemberSet(targetSchema);

            this.serializeImpl   = Generator.GenerateSerializeMethod <T>(il => Generator.EmitSerializeFields(typeof(T), serializers, il, members));
            this.deserializeImpl = Generator.GenerateDeserializeMethod <T>(il => Generator.EmitDeserializeFields(typeof(T), serializers, il, members));

            return(targetSchema ?? runtimeSchema);
        }
Ejemplo n.º 12
0
        void ActivateSchema(Schema schema)
        {
            // What schema changes are relevant to us?
            // - Schema of own type
            // - Schema of value-types inside us (dispatches for ref types are handled by RefFormatter anyway)

            // For now we only adapt to change to the current type schema.
            // Do we have serializers prepared for this schema already?


            // Important sanity check, if this happens the user should definitely know about it!
            if (_deserializationDepth > 0)
            {
                if (schema.Type.IsValueType)
                {
                    throw new InvalidOperationException("Schema of a value-type has changed while an object-type is being deserialized. This is feature is WIP, check out GitHub for more information.");
                }
            }


            // Use already compiled serializers
            if (_generatedSerializerPairs.TryGetValue(schema, out var pair))
            {
                _serializer   = pair.Serializer;
                _deserializer = pair.Deserializer;

                _currentSchema = schema;
                return;
            }

            bool isStatic = schema.IsStatic;

            // Generate
            if (schema.IsPrimary)
            {
                _serializer = DynamicFormatter <T> .GenerateSerializer(_ceras, schema, true, isStatic).Compile();

                _deserializer = DynamicFormatter <T> .GenerateDeserializer(_ceras, schema, true, isStatic).Compile();
            }
            else
            {
                // Different Schema -> generate no serializer!
                // Writing data in some old format is not supported (yet, maybe in the future).
                // In theory we could do it. But it's not implemented because there would have to be some way for the user to specify what Schema to use.
                // And we get into all sorts of troubles with type-conversion (not implemented yet, but it will probably arrive earlier than this...)
                // This also protects us against bugs!
                _serializer   = ErrorSerializer;
                _deserializer = DynamicFormatter <T> .GenerateDeserializer(_ceras, schema, true, isStatic).Compile();
            }

            _currentSchema = schema;

            _generatedSerializerPairs.Add(schema, new SerializerPair(_serializer, _deserializer));
        }
Ejemplo n.º 13
0
        public StructPropertyConverter(Type owner, PropertyInfo property, IJsonConverter valueConverter)
        {
            var instance  = Expression.Parameter(owner.MakeByRefType());
            var converter = Expression.Constant(valueConverter, valueConverter.GetType());

            Serialize = SerializationUtils.BuildSerialize <SerializeDelegate>(instance, property, converter);
            Write     = SerializationUtils.BuildWrite <WriteDelegate>(instance, property, converter);

            if (property.CanWrite)
            {
                Deserialize = SerializationUtils.BuildDeserialize <DeserializeDelegate>(instance, property, converter);
                Read        = SerializationUtils.BuildRead <ReadDelegate>(instance, property, converter);
            }
            else
            {
                Deserialize = ReadonlyProperty;
                Read        = ReadonlyProperty;
            }
        }
Ejemplo n.º 14
0
        protected Tuple <long, T> DeserializeTime <T>(DeserializeDelegate <T> deserializer, string input)
        {
            var output = new List <T>(WarmCount + TestCount);

            for (var i = 0; i < WarmCount; i++)
            {
                var obj = deserializer(input);
                output.Add(obj);
            }
            var start = PerformGc();

            for (var i = 0; i < TestCount; i++)
            {
                var obj = deserializer(input);
                output.Add(obj);
            }
            var end = Ticks();

            return(new Tuple <long, T>(end - start, output[Random.Next(WarmCount + TestCount)]));
        }
Ejemplo n.º 15
0
        public DataDefinition(Type type)
        {
            Type = type;

            var fieldDefs = GetFieldDefinitions();

            Duplicates = fieldDefs
                         .Where(f =>
                                fieldDefs.Count(df => df.Attribute.Tag == f.Attribute.Tag) > 1)
                         .Select(f => f.Attribute.Tag)
                         .Distinct()
                         .ToArray();

            var fields = fieldDefs;

            fields.Sort((a, b) => b.Attribute.Priority.CompareTo(a.Attribute.Priority));

            BaseFieldDefinitions = fields.ToImmutableArray();
            DefaultValues        = fieldDefs.Select(f => f.DefaultValue).ToArray();

            _deserialize = EmitDeserializationDelegate();
            _populate    = EmitPopulateDelegate();
            _serialize   = EmitSerializeDelegate();
            _copy        = EmitCopyDelegate();

            FieldAccessors = new AccessField <object, object?> [BaseFieldDefinitions.Length];

            for (var i = 0; i < BaseFieldDefinitions.Length; i++)
            {
                var fieldDefinition = BaseFieldDefinitions[i];
                FieldAccessors[i] = EmitFieldAccessor(fieldDefinition);
            }

            FieldAssigners = new AssignField <object, object?> [BaseFieldDefinitions.Length];

            for (var i = 0; i < BaseFieldDefinitions.Length; i++)
            {
                var fieldDefinition = BaseFieldDefinitions[i];
                FieldAssigners[i] = EmitFieldAssigner(fieldDefinition);
            }
        }
Ejemplo n.º 16
0
        public DynamicObjectFormatter(CerasSerializer serializer)
        {
            _ceras = serializer;

            var type = typeof(T);

            ThrowIfBanned(type);
            ThrowIfNonspecific(type);

            var schema = serializer.GetSerializationSchema(type, _ceras.Config.DefaultTargets, _ceras.Config.ShouldSerializeMember);

            if (schema.Members.Count > 0)
            {
                _dynamicSerializer   = GenerateSerializer(schema.Members);
                _dynamicDeserializer = GenerateDeserializer(schema.Members);
            }
            else
            {
                _dynamicSerializer   = (ref byte[] buffer, ref int offset, T value) => { };
                _dynamicDeserializer = (byte[] buffer, ref int offset, ref T value) => { };
            }
        }
 public static void RegisterDeserializer(string ID, DeserializeDelegate deserializer)
 {
     deserializers.Add(ID, deserializer);
 }
Ejemplo n.º 18
0
 public SerializerPair(SerializeDelegate <T> serializer, DeserializeDelegate <T> deserializer)
 {
     Serializer   = serializer;
     Deserializer = deserializer;
 }
Ejemplo n.º 19
0
        private Tuple <long, string> DeserializeTimeNewtonsoftJson()
        {
            DeserializeDelegate <string> deserializer = JsonConvert.DeserializeObject <string>;

            return(DeserializeTime(deserializer, JsonValue));
        }
Ejemplo n.º 20
0
        public DeserializerTypeDescriptor(Type type)
        {
            var ifaces            = type.GetInterfaces();
            var iListType         = ifaces.FirstOrDefault(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IList <>));
            var iDictionaryType   = ifaces.FirstOrDefault(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IDictionary <,>));
            var isIList           = iListType != null;
            var isIDictionary     = iDictionaryType != null;
            var runtimeProperties = type.GetRuntimeProperties().OrderBy(p => p.Name).Where(prop =>
            {
                if (prop.IsSpecialName || !prop.CanRead || !prop.CanWrite)
                {
                    return(false);
                }
                if (prop.GetAttribute <NonSerializeAttribute>() != null)
                {
                    return(false);
                }
                if (prop.GetIndexParameters().Length > 0)
                {
                    return(false);
                }
                if (isIList && prop.Name == "Capacity")
                {
                    return(false);
                }
                return(true);
            }).ToArray();

            Activator       = Factory.Accessors.CreateActivator(type);
            IsNSerializable = ifaces.Any(i => i == typeof(IRawSerializable));
            Properties      = new Dictionary <string, FastPropertyInfo>();
            var propNames = new string[runtimeProperties.Length];
            var idx       = 0;

            foreach (var prop in runtimeProperties)
            {
                Properties[prop.Name] = prop.GetFastPropertyInfo();
                propNames[idx++]      = prop.Name;
            }
            var isArray = type.IsArray;

            if (isArray)
            {
                isIList       = false;
                isIDictionary = false;
            }
            Metadata = new DeserializerMetaDataOfType(type, isArray, isIList, isIDictionary, propNames);

            //*** Expressions
            var serExpressions = new List <Expression>();
            var varExpressions = new List <ParameterExpression>();
            //
            var table        = Expression.Parameter(typeof(DeserializersTable), "table");
            var returnTarget = Expression.Label(typeof(object), "ReturnTarget");

            var value    = Expression.Parameter(type, "value");
            var capacity = Expression.Parameter(typeof(int), "capacity");

            varExpressions.Add(value);
            varExpressions.Add(capacity);

            var objectCache = Expression.Field(table, "ObjectCache");

            if (isArray)
            {
                var elementType = type.GetElementType();

                serExpressions.Add(Expression.Assign(capacity, Expression.Call(table, DeserializersTable.StreamReadIntMethod)));
                serExpressions.Add(Expression.Assign(value, Expression.NewArrayBounds(elementType, capacity)));
                serExpressions.Add(Expression.Call(objectCache, "Set", Type.EmptyTypes, value));

                var methodName = "InnerReadValue";
                if (DeserializersTable.ReadValuesFromType.TryGetValue(elementType, out var propMethod))
                {
                    methodName = propMethod.Name;
                }
                else if (elementType.IsEnum)
                {
                    methodName = DeserializersTable.ReadValuesFromType[typeof(Enum)].Name;
                }
                else if (elementType == typeof(object))
                {
                    methodName = "ReadValue";
                }

                var forIdx = Expression.Parameter(typeof(int), "i");
                varExpressions.Add(forIdx);
                var breakLabel = Expression.Label(typeof(void), "exitLoop");
                serExpressions.Add(Expression.Assign(forIdx, Expression.Constant(0)));
                var loop = Expression.Loop(
                    Expression.IfThenElse(
                        Expression.LessThan(forIdx, capacity),
                        Expression.Assign(Expression.ArrayAccess(value, Expression.PostIncrementAssign(forIdx)),
                                          Expression.Convert(Expression.Call(table, methodName, Type.EmptyTypes, Expression.Call(table, "StreamReadByte", Type.EmptyTypes)), elementType)),
                        Expression.Break(breakLabel)), breakLabel);
                serExpressions.Add(loop);
            }
            else if (isIList)
            {
                serExpressions.Add(Expression.Assign(capacity, Expression.Call(table, DeserializersTable.StreamReadIntMethod)));
                serExpressions.Add(Expression.Assign(value, Expression.New(type)));
                serExpressions.Add(Expression.Call(objectCache, "Set", Type.EmptyTypes, value));

                var addMethod   = type.GetMethod("Add", iListType.GenericTypeArguments);
                var elementType = iListType.GenericTypeArguments[0];
                var methodName  = "InnerReadValue";
                if (DeserializersTable.ReadValuesFromType.TryGetValue(elementType, out var propMethod))
                {
                    methodName = propMethod.Name;
                }
                else if (elementType.IsEnum)
                {
                    methodName = DeserializersTable.ReadValuesFromType[typeof(Enum)].Name;
                }
                else if (elementType == typeof(object))
                {
                    methodName = "ReadValue";
                }

                var forIdx = Expression.Parameter(typeof(int), "i");
                varExpressions.Add(forIdx);
                var breakLabel = Expression.Label(typeof(void), "exitLoop");
                serExpressions.Add(Expression.Assign(forIdx, Expression.Constant(0)));
                var loop = Expression.Loop(
                    Expression.IfThenElse(
                        Expression.LessThan(forIdx, capacity),
                        Expression.Block(
                            Expression.Call(value, addMethod, Expression.Convert(Expression.Call(table, methodName, Type.EmptyTypes, Expression.Call(table, "StreamReadByte", Type.EmptyTypes)), elementType)),
                            Expression.PostIncrementAssign(forIdx)
                            ),
                        Expression.Break(breakLabel)), breakLabel);
                serExpressions.Add(loop);
            }
            else if (isIDictionary)
            {
                serExpressions.Add(Expression.Assign(capacity, Expression.Call(table, DeserializersTable.StreamReadIntMethod)));
                serExpressions.Add(Expression.Assign(value, Expression.New(type)));
                serExpressions.Add(Expression.Call(objectCache, "Set", Type.EmptyTypes, value));

                var addMethod        = type.GetMethod("Add", iDictionaryType.GenericTypeArguments);
                var keyElementType   = iDictionaryType.GenericTypeArguments[0];
                var valueElementType = iDictionaryType.GenericTypeArguments[1];

                var keyMethodName = "InnerReadValue";
                if (DeserializersTable.ReadValuesFromType.TryGetValue(keyElementType, out var keyPropMethod))
                {
                    keyMethodName = keyPropMethod.Name;
                }
                else if (keyElementType.IsEnum)
                {
                    keyMethodName = DeserializersTable.ReadValuesFromType[typeof(Enum)].Name;
                }
                else if (keyElementType == typeof(object))
                {
                    keyMethodName = "ReadValue";
                }

                var valueMethodName = "InnerReadValue";
                if (DeserializersTable.ReadValuesFromType.TryGetValue(valueElementType, out var valuePropMethod))
                {
                    valueMethodName = valuePropMethod.Name;
                }
                else if (valueElementType.IsEnum)
                {
                    valueMethodName = DeserializersTable.ReadValuesFromType[typeof(Enum)].Name;
                }
                else if (valueElementType == typeof(object))
                {
                    valueMethodName = "ReadValue";
                }

                var forIdx = Expression.Parameter(typeof(int), "i");
                varExpressions.Add(forIdx);
                var breakLabel = Expression.Label(typeof(void), "exitLoop");
                serExpressions.Add(Expression.Assign(forIdx, Expression.Constant(0)));
                var loop = Expression.Loop(
                    Expression.IfThenElse(
                        Expression.LessThan(forIdx, capacity),
                        Expression.Block(
                            Expression.Call(value, addMethod,
                                            Expression.Convert(Expression.Call(table, keyMethodName, Type.EmptyTypes, Expression.Call(table, "StreamReadByte", Type.EmptyTypes)), keyElementType),
                                            Expression.Convert(Expression.Call(table, valueMethodName, Type.EmptyTypes, Expression.Call(table, "StreamReadByte", Type.EmptyTypes)), valueElementType)),
                            Expression.PostIncrementAssign(forIdx)
                            ),
                        Expression.Break(breakLabel)), breakLabel);
                serExpressions.Add(loop);
            }
            else
            {
                serExpressions.Add(Expression.Assign(value, Expression.New(type)));
                serExpressions.Add(Expression.Call(objectCache, "Set", Type.EmptyTypes, value));
            }
            foreach (var prop in runtimeProperties)
            {
                var setExp = Expression.Property(value, prop);
                serExpressions.Add(Expression.Assign(setExp, GetValueExpression(prop.PropertyType, table)));
            }

            serExpressions.Add(Expression.Call(table, "StreamReadByte", Type.EmptyTypes));
            serExpressions.Add(Expression.Return(returnTarget, value, typeof(object)));
            serExpressions.Add(Expression.Label(returnTarget, value));

            var block  = Expression.Block(varExpressions, serExpressions).Reduce();
            var lambda = Expression.Lambda <DeserializeDelegate>(block, type.Name + "_Deserializer", new[] { table });

            //Lambda = lambda;
            DeserializeFunc = lambda.Compile();
        }
Ejemplo n.º 21
0
        private Tuple <long, string> DeserializeTimeJsonLib(IJsonContext ctx)
        {
            DeserializeDelegate <string> deserializer = ctx.GetSerializator <string>().FromJson;

            return(DeserializeTime(deserializer, JsonValue));
        }
Ejemplo n.º 22
0
        DeserializeTimeNewtonsoftJson()
        {
            DeserializeDelegate <Dictionary <string, Dictionary <string, Dictionary <string, int?> > > > deserializer =
                JsonConvert.DeserializeObject <Dictionary <string, Dictionary <string, Dictionary <string, int?> > > >;

            return(DeserializeTime(deserializer, JsonValue));
        }
Ejemplo n.º 23
0
        private Tuple <long, MediumObject> DeserializeTimeJsonLib(IJsonContext ctx)
        {
            DeserializeDelegate <MediumObject> deserializer = ctx.GetSerializator <MediumObject>().FromJson;

            return(DeserializeTime(deserializer, JsonValue));
        }
Ejemplo n.º 24
0
        private Tuple <long, MediumObject> DeserializeTimeNewtonsoftJson()
        {
            DeserializeDelegate <MediumObject> deserializer = JsonConvert.DeserializeObject <MediumObject>;

            return(DeserializeTime(deserializer, JsonValue));
        }
Ejemplo n.º 25
0
        private Tuple <long, Dictionary <string, Dictionary <string, Dictionary <string, int?> > > > DeserializeTimeJsonLib(
            IJsonContext ctx)
        {
            DeserializeDelegate <Dictionary <string, Dictionary <string, Dictionary <string, int?> > > > deserializer =
                ctx.GetSerializator <Dictionary <string, Dictionary <string, Dictionary <string, int?> > > >().FromJson;

            return(DeserializeTime(deserializer, JsonValue));
        }