Пример #1
0
        private uint GetEnumTypeIndex(TypeDesc type)
        {
            System.Diagnostics.Debug.Assert(type.IsEnum, "GetEnumTypeIndex was called with wrong type");
            DefType defType = type as DefType;

            System.Diagnostics.Debug.Assert(defType != null, "GetEnumTypeIndex was called with non def type");
            List <FieldDesc> fieldsDescriptors = new List <FieldDesc>();

            foreach (var field in defType.GetFields())
            {
                if (field.IsLiteral)
                {
                    fieldsDescriptors.Add(field);
                }
            }
            EnumTypeDescriptor enumTypeDescriptor = new EnumTypeDescriptor
            {
                ElementCount = (ulong)fieldsDescriptors.Count,
                ElementType  = PrimitiveTypeDescriptor.GetPrimitiveTypeIndex(defType.UnderlyingType),
                Name         = _objectWriter.GetMangledName(type),
            };

            EnumRecordTypeDescriptor[] typeRecords = new EnumRecordTypeDescriptor[enumTypeDescriptor.ElementCount];
            for (int i = 0; i < fieldsDescriptors.Count; ++i)
            {
                FieldDesc field = fieldsDescriptors[i];
                EnumRecordTypeDescriptor recordTypeDescriptor;
                recordTypeDescriptor.Value = GetEnumRecordValue(field);
                recordTypeDescriptor.Name  = field.Name;
                typeRecords[i]             = recordTypeDescriptor;
            }
            uint typeIndex = _objectWriter.GetEnumTypeIndex(enumTypeDescriptor, typeRecords);

            return(typeIndex);
        }
        private Expression BuildCreateEnumTypeExpression(EnumTypeDescriptor enumTypeDescriptor)
        {
            var sqlTypeExpression = new SqlTypeExpression(enumTypeDescriptor.Name, true);
            var asExpression      = new SqlEnumDefinitionExpression(enumTypeDescriptor.GetValues());

            return(new SqlCreateTypeExpression(sqlTypeExpression, asExpression, true));
        }
Пример #3
0
        public static TypeReferenceBuilder ToTypeReference(
            this ITypeDescriptor typeReferenceDescriptor,
            TypeReferenceBuilder?builder = null)
        {
            TypeReferenceBuilder actualBuilder = builder ?? TypeReferenceBuilder.New();

            if (typeReferenceDescriptor is NonNullTypeDescriptor n)
            {
                typeReferenceDescriptor = n.InnerType;
            }
            else
            {
                actualBuilder.SetIsNullable(true);
            }

            return(typeReferenceDescriptor switch
            {
                ListTypeDescriptor list =>
                ToTypeReference(list.InnerType, actualBuilder.SetListType()),

                EnumTypeDescriptor @enum =>
                actualBuilder.SetName(@enum.RuntimeType.ToString()),

                ILeafTypeDescriptor leaf =>
                actualBuilder.SetName(leaf.RuntimeType.ToString()),

                INamedTypeDescriptor named =>
                actualBuilder.SetName(named.RuntimeType.ToString()),

                _ => throw new ArgumentOutOfRangeException(nameof(typeReferenceDescriptor))
            });
Пример #4
0
        public ITypeDescriptor Create(Type type)
        {
            SerializerTypeInfo result;

            if (_typeOrDescriptor2Info.TryGetValue(type, out result))
            {
                return(result.Descriptor);
            }
            if (_typeOrDescriptor2InfoNew.TryGetValue(type, out result))
            {
                return(result.Descriptor);
            }
            ITypeDescriptor desc = null;

            if (!type.IsSubclassOf(typeof(Delegate)))
            {
                if (type.IsGenericType)
                {
                    if (type.GetGenericTypeDefinition().InheritsOrImplements(typeof(IList <>)))
                    {
                        desc = new ListTypeDescriptor(this, type);
                    }
                    else if (type.GetGenericTypeDefinition().InheritsOrImplements(typeof(IDictionary <,>)))
                    {
                        desc = new DictionaryTypeDescriptor(this, type);
                    }
                }
                else if (type.IsArray)
                {
                    desc = new ListTypeDescriptor(this, type);
                }
                else if (type.IsEnum)
                {
                    desc = new EnumTypeDescriptor(this, type);
                }
                else
                {
                    desc = new ObjectTypeDescriptor(this, type);
                }
            }
            if (desc == null)
            {
                throw new BTDBException("Don't know how to serialize type " + type.ToSimpleName());
            }
            result = new SerializerTypeInfo
            {
                Id         = 0,
                Descriptor = desc
            };
            _typeOrDescriptor2InfoNew[desc] = result;
            _typeOrDescriptor2InfoNew[type] = result;
            desc.FinishBuildFromType(this);
            return(desc);
        }
Пример #5
0
        public void ProcessMetadataLog(ByteBuffer buffer)
        {
            var reader = new ByteBufferReader(buffer);
            var typeId = reader.ReadVInt32();

            while (typeId != 0)
            {
                var             typeCategory = (TypeCategory)reader.ReadUInt8();
                ITypeDescriptor descriptor;
                switch (typeCategory)
                {
                case TypeCategory.BuildIn:
                    throw new ArgumentOutOfRangeException();

                case TypeCategory.Class:
                    descriptor = new ObjectTypeDescriptor(this, reader, NestedDescriptorReader);
                    break;

                case TypeCategory.List:
                    descriptor = new ListTypeDescriptor(this, reader, NestedDescriptorReader);
                    break;

                case TypeCategory.Dictionary:
                    descriptor = new DictionaryTypeDescriptor(this, reader, NestedDescriptorReader);
                    break;

                case TypeCategory.Enum:
                    descriptor = new EnumTypeDescriptor(this, reader);
                    break;

                case TypeCategory.Nullable:
                    descriptor = new NullableTypeDescriptor(this, reader, NestedDescriptorReader);
                    break;

                default:
                    throw new ArgumentOutOfRangeException();
                }
                while (-typeId - 1 >= _id2InfoNew.Count)
                {
                    _id2InfoNew.Add(null);
                }
                if (_id2InfoNew[-typeId - 1] == null)
                {
                    _id2InfoNew[-typeId - 1] = new DeserializerTypeInfo {
                        Id = typeId, Descriptor = descriptor
                    }
                }
                ;
                typeId = reader.ReadVInt32();
            }
            for (var i = 0; i < _id2InfoNew.Count; i++)
            {
                _id2InfoNew[i].Descriptor.MapNestedTypes(d =>
                {
                    var placeHolderDescriptor = d as PlaceHolderDescriptor;
                    return(placeHolderDescriptor != null ? _id2InfoNew[-placeHolderDescriptor.TypeId - 1].Descriptor : d);
                });
            }
            // This additional cycle is needed to fill names of recursive structures
            for (var i = 0; i < _id2InfoNew.Count; i++)
            {
                _id2InfoNew[i].Descriptor.MapNestedTypes(d => d);
            }
            for (var i = 0; i < _id2InfoNew.Count; i++)
            {
                var infoForType = _id2InfoNew[i];
                for (var j = ReservedBuildinTypes; j < _id2Info.Count; j++)
                {
                    if (infoForType.Descriptor.Equals(_id2Info[j].Descriptor))
                    {
                        _remapToOld[infoForType.Descriptor] = _id2Info[j].Descriptor;
                        _id2InfoNew[i] = _id2Info[j];
                        infoForType    = _id2InfoNew[i];
                        break;
                    }
                }
                if (infoForType.Id < 0)
                {
                    infoForType.Id = _id2Info.Count;
                    _id2Info.Add(infoForType);
                    _typeOrDescriptor2Info[infoForType.Descriptor] = infoForType;
                }
            }
            for (var i = 0; i < _id2InfoNew.Count; i++)
            {
                _id2InfoNew[i].Descriptor.MapNestedTypes(d =>
                {
                    ITypeDescriptor res;
                    return(_remapToOld.TryGetValue(d, out res) ? res : d);
                });
            }
            _id2InfoNew.Clear();
            _remapToOld.Clear();
        }

        Func <AbstractBufferedReader, ITypeBinaryDeserializerContext, ITypeDescriptor, object> LoaderFactory(ITypeDescriptor descriptor)
        {
            var loadAsType    = LoadAsType(descriptor);
            var methodBuilder = ILBuilder.Instance.NewMethod <Func <AbstractBufferedReader, ITypeBinaryDeserializerContext, ITypeDescriptor, object> >("DeserializerFor" + descriptor.Name);
            var il            = methodBuilder.Generator;

            descriptor.GenerateLoad(il, ilGen => ilGen.Ldarg(0), ilGen => ilGen.Ldarg(1), ilGen => ilGen.Ldarg(2), loadAsType);
            if (loadAsType.IsValueType)
            {
                il.Box(loadAsType);
            }
            else if (loadAsType != typeof(object))
            {
                il.Castclass(typeof(object));
            }
            il.Ret();
            return(methodBuilder.Create());
        }
Пример #6
0
 public uint GetEnumTypeIndex(EnumTypeDescriptor enumTypeDescriptor, EnumRecordTypeDescriptor[] typeRecords)
 {
     return(GetEnumTypeIndex(_nativeObjectWriter, enumTypeDescriptor, typeRecords));
 }
Пример #7
0
 private static extern uint GetEnumTypeIndex(IntPtr objWriter, EnumTypeDescriptor enumTypeDescriptor, EnumRecordTypeDescriptor[] typeRecords);
Пример #8
0
 uint ITypesDebugInfoWriter.GetEnumTypeIndex(EnumTypeDescriptor enumTypeDescriptor, EnumRecordTypeDescriptor[] typeRecords)
 {
     return(_dbgInfoWriter.GetEnumTypeIndex(enumTypeDescriptor, typeRecords));
 }
Пример #9
0
        public ITypeDescriptor Create(Type type)
        {
            if (_typeOrDescriptor2Info.TryGetValue(type, out var result))
            {
                return(result.Descriptor);
            }
            if (_typeOrDescriptor2InfoNew.TryGetValue(type, out result))
            {
                return(result.Descriptor);
            }
            ITypeDescriptor desc            = null;
            Type            typeAlternative = null;

            if (!type.IsSubclassOf(typeof(Delegate)))
            {
                if (type.IsGenericType)
                {
                    typeAlternative = type.SpecializationOf(typeof(IList <>));
                    if (typeAlternative != null)
                    {
                        if (type != typeAlternative)
                        {
                            if (_typeOrDescriptor2Info.TryGetValue(typeAlternative, out result))
                            {
                                _typeOrDescriptor2Info[type] = result;
                                return(result.Descriptor);
                            }

                            if (_typeOrDescriptor2InfoNew.TryGetValue(typeAlternative, out result))
                            {
                                _typeOrDescriptor2InfoNew[type] = result;
                                return(result.Descriptor);
                            }
                        }

                        desc = new ListTypeDescriptor(this, typeAlternative);
                    }
                    else
                    {
                        typeAlternative = type.SpecializationOf(typeof(IDictionary <,>));
                        if (typeAlternative != null)
                        {
                            if (type != typeAlternative)
                            {
                                if (_typeOrDescriptor2Info.TryGetValue(typeAlternative, out result))
                                {
                                    _typeOrDescriptor2Info[type] = result;
                                    return(result.Descriptor);
                                }

                                if (_typeOrDescriptor2InfoNew.TryGetValue(typeAlternative, out result))
                                {
                                    _typeOrDescriptor2InfoNew[type] = result;
                                    return(result.Descriptor);
                                }
                            }

                            desc = new DictionaryTypeDescriptor(this, typeAlternative);
                        }
                        else if (type.GetGenericTypeDefinition().InheritsOrImplements(typeof(IIndirect <>)))
                        {
                            return(null);
                        }
                        else if (type.GetGenericTypeDefinition() == typeof(Nullable <>))
                        {
                            typeAlternative = type.SpecializationOf(typeof(Nullable <>));
                            if (typeAlternative != null)
                            {
                                if (type != typeAlternative)
                                {
                                    if (_typeOrDescriptor2Info.TryGetValue(typeAlternative, out result))
                                    {
                                        _typeOrDescriptor2Info[type] = result;
                                        return(result.Descriptor);
                                    }

                                    if (_typeOrDescriptor2InfoNew.TryGetValue(typeAlternative, out result))
                                    {
                                        _typeOrDescriptor2InfoNew[type] = result;
                                        return(result.Descriptor);
                                    }
                                }

                                desc = new NullableTypeDescriptor(this, typeAlternative);
                            }
                        }
                    }
                }
                else if (type.IsArray)
                {
                    typeAlternative = type.SpecializationOf(typeof(IList <>));
                    Debug.Assert(typeAlternative != null && type != typeAlternative);
                    if (_typeOrDescriptor2Info.TryGetValue(typeAlternative, out result))
                    {
                        _typeOrDescriptor2Info[type] = result;
                        return(result.Descriptor);
                    }

                    if (_typeOrDescriptor2InfoNew.TryGetValue(typeAlternative, out result))
                    {
                        _typeOrDescriptor2InfoNew[type] = result;
                        return(result.Descriptor);
                    }

                    desc = new ListTypeDescriptor(this, typeAlternative);
                }
                else if (type.IsEnum)
                {
                    desc = new EnumTypeDescriptor(this, type);
                }
                else if (type.IsValueType)
                {
                    throw new BTDBException($"Unsupported value type {type.Name}.");
                }
                else
                {
                    desc = new ObjectTypeDescriptor(this, type);
                }
            }

            if (desc == null)
            {
                throw new BTDBException("Don't know how to serialize type " + type.ToSimpleName());
            }
            result = new SerializerTypeInfo
            {
                Id         = 0,
                Descriptor = desc
            };
            _typeOrDescriptor2InfoNew[desc] = result;
            _typeOrDescriptor2InfoNew[type] = result;
            if (typeAlternative != null)
            {
                _typeOrDescriptor2InfoNew[typeAlternative] = result;
            }
            if (!desc.FinishBuildFromType(this))
            {
                _typeOrDescriptor2InfoNew.Remove(desc);
                _typeOrDescriptor2InfoNew.Remove(type);
                if (typeAlternative != null)
                {
                    _typeOrDescriptor2InfoNew.Remove(typeAlternative);
                }
                return(null);
            }

            return(desc);
        }
Пример #10
0
        public void ProcessMetadataLog(ByteBuffer buffer)
        {
            var reader = new ByteBufferReader(buffer);
            var typeId = reader.ReadVInt32();

            while (typeId != 0)
            {
                var             typeCategory = (TypeCategory)reader.ReadUInt8();
                ITypeDescriptor descriptor;
                switch (typeCategory)
                {
                case TypeCategory.BuildIn:
                    throw new ArgumentOutOfRangeException();

                case TypeCategory.Class:
                    descriptor = new ObjectTypeDescriptor(this, reader, NestedDescriptorReader);
                    break;

                case TypeCategory.List:
                    descriptor = new ListTypeDescriptor(this, reader, NestedDescriptorReader);
                    break;

                case TypeCategory.Dictionary:
                    descriptor = new DictionaryTypeDescriptor(this, reader, NestedDescriptorReader);
                    break;

                case TypeCategory.Enum:
                    descriptor = new EnumTypeDescriptor(this, reader);
                    break;

                case TypeCategory.Nullable:
                    descriptor = new NullableTypeDescriptor(this, reader, NestedDescriptorReader);
                    break;

                default:
                    throw new ArgumentOutOfRangeException();
                }

                while (-typeId - 1 >= _id2InfoNew.Count)
                {
                    _id2InfoNew.Add(null);
                }
                if (_id2InfoNew[-typeId - 1] == null)
                {
                    _id2InfoNew[-typeId - 1] = new SerializerTypeInfo {
                        Id = typeId, Descriptor = descriptor
                    }
                }
                ;
                typeId = reader.ReadVInt32();
            }

            for (var i = 0; i < _id2InfoNew.Count; i++)
            {
                _id2InfoNew[i] !.Descriptor.MapNestedTypes(d =>
                {
                    var placeHolderDescriptor = d as PlaceHolderDescriptor;
                    return(placeHolderDescriptor != null
                        ? _id2InfoNew[-placeHolderDescriptor.TypeId - 1] !.Descriptor
                        : d);
                });
            }

            // This additional cycle is needed to fill names of recursive structures
            for (var i = 0; i < _id2InfoNew.Count; i++)
            {
                _id2InfoNew[i] !.Descriptor.MapNestedTypes(d => d);
            }

            for (var i = 0; i < _id2InfoNew.Count; i++)
            {
                var infoForType = _id2InfoNew[i] !;
                for (var j = ReservedBuildinTypes; j < _id2Info.Count; j++)
                {
                    if (infoForType.Descriptor.Equals(_id2Info[j].Descriptor))
                    {
                        _remapToOld[infoForType.Descriptor] = _id2Info[j].Descriptor;
                        _id2InfoNew[i] = _id2Info[j];
                        infoForType    = _id2InfoNew[i];
                        break;
                    }
                }

                if (infoForType.Id < 0)
                {
                    infoForType.Id = _id2Info.Count;
                    _id2Info.Add(infoForType);
                    _typeOrDescriptor2Info[infoForType.Descriptor] = infoForType;
                }
            }

            for (var i = 0; i < _id2InfoNew.Count; i++)
            {
                _id2InfoNew[i] !.Descriptor.MapNestedTypes(d =>
                {
                    ITypeDescriptor res;
                    return(_remapToOld.TryGetValue(d, out res) ? res : d);
                });
            }

            _id2InfoNew.Clear();
            _remapToOld.Clear();
        }
Пример #11
0
 public static EnumTypeDescriptor ToDescriptor(
     this EnumTypeDefinition definition,
     IDescriptorContext context)
 => EnumTypeDescriptor.From(context, definition);
        private Expression BuildCreateEnumTypeExpression(EnumTypeDescriptor enumTypeDescriptor)
        {
            var sqlTypeExpression = new SqlTypeExpression(enumTypeDescriptor.Name);
            var asExpression = new SqlEnumDefinitionExpression(enumTypeDescriptor.GetValues());

            return new SqlCreateTypeExpression(sqlTypeExpression, asExpression, true);
        }