예제 #1
0
        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="type">Type.</param>
        /// <param name="typeId">Type ID.</param>
        /// <param name="typeName">Type name.</param>
        /// <param name="userType">User type flag.</param>
        /// <param name="nameMapper">Name converter.</param>
        /// <param name="idMapper">Mapper.</param>
        /// <param name="serializer">Serializer.</param>
        /// <param name="keepDeserialized">Whether to cache deserialized value in IBinaryObject</param>
        /// <param name="affKeyFieldName">Affinity field key name.</param>
        /// <param name="isEnum">Enum flag.</param>
        /// <param name="isRegistered">Registered flag.</param>
        public BinaryFullTypeDescriptor(
            Type type,
            int typeId,
            string typeName,
            bool userType,
            IBinaryNameMapper nameMapper,
            IBinaryIdMapper idMapper,
            IBinarySerializerInternal serializer,
            bool keepDeserialized,
            string affKeyFieldName,
            bool isEnum,
            bool isRegistered = true)
        {
            _type             = type;
            _typeId           = typeId;
            _typeName         = typeName;
            _userType         = userType;
            _nameMapper       = nameMapper;
            _idMapper         = idMapper;
            _serializer       = serializer;
            _keepDeserialized = keepDeserialized;
            _affKeyFieldName  = affKeyFieldName;
            _isEnum           = isEnum;

            _isRegistered = isRegistered;
            _schema       = new BinaryObjectSchema();
        }
예제 #2
0
        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="type">Type.</param>
        /// <param name="typeId">Type ID.</param>
        /// <param name="typeName">Type name.</param>
        /// <param name="userType">User type flag.</param>
        /// <param name="nameMapper">Name converter.</param>
        /// <param name="idMapper">Mapper.</param>
        /// <param name="serializer">Serializer.</param>
        /// <param name="keepDeserialized">Whether to cache deserialized value in IBinaryObject</param>
        /// <param name="affKeyFieldName">Affinity field key name.</param>
        /// <param name="isEnum">Enum flag.</param>
        /// <param name="comparer">Equality comparer.</param>
        public BinaryFullTypeDescriptor(
            Type type,
            int typeId,
            string typeName,
            bool userType,
            IBinaryNameMapper nameMapper,
            IBinaryIdMapper idMapper,
            IBinarySerializerInternal serializer,
            bool keepDeserialized,
            string affKeyFieldName,
            bool isEnum,
            IEqualityComparer <IBinaryObject> comparer)
        {
            _type             = type;
            _typeId           = typeId;
            _typeName         = typeName;
            _userType         = userType;
            _nameMapper       = nameMapper;
            _idMapper         = idMapper;
            _serializer       = serializer;
            _keepDeserialized = keepDeserialized;
            _affKeyFieldName  = affKeyFieldName;
            _isEnum           = isEnum;

            _equalityComparer = comparer as IBinaryEqualityComparer;

            if (comparer != null && _equalityComparer == null)
            {
                throw new IgniteException(string.Format("Unsupported IEqualityComparer<IBinaryObject> " +
                                                        "implementation: {0}. Only predefined implementations " +
                                                        "are supported.", comparer.GetType()));
            }
        }
예제 #3
0
        /// <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>
        /// Registers the specified type.
        /// </summary>
        internal IBinarySerializerInternal Register(Type type, int typeId, IBinaryNameMapper converter,
                                                    IBinaryIdMapper idMapper)
        {
            _isInUse = true;

            return(new BinaryReflectiveSerializerInternal(_rawMode).Register(type, typeId, converter, idMapper));
        }
예제 #5
0
        /// <summary>
        /// Resolve type ID.
        /// </summary>
        /// <param name="typeName">Type name.</param>
        /// <param name="idMapper">ID mapper.</param>
        private static int GetTypeId(string typeName, IBinaryIdMapper idMapper)
        {
            Debug.Assert(typeName != null);

            int id = 0;

            if (idMapper != null)
            {
                try
                {
                    id = idMapper.GetTypeId(typeName);
                }
                catch (Exception e)
                {
                    throw new BinaryObjectException("Failed to resolve type ID due to ID mapper exception " +
                                                    "[typeName=" + typeName + ", idMapper=" + idMapper + ']', e);
                }
            }

            if (id == 0)
            {
                id = BinaryUtils.GetStringHashCodeLowerCase(typeName);
            }

            return(id);
        }
        /// <summary>Register type.</summary>
        /// <param name="type">Type.</param>
        /// <param name="typeId">Type ID.</param>
        /// <param name="converter">Name converter.</param>
        /// <param name="idMapper">ID mapper.</param>
        internal BinaryReflectiveSerializerInternal Register(Type type, int typeId, IBinaryNameMapper converter,
                                                             IBinaryIdMapper idMapper)
        {
            Debug.Assert(_wActions == null && _rActions == null);

            List <FieldInfo> fields = new List <FieldInfo>();

            Type curType = type;

            while (curType != null)
            {
                foreach (FieldInfo field in curType.GetFields(Flags))
                {
                    if (!field.IsNotSerialized)
                    {
                        fields.Add(field);
                    }
                }

                curType = curType.BaseType;
            }

            IDictionary <int, string> idMap = new Dictionary <int, string>();

            foreach (FieldInfo field in fields)
            {
                string fieldName = BinaryUtils.CleanFieldName(field.Name);

                int fieldId = BinaryUtils.FieldId(typeId, fieldName, converter, idMapper);

                if (idMap.ContainsKey(fieldId))
                {
                    throw new BinaryObjectException("Conflicting field IDs [type=" +
                                                    type.Name + ", field1=" + idMap[fieldId] + ", field2=" + fieldName +
                                                    ", fieldId=" + fieldId + ']');
                }

                idMap[fieldId] = fieldName;
            }

            fields.Sort(Compare);

            var wActions = new BinaryReflectiveWriteAction[fields.Count];
            var rActions = new BinaryReflectiveReadAction[fields.Count];

            for (int i = 0; i < fields.Count; i++)
            {
                BinaryReflectiveWriteAction writeAction;
                BinaryReflectiveReadAction  readAction;

                BinaryReflectiveActions.GetTypeActions(fields[i], out writeAction, out readAction, _rawMode);

                wActions[i] = writeAction;
                rActions[i] = readAction;
            }

            return(new BinaryReflectiveSerializerInternal(wActions, rActions, _rawMode));
        }
예제 #7
0
        /// <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);
            }
        }
예제 #8
0
        /// <summary>
        /// Register type.
        /// </summary>
        /// <param name="type">Type.</param>
        /// <param name="typeId">Type ID.</param>
        /// <param name="converter">Name converter.</param>
        /// <param name="idMapper">ID mapper.</param>
        /// <param name="forceTimestamp">Force timestamp serialization for DateTime fields..</param>
        /// <returns>Resulting serializer.</returns>
        internal BinaryReflectiveSerializerInternal Register(Type type, int typeId, IBinaryNameMapper converter,
                                                             IBinaryIdMapper idMapper, bool forceTimestamp)
        {
            Debug.Assert(_wActions == null && _rActions == null);

            var fields = ReflectionUtils.GetAllFields(type).Where(x => !x.IsNotSerialized).ToList();

            IDictionary <int, string> idMap = new Dictionary <int, string>();

            foreach (FieldInfo field in fields)
            {
                string fieldName = BinaryUtils.CleanFieldName(field.Name);

                int fieldId = BinaryUtils.FieldId(typeId, fieldName, converter, idMapper);

                if (idMap.ContainsKey(fieldId))
                {
                    if (fieldName == idMap[fieldId])
                    {
                        string baseClassName = field.DeclaringType != null ? field.DeclaringType.Name : null;
                        throw new BinaryObjectException(string.Format(
                                                            "{0} derives from {1} and hides field {2} from the base class. " +
                                                            "Ignite can not serialize two fields with the same name.", type.Name, baseClassName, fieldName));
                    }

                    throw new BinaryObjectException(string.Format(
                                                        "Conflicting field IDs [type={0}, field1={1}, field2={2}, fieldId={3}])",
                                                        type.Name, idMap[fieldId], fieldName, fieldId));
                }

                idMap[fieldId] = fieldName;
            }

            fields.Sort(Compare);

            var wActions = new BinaryReflectiveWriteAction[fields.Count];
            var rActions = new BinaryReflectiveReadAction[fields.Count];

            for (int i = 0; i < fields.Count; i++)
            {
                BinaryReflectiveWriteAction writeAction;
                BinaryReflectiveReadAction  readAction;

                BinaryReflectiveActions.GetTypeActions(fields[i], out writeAction, out readAction, _rawMode, forceTimestamp);

                wActions[i] = writeAction;
                rActions[i] = readAction;
            }

            var serDesc = SerializableTypeDescriptor.Get(type);

            return(new BinaryReflectiveSerializerInternal(wActions, rActions, _rawMode, serDesc));
        }
예제 #9
0
        /// <summary>Register type.</summary>
        /// <param name="type">Type.</param>
        /// <param name="typeId">Type ID.</param>
        /// <param name="converter">Name converter.</param>
        /// <param name="idMapper">ID mapper.</param>
        public void Register(Type type, int typeId, IBinaryNameMapper converter,
                             IBinaryIdMapper idMapper)
        {
            if (type.GetInterface(typeof(IBinarizable).Name) != null)
            {
                return;
            }

            List <FieldInfo> fields = new List <FieldInfo>();

            Type curType = type;

            while (curType != null)
            {
                foreach (FieldInfo field in curType.GetFields(Flags))
                {
                    if (!field.IsNotSerialized)
                    {
                        fields.Add(field);
                    }
                }

                curType = curType.BaseType;
            }

            IDictionary <int, string> idMap = new Dictionary <int, string>();

            foreach (FieldInfo field in fields)
            {
                string fieldName = BinaryUtils.CleanFieldName(field.Name);

                int fieldId = BinaryUtils.FieldId(typeId, fieldName, converter, idMapper);

                if (idMap.ContainsKey(fieldId))
                {
                    throw new BinaryObjectException("Conflicting field IDs [type=" +
                                                    type.Name + ", field1=" + idMap[fieldId] + ", field2=" + fieldName +
                                                    ", fieldId=" + fieldId + ']');
                }

                idMap[fieldId] = fieldName;
            }

            fields.Sort(Compare);

            Descriptor desc = new Descriptor(fields);

            _types[type] = desc;
        }
예제 #10
0
        /// <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>Register type.</summary>
        /// <param name="type">Type.</param>
        /// <param name="typeId">Type ID.</param>
        /// <param name="converter">Name converter.</param>
        /// <param name="idMapper">ID mapper.</param>
        public void Register(Type type, int typeId, IBinaryNameMapper converter,
            IBinaryIdMapper idMapper)
        {
            if (type.GetInterface(typeof(IBinarizable).Name) != null)
                return;

            List<FieldInfo> fields = new List<FieldInfo>();

            Type curType = type;

            while (curType != null)
            {
                foreach (FieldInfo field in curType.GetFields(Flags))
                {
                    if (!field.IsNotSerialized)
                        fields.Add(field);
                }

                curType = curType.BaseType;
            }

            IDictionary<int, string> idMap = new Dictionary<int, string>();

            foreach (FieldInfo field in fields)
            {
                string fieldName = BinaryUtils.CleanFieldName(field.Name);

                int fieldId = BinaryUtils.FieldId(typeId, fieldName, converter, idMapper);

                if (idMap.ContainsKey(fieldId))
                {
                    throw new BinaryObjectException("Conflicting field IDs [type=" +
                        type.Name + ", field1=" + idMap[fieldId] + ", field2=" + fieldName +
                        ", fieldId=" + fieldId + ']');
                }

                idMap[fieldId] = fieldName;
            }

            fields.Sort(Compare);

            Descriptor desc = new Descriptor(fields);

            _types[type] = desc;
        }
        /// <summary>
        /// Register type.
        /// </summary>
        /// <param name="type">Type.</param>
        /// <param name="typeId">Type ID.</param>
        /// <param name="converter">Name converter.</param>
        /// <param name="idMapper">ID mapper.</param>
        /// <param name="forceTimestamp">Force timestamp serialization for DateTime fields..</param>
        /// <returns>Resulting serializer.</returns>
        internal BinaryReflectiveSerializerInternal Register(Type type, int typeId, IBinaryNameMapper converter,
                                                             IBinaryIdMapper idMapper, bool forceTimestamp)
        {
            Debug.Assert(_wActions == null && _rActions == null);

            var fields = ReflectionUtils.GetAllFields(type).Where(x => !x.IsNotSerialized).ToList();

            IDictionary <int, string> idMap = new Dictionary <int, string>();

            foreach (FieldInfo field in fields)
            {
                string fieldName = BinaryUtils.CleanFieldName(field.Name);

                int fieldId = BinaryUtils.FieldId(typeId, fieldName, converter, idMapper);

                if (idMap.ContainsKey(fieldId))
                {
                    throw new BinaryObjectException("Conflicting field IDs [type=" +
                                                    type.Name + ", field1=" + idMap[fieldId] + ", field2=" + fieldName +
                                                    ", fieldId=" + fieldId + ']');
                }

                idMap[fieldId] = fieldName;
            }

            fields.Sort(Compare);

            var wActions = new BinaryReflectiveWriteAction[fields.Count];
            var rActions = new BinaryReflectiveReadAction[fields.Count];

            for (int i = 0; i < fields.Count; i++)
            {
                BinaryReflectiveWriteAction writeAction;
                BinaryReflectiveReadAction  readAction;

                BinaryReflectiveActions.GetTypeActions(fields[i], out writeAction, out readAction, _rawMode, forceTimestamp);

                wActions[i] = writeAction;
                rActions[i] = readAction;
            }

            var serDesc = SerializableTypeDescriptor.Get(type);

            return(new BinaryReflectiveSerializerInternal(wActions, rActions, _rawMode, serDesc));
        }
예제 #13
0
        /// <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);
            }
        }
예제 #14
0
        /// <summary>
        /// Initializes a new instance of the <see cref="BinaryFullTypeDescriptor"/> class,
        /// copying values from specified descriptor.
        /// </summary>
        /// <param name="desc">The descriptor to copy from.</param>
        /// <param name="type">Type.</param>
        /// <param name="serializer">Serializer.</param>
        /// <param name="isRegistered">Registered flag.</param>
        public BinaryFullTypeDescriptor(BinaryFullTypeDescriptor desc, Type type,
                                        IBinarySerializerInternal serializer, bool isRegistered)
        {
            _type             = type;
            _typeId           = desc._typeId;
            _typeName         = desc._typeName;
            _userType         = desc._userType;
            _nameMapper       = desc._nameMapper;
            _idMapper         = desc._idMapper;
            _serializer       = serializer;
            _keepDeserialized = desc._keepDeserialized;
            _affKeyFieldName  = desc._affKeyFieldName;
            _isEnum           = desc._isEnum;
            _isRegistered     = isRegistered;

            _schema              = desc._schema;
            _writerTypeStruct    = desc._writerTypeStruct;
            _readerTypeStructure = desc._readerTypeStructure;
        }
예제 #15
0
        /// <summary>
        /// Add type.
        /// </summary>
        /// <param name="type">Type.</param>
        /// <param name="typeId">Type ID.</param>
        /// <param name="typeName">Type name.</param>
        /// <param name="userType">User type flag.</param>
        /// <param name="keepDeserialized">Whether to cache deserialized value in IBinaryObject</param>
        /// <param name="nameMapper">Name mapper.</param>
        /// <param name="idMapper">ID mapper.</param>
        /// <param name="serializer">Serializer.</param>
        /// <param name="affKeyFieldName">Affinity key field name.</param>
        /// <param name="isEnum">Enum flag.</param>
        /// <param name="comparer">Comparer.</param>
        private void AddType(Type type, int typeId, string typeName, bool userType,
                             bool keepDeserialized, IBinaryNameMapper nameMapper, IBinaryIdMapper idMapper,
                             IBinarySerializerInternal serializer, string affKeyFieldName, bool isEnum,
                             IEqualityComparer <IBinaryObject> comparer)
        {
            long typeKey = BinaryUtils.TypeKey(userType, typeId);

            IBinaryTypeDescriptor conflictingType;

            if (_idToDesc.TryGetValue(typeKey, out conflictingType))
            {
                var type1 = conflictingType.Type != null
                    ? conflictingType.Type.AssemblyQualifiedName
                    : conflictingType.TypeName;

                var type2 = type != null ? type.AssemblyQualifiedName : typeName;

                throw new BinaryObjectException(string.Format("Conflicting type IDs [type1='{0}', " +
                                                              "type2='{1}', typeId={2}]", type1, type2, typeId));
            }

            if (userType && _typeNameToDesc.ContainsKey(typeName))
            {
                throw new BinaryObjectException("Conflicting type name: " + typeName);
            }

            var descriptor = new BinaryFullTypeDescriptor(type, typeId, typeName, userType, nameMapper, idMapper,
                                                          serializer, keepDeserialized, affKeyFieldName, isEnum, comparer);

            if (type != null)
            {
                _typeToDesc[type] = descriptor;
            }

            if (userType)
            {
                _typeNameToDesc[typeName] = descriptor;
            }

            _idToDesc.GetOrAdd(typeKey, _ => descriptor);
        }
예제 #16
0
 /// <summary>
 /// Constructor.
 /// </summary>
 /// <param name="type">Type.</param>
 /// <param name="typeId">Type ID.</param>
 /// <param name="typeName">Type name.</param>
 /// <param name="userType">User type flag.</param>
 /// <param name="nameMapper">Name converter.</param>
 /// <param name="idMapper">Mapper.</param>
 /// <param name="serializer">Serializer.</param>
 /// <param name="keepDeserialized">Whether to cache deserialized value in IBinaryObject</param>
 /// <param name="affKeyFieldName">Affinity field key name.</param>
 public BinaryFullTypeDescriptor(
     Type type,
     int typeId,
     string typeName,
     bool userType,
     IBinaryNameMapper nameMapper,
     IBinaryIdMapper idMapper,
     IBinarySerializer serializer,
     bool keepDeserialized,
     string affKeyFieldName)
 {
     _type             = type;
     _typeId           = typeId;
     _typeName         = typeName;
     _userType         = userType;
     _nameMapper       = nameMapper;
     _idMapper         = idMapper;
     _serializer       = serializer;
     _keepDeserialized = keepDeserialized;
     _affKeyFieldName  = affKeyFieldName;
 }
예제 #17
0
 /// <summary>
 /// Constructor.
 /// </summary>
 /// <param name="type">Type.</param>
 /// <param name="typeId">Type ID.</param>
 /// <param name="typeName">Type name.</param>
 /// <param name="userType">User type flag.</param>
 /// <param name="nameMapper">Name converter.</param>
 /// <param name="idMapper">Mapper.</param>
 /// <param name="serializer">Serializer.</param>
 /// <param name="keepDeserialized">Whether to cache deserialized value in IBinaryObject</param>
 /// <param name="affKeyFieldName">Affinity field key name.</param>
 public BinaryFullTypeDescriptor(
     Type type, 
     int typeId, 
     string typeName, 
     bool userType, 
     IBinaryNameMapper nameMapper, 
     IBinaryIdMapper idMapper, 
     IBinarySerializer serializer, 
     bool keepDeserialized, 
     string affKeyFieldName)
 {
     _type = type;
     _typeId = typeId;
     _typeName = typeName;
     _userType = userType;
     _nameMapper = nameMapper;
     _idMapper = idMapper;
     _serializer = serializer;
     _keepDeserialized = keepDeserialized;
     _affKeyFieldName = affKeyFieldName;
 }
예제 #18
0
        /// <summary>
        /// Add type.
        /// </summary>
        /// <param name="type">Type.</param>
        /// <param name="typeId">Type ID.</param>
        /// <param name="typeName">Type name.</param>
        /// <param name="userType">User type flag.</param>
        /// <param name="keepDeserialized">Whether to cache deserialized value in IBinaryObject</param>
        /// <param name="nameMapper">Name mapper.</param>
        /// <param name="idMapper">ID mapper.</param>
        /// <param name="serializer">Serializer.</param>
        /// <param name="affKeyFieldName">Affinity key field name.</param>
        /// <param name="isEnum">Enum flag.</param>
        private void AddType(Type type, int typeId, string typeName, bool userType,
                             bool keepDeserialized, IBinaryNameMapper nameMapper, IBinaryIdMapper idMapper,
                             IBinarySerializerInternal serializer, string affKeyFieldName, bool isEnum)
        {
            long typeKey = BinaryUtils.TypeKey(userType, typeId);

            BinaryFullTypeDescriptor conflictingType;

            if (_idToDesc.TryGetValue(typeKey, out conflictingType))
            {
                var type1 = conflictingType.Type != null
                    ? conflictingType.Type.AssemblyQualifiedName
                    : conflictingType.TypeName;

                var type2 = type != null ? type.AssemblyQualifiedName : typeName;

                ThrowConflictingTypeError(type1, type2, typeId);
            }

            if (userType && _typeNameToDesc.ContainsKey(typeName))
            {
                throw new BinaryObjectException("Conflicting type name: " + typeName);
            }

            var descriptor = new BinaryFullTypeDescriptor(type, typeId, typeName, userType, nameMapper, idMapper,
                                                          serializer, keepDeserialized, affKeyFieldName, isEnum);

            if (type != null)
            {
                _typeToDesc.GetOrAdd(type, x => descriptor);
            }

            if (userType)
            {
                _typeNameToDesc.GetOrAdd(typeName, x => descriptor);
            }

            _idToDesc.GetOrAdd(typeKey, _ => descriptor);
        }
예제 #19
0
        /// <summary>
        /// Write object.
        /// </summary>
        /// <param name="obj">Object.</param>
        public void Write <T>(T obj)
        {
            // Handle special case for null.
            if (obj == null)
            {
                _stream.WriteByte(BinaryUtils.HdrNull);

                return;
            }

            // We use GetType() of a real object instead of typeof(T) to take advantage of
            // automatic Nullable'1 unwrapping.
            Type type = obj.GetType();

            // Handle common case when primitive is written.
            if (type.IsPrimitive)
            {
                WritePrimitive(obj, type);

                return;
            }

            // Handle special case for builder.
            if (WriteBuilderSpecials(obj))
            {
                return;
            }

            // Suppose that we faced normal object and perform descriptor lookup.
            IBinaryTypeDescriptor desc = type.IsEnum ? null : _marsh.GetDescriptor(type);

            if (desc != null)
            {
                // Writing normal object.
                var pos = _stream.Position;

                // Dealing with handles.
                if (!(desc.Serializer is IBinarySystemTypeSerializer) && WriteHandle(pos, obj))
                {
                    return;
                }

                // Skip header length as not everything is known now
                _stream.Seek(BinaryObjectHeader.Size, SeekOrigin.Current);

                // Preserve old frame.
                int oldTypeId = _curTypeId;
                IBinaryNameMapper oldConverter = _curConverter;
                IBinaryIdMapper   oldMapper    = _curMapper;
                int oldRawPos = _curRawPos;
                var oldPos    = _curPos;

                var oldStruct = _curStruct;

                // Push new frame.
                _curTypeId    = desc.TypeId;
                _curConverter = desc.NameMapper;
                _curMapper    = desc.IdMapper;
                _curRawPos    = 0;
                _curPos       = pos;

                _curStruct = new BinaryStructureTracker(desc, desc.WriterTypeStructure);
                var schemaIdx = _schema.PushSchema();

                try
                {
                    // Write object fields.
                    desc.Serializer.WriteBinary(obj, this);

                    // Write schema
                    var schemaOffset = _stream.Position - pos;

                    int schemaId;

                    var flags = desc.UserType
                        ? BinaryObjectHeader.Flag.UserType
                        : BinaryObjectHeader.Flag.None;

                    var hasSchema = _schema.WriteSchema(_stream, schemaIdx, out schemaId, ref flags);

                    if (hasSchema)
                    {
                        flags |= BinaryObjectHeader.Flag.HasSchema;

                        // Calculate and write header.
                        if (_curRawPos > 0)
                        {
                            _stream.WriteInt(_curRawPos - pos); // raw offset is in the last 4 bytes
                        }
                    }
                    else
                    {
                        schemaOffset = BinaryObjectHeader.Size;
                    }

                    if (_curRawPos > 0)
                    {
                        flags |= BinaryObjectHeader.Flag.HasRaw;
                    }

                    var len = _stream.Position - pos;

                    var header = new BinaryObjectHeader(desc.TypeId, obj.GetHashCode(), len,
                                                        schemaId, schemaOffset, flags);

                    BinaryObjectHeader.Write(header, _stream, pos);

                    Stream.Seek(pos + len, SeekOrigin.Begin); // Seek to the end
                }
                finally
                {
                    _schema.PopSchema(schemaIdx);
                }

                // Apply structure updates if any.
                _curStruct.UpdateWriterStructure(this);

                // Restore old frame.
                _curTypeId    = oldTypeId;
                _curConverter = oldConverter;
                _curMapper    = oldMapper;
                _curRawPos    = oldRawPos;
                _curPos       = oldPos;

                _curStruct = oldStruct;
            }
            else
            {
                // Are we dealing with a well-known type?
                var handler = BinarySystemHandlers.GetWriteHandler(type);

                if (handler == null)  // We did our best, object cannot be marshalled.
                {
                    throw new BinaryObjectException("Unsupported object type [type=" + type + ", object=" + obj + ']');
                }

                handler(this, obj);
            }
        }
예제 #20
0
        /// <summary>
        /// Add type.
        /// </summary>
        /// <param name="type">Type.</param>
        /// <param name="typeId">Type ID.</param>
        /// <param name="typeName">Type name.</param>
        /// <param name="userType">User type flag.</param>
        /// <param name="keepDeserialized">Whether to cache deserialized value in IBinaryObject</param>
        /// <param name="nameMapper">Name mapper.</param>
        /// <param name="idMapper">ID mapper.</param>
        /// <param name="serializer">Serializer.</param>
        /// <param name="affKeyFieldName">Affinity key field name.</param>
        /// <param name="isEnum">Enum flag.</param>
        private BinaryFullTypeDescriptor AddType(Type type, int typeId, string typeName, bool userType,
                                                 bool keepDeserialized, IBinaryNameMapper nameMapper, IBinaryIdMapper idMapper,
                                                 IBinarySerializerInternal serializer, string affKeyFieldName, bool isEnum)
        {
            Debug.Assert(!string.IsNullOrEmpty(typeName));

            long typeKey = BinaryUtils.TypeKey(userType, typeId);

            BinaryFullTypeDescriptor conflictingType;

            if (_idToDesc.TryGetValue(typeKey, out conflictingType) && conflictingType.TypeName != typeName)
            {
                ThrowConflictingTypeError(typeName, conflictingType.TypeName, typeId);
            }

            var descriptor = new BinaryFullTypeDescriptor(type, typeId, typeName, userType, nameMapper, idMapper,
                                                          serializer, keepDeserialized, affKeyFieldName, isEnum);

            if (RegistrationDisabled)
            {
                return(descriptor);
            }

            if (type != null)
            {
                _typeToDesc.Set(type, descriptor);
            }

            if (userType)
            {
                _typeNameToDesc.Set(typeName, descriptor);
            }

            _idToDesc.Set(typeKey, descriptor);

            return(descriptor);
        }
예제 #21
0
        /// <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));
        }