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("读取异常"); } }
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) => { }; } }
/// <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)); } }
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(); }
/// <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; }
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; }
public SchemaDynamicFormatter(CerasSerializer ceras, Schema schema) { _ceras = ceras; _schema = schema; _serializer = GenerateSerializer(schema); _deserializer = GenerateDeserializer(schema); }
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); }
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)); }
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; } }
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)])); }
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); } }
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); }
public SerializerPair(SerializeDelegate <T> serializer, DeserializeDelegate <T> deserializer) { Serializer = serializer; Deserializer = deserializer; }
private Tuple <long, string> DeserializeTimeNewtonsoftJson() { DeserializeDelegate <string> deserializer = JsonConvert.DeserializeObject <string>; return(DeserializeTime(deserializer, JsonValue)); }
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(); }
private Tuple <long, string> DeserializeTimeJsonLib(IJsonContext ctx) { DeserializeDelegate <string> deserializer = ctx.GetSerializator <string>().FromJson; return(DeserializeTime(deserializer, JsonValue)); }
DeserializeTimeNewtonsoftJson() { DeserializeDelegate <Dictionary <string, Dictionary <string, Dictionary <string, int?> > > > deserializer = JsonConvert.DeserializeObject <Dictionary <string, Dictionary <string, Dictionary <string, int?> > > >; return(DeserializeTime(deserializer, JsonValue)); }
private Tuple <long, MediumObject> DeserializeTimeJsonLib(IJsonContext ctx) { DeserializeDelegate <MediumObject> deserializer = ctx.GetSerializator <MediumObject>().FromJson; return(DeserializeTime(deserializer, JsonValue)); }
private Tuple <long, MediumObject> DeserializeTimeNewtonsoftJson() { DeserializeDelegate <MediumObject> deserializer = JsonConvert.DeserializeObject <MediumObject>; return(DeserializeTime(deserializer, JsonValue)); }
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)); }