/// <summary> /// Gets the serializer. /// </summary> private static IBinarySerializerInternal GetSerializer(BinaryConfiguration cfg, BinaryTypeConfiguration typeCfg, Type type, int typeId, IBinaryNameMapper nameMapper, IBinaryIdMapper idMapper, ILogger log) { var serializer = (typeCfg != null ? typeCfg.Serializer : null) ?? (cfg != null ? cfg.Serializer : null); if (serializer == null) { if (type.GetInterfaces().Contains(typeof(IBinarizable))) { return(BinarizableSerializer.Instance); } if (type.GetInterfaces().Contains(typeof(ISerializable))) { LogSerializableWarning(type, log); return(new SerializableSerializer(type)); } serializer = new BinaryReflectiveSerializer { ForceTimestamp = cfg != null && cfg.ForceTimestamp }; } var refSerializer = serializer as BinaryReflectiveSerializer; return(refSerializer != null ? refSerializer.Register(type, typeId, nameMapper, idMapper) : new UserSerializerProxy(serializer)); }
/// <summary> /// Gets descriptor for a type id. /// </summary> /// <param name="userType">User type flag.</param> /// <param name="typeId">Type id.</param> /// <param name="requiresType">If set to true, resulting descriptor must have Type property populated. /// <para /> /// When working in binary mode, we don't need Type. And there is no Type at all in some cases. /// So we should not attempt to call BinaryProcessor right away. /// Only when we really deserialize the value, requiresType is set to true /// and we attempt to resolve the type by all means.</param> /// <param name="typeName">Known type name.</param> /// <param name="knownType">Optional known type.</param> /// <returns> /// Descriptor. /// </returns> public IBinaryTypeDescriptor GetDescriptor(bool userType, int typeId, bool requiresType = false, string typeName = null, Type knownType = null) { BinaryFullTypeDescriptor desc; var typeKey = BinaryUtils.TypeKey(userType, typeId); if (_idToDesc.TryGetValue(typeKey, out desc) && (!requiresType || desc.Type != null)) { return(desc); } if (!userType) { return(null); } if (requiresType && _ignite != null) { // Check marshaller context for dynamically registered type. var type = knownType; if (type == null && _ignite != null) { typeName = typeName ?? _ignite.BinaryProcessor.GetTypeName(typeId); if (typeName != null) { type = new TypeResolver().ResolveType(typeName, nameMapper: _cfg.NameMapper ?? GetDefaultNameMapper()); if (type == null) { // Type is registered, but assembly is not present. return(new BinarySurrogateTypeDescriptor(_cfg, typeId, typeName)); } } } if (type != null) { return(AddUserType(type, typeId, GetTypeName(type), true, desc)); } } var meta = GetBinaryType(typeId); if (meta != BinaryType.Empty) { var typeCfg = new BinaryTypeConfiguration(meta.TypeName) { IsEnum = meta.IsEnum, AffinityKeyFieldName = meta.AffinityKeyFieldName }; return(AddUserType(typeCfg, new TypeResolver())); } return(new BinarySurrogateTypeDescriptor(_cfg, typeId, typeName)); }
/// <summary> /// Add user type. /// </summary> /// <param name="cfg">Configuration.</param> /// <param name="typeCfg">Type configuration.</param> /// <param name="typeResolver">The type resolver.</param> /// <param name="dfltSerializer">The default serializer.</param> private void AddUserType(BinaryConfiguration cfg, BinaryTypeConfiguration typeCfg, TypeResolver typeResolver, IBinarySerializer dfltSerializer) { // Get converter/mapper/serializer. IBinaryNameMapper nameMapper = typeCfg.NameMapper ?? cfg.DefaultNameMapper; IBinaryIdMapper idMapper = typeCfg.IdMapper ?? cfg.DefaultIdMapper; bool keepDeserialized = typeCfg.KeepDeserialized ?? cfg.DefaultKeepDeserialized; // Try resolving type. Type type = typeResolver.ResolveType(typeCfg.TypeName); if (type != null) { // Type is found. var typeName = BinaryUtils.GetTypeName(type); int typeId = BinaryUtils.TypeId(typeName, nameMapper, idMapper); var serializer = typeCfg.Serializer ?? cfg.DefaultSerializer ?? GetBinarizableSerializer(type) ?? dfltSerializer; var refSerializer = serializer as BinaryReflectiveSerializer; if (refSerializer != null) { refSerializer.Register(type, typeId, nameMapper, idMapper); } if (typeCfg.IsEnum != type.IsEnum) { throw new BinaryObjectException( string.Format( "Invalid IsEnum flag in binary type configuration. " + "Configuration value: IsEnum={0}, actual type: IsEnum={1}", typeCfg.IsEnum, type.IsEnum)); } var affKeyFld = typeCfg.AffinityKeyFieldName ?? GetAffinityKeyFieldNameFromAttribute(type); AddType(type, typeId, typeName, true, keepDeserialized, nameMapper, idMapper, serializer, affKeyFld, type.IsEnum); } else { // Type is not found. string typeName = BinaryUtils.SimpleTypeName(typeCfg.TypeName); int typeId = BinaryUtils.TypeId(typeName, nameMapper, idMapper); AddType(null, typeId, typeName, true, keepDeserialized, nameMapper, idMapper, null, typeCfg.AffinityKeyFieldName, typeCfg.IsEnum); } }
public void TestStructure() { for (int i = 1; i <= RepeatCnt; i++) { Console.WriteLine(">>> Iteration started: " + i); // 1. Generate and shuffle objects. IList <BranchedType> objs = new List <BranchedType>(); for (int j = 0; j < 6 * ObjectsPerMode; j++) { objs.Add(new BranchedType((j % 6) + 1)); } objs = IgniteUtils.Shuffle(objs); // 2. Create new marshaller. BinaryTypeConfiguration typeCfg = new BinaryTypeConfiguration(typeof(BranchedType)); BinaryConfiguration cfg = new BinaryConfiguration { TypeConfigurations = new List <BinaryTypeConfiguration> { typeCfg } }; Marshaller marsh = new Marshaller(cfg); // 3. Marshal all data and ensure deserialized object is fine. foreach (BranchedType obj in objs) { Console.WriteLine(">>> Write object [mode=" + obj.mode + ']'); byte[] data = marsh.Marshal(obj); BranchedType other = marsh.Unmarshal <BranchedType>(data); Assert.IsTrue(obj.Equals(other)); } Console.WriteLine(); // 4. Ensure that all fields are recorded. var desc = marsh.GetDescriptor(typeof(BranchedType)); CollectionAssert.AreEquivalent(new[] { "mode", "f2", "f3", "f4", "f5", "f6", "f7", "f8" }, desc.WriterTypeStructure.FieldTypes.Keys); } }
/// <summary> /// Add user type. /// </summary> /// <param name="typeCfg">Type configuration.</param> /// <param name="typeResolver">The type resolver.</param> /// <exception cref="BinaryObjectException"></exception> private BinaryFullTypeDescriptor AddUserType(BinaryTypeConfiguration typeCfg, TypeResolver typeResolver) { // Get converter/mapper/serializer. IBinaryNameMapper nameMapper = typeCfg.NameMapper ?? _cfg.NameMapper ?? GetDefaultNameMapper(); IBinaryIdMapper idMapper = typeCfg.IdMapper ?? _cfg.IdMapper; bool keepDeserialized = typeCfg.KeepDeserialized ?? _cfg.KeepDeserialized; // Try resolving type. Type type = typeResolver.ResolveType(typeCfg.TypeName); if (type != null) { ValidateUserType(type); if (typeCfg.IsEnum != BinaryUtils.IsIgniteEnum(type)) { throw new BinaryObjectException( string.Format( "Invalid IsEnum flag in binary type configuration. " + "Configuration value: IsEnum={0}, actual type: IsEnum={1}, type={2}", typeCfg.IsEnum, type.IsEnum, type)); } // Type is found. var typeName = GetTypeName(type, nameMapper); int typeId = GetTypeId(typeName, idMapper); var affKeyFld = typeCfg.AffinityKeyFieldName ?? AffinityKeyMappedAttribute.GetFieldNameFromAttribute(type); var serializer = GetSerializer(_cfg, typeCfg, type, typeId, nameMapper, idMapper, _log); return(AddType(type, typeId, typeName, true, keepDeserialized, nameMapper, idMapper, serializer, affKeyFld, BinaryUtils.IsIgniteEnum(type))); } else { // Type is not found. string typeName = GetTypeName(typeCfg.TypeName, nameMapper); int typeId = GetTypeId(typeName, idMapper); return(AddType(null, typeId, typeName, true, keepDeserialized, nameMapper, idMapper, null, typeCfg.AffinityKeyFieldName, typeCfg.IsEnum)); } }
/// <summary> /// Add user type. /// </summary> /// <param name="cfg">Configuration.</param> /// <param name="typeCfg">Type configuration.</param> /// <param name="typeResolver">The type resolver.</param> /// <param name="dfltSerializer">The default serializer.</param> private void AddUserType(BinaryConfiguration cfg, BinaryTypeConfiguration typeCfg, TypeResolver typeResolver, IBinarySerializer dfltSerializer) { // Get converter/mapper/serializer. IBinaryNameMapper nameMapper = typeCfg.NameMapper ?? cfg.DefaultNameMapper; IBinaryIdMapper idMapper = typeCfg.IdMapper ?? cfg.DefaultIdMapper; bool keepDeserialized = typeCfg.KeepDeserialized ?? cfg.DefaultKeepDeserialized; // Try resolving type. Type type = typeResolver.ResolveType(typeCfg.TypeName); if (type != null) { // Type is found. var typeName = GetTypeName(type); int typeId = BinaryUtils.TypeId(typeName, nameMapper, idMapper); var serializer = typeCfg.Serializer ?? cfg.DefaultSerializer ?? GetBinarizableSerializer(type) ?? dfltSerializer; var refSerializer = serializer as BinaryReflectiveSerializer; if (refSerializer != null) { refSerializer.Register(type, typeId, nameMapper, idMapper); } AddType(type, typeId, typeName, true, keepDeserialized, nameMapper, idMapper, serializer, typeCfg.AffinityKeyFieldName); } else { // Type is not found. string typeName = BinaryUtils.SimpleTypeName(typeCfg.TypeName); int typeId = BinaryUtils.TypeId(typeName, nameMapper, idMapper); AddType(null, typeId, typeName, true, keepDeserialized, nameMapper, idMapper, null, typeCfg.AffinityKeyFieldName); } }
public void TestStructure() { for (int i = 1; i <= RepeatCnt; i++) { Console.WriteLine(">>> Iteration started: " + i); // 1. Generate and shuffle objects. IList <BranchedType> objs = new List <BranchedType>(); for (int j = 0; j < 6 * ObjectsPerMode; j++) { objs.Add(new BranchedType((j % 6) + 1)); } objs = IgniteUtils.Shuffle(objs); // 2. Create new marshaller. BinaryTypeConfiguration typeCfg = new BinaryTypeConfiguration(typeof(BranchedType)); BinaryConfiguration cfg = new BinaryConfiguration { TypeConfigurations = new List <BinaryTypeConfiguration> { typeCfg } }; Marshaller marsh = new Marshaller(cfg); // 3. Marshal all data and ensure deserialized object is fine. // Use single stream to test object offsets using (var stream = new BinaryHeapStream(128)) { var writer = marsh.StartMarshal(stream); foreach (var obj in objs) { Console.WriteLine(">>> Write object [mode=" + obj.mode + ']'); writer.WriteObject(obj); } stream.Seek(0, SeekOrigin.Begin); var reader = marsh.StartUnmarshal(stream); foreach (var obj in objs) { var other = reader.ReadObject <BranchedType>(); Assert.IsTrue(obj.Equals(other)); } } Console.WriteLine(); // 4. Ensure that all fields are recorded. var desc = marsh.GetDescriptor(typeof(BranchedType)); CollectionAssert.AreEquivalent(new[] { "mode", "f2", "f3", "f4", "f5", "f6", "f7", "f8" }, desc.WriterTypeStructure.FieldTypes.Keys); } }
/// <summary> /// Gets the serializer. /// </summary> private static IBinarySerializerInternal GetSerializer(BinaryConfiguration cfg, BinaryTypeConfiguration typeCfg, Type type, int typeId, IBinaryNameMapper nameMapper, IBinaryIdMapper idMapper) { var serializer = typeCfg.Serializer ?? cfg.DefaultSerializer; if (serializer == null) { if (type.GetInterfaces().Contains(typeof(IBinarizable))) { return(BinarizableSerializer.Instance); } serializer = new BinaryReflectiveSerializer(); } var refSerializer = serializer as BinaryReflectiveSerializer; return(refSerializer != null ? refSerializer.Register(type, typeId, nameMapper, idMapper) : new UserSerializerProxy(serializer)); }