예제 #1
0
        internal IProtoSerializer TryGetBasicTypeSerializer(Type type)
        {
            int idx = this.basicTypes.IndexOf(RuntimeTypeModel.BasicTypeFinder, type);

            if (idx >= 0)
            {
                return(((RuntimeTypeModel.BasicType) this.basicTypes[idx]).Serializer);
            }
            IProtoSerializer result;

            lock (this.basicTypes)
            {
                idx = this.basicTypes.IndexOf(RuntimeTypeModel.BasicTypeFinder, type);
                if (idx >= 0)
                {
                    result = ((RuntimeTypeModel.BasicType) this.basicTypes[idx]).Serializer;
                }
                else
                {
                    MetaType.AttributeFamily family = MetaType.GetContractFamily(this, type, null);
                    WireType         defaultWireType;
                    IProtoSerializer ser = (family == MetaType.AttributeFamily.None) ? ValueMember.TryGetCoreSerializer(this, DataFormat.Default, type, out defaultWireType, false, false, false, false) : null;
                    if (ser != null)
                    {
                        this.basicTypes.Add(new RuntimeTypeModel.BasicType(type, ser));
                    }
                    result = ser;
                }
            }
            return(result);
        }
예제 #2
0
        internal int FindOrAddAuto(Type type, bool demand, bool addWithContractOnly, bool addEvenIfAutoDisabled)
        {
            int key = this.types.IndexOf(RuntimeTypeModel.MetaTypeFinder, type);

            if (key >= 0)
            {
                MetaType metaType = (MetaType)this.types[key];
                if (metaType.Pending)
                {
                    this.WaitOnLock(metaType);
                }
                return(key);
            }
            bool shouldAdd = this.AutoAddMissingTypes || addEvenIfAutoDisabled;

            if (Helpers.IsEnum(type) || this.TryGetBasicTypeSerializer(type) == null)
            {
                Type underlyingType = TypeModel.ResolveProxies(type);
                if (underlyingType != null)
                {
                    key  = this.types.IndexOf(RuntimeTypeModel.MetaTypeFinder, underlyingType);
                    type = underlyingType;
                }
                if (key < 0)
                {
                    int opaqueToken = 0;
                    try
                    {
                        this.TakeLock(ref opaqueToken);
                        MetaType metaType;
                        if ((metaType = this.RecogniseCommonTypes(type)) == null)
                        {
                            MetaType.AttributeFamily family = MetaType.GetContractFamily(this, type, null);
                            if (family == MetaType.AttributeFamily.AutoTuple)
                            {
                                addEvenIfAutoDisabled = (shouldAdd = true);
                            }
                            if (!shouldAdd || (!Helpers.IsEnum(type) && addWithContractOnly && family == MetaType.AttributeFamily.None))
                            {
                                if (demand)
                                {
                                    TypeModel.ThrowUnexpectedType(type);
                                }
                                return(key);
                            }
                            metaType = this.Create(type);
                        }
                        metaType.Pending = true;
                        bool weAdded = false;
                        int  winner  = this.types.IndexOf(RuntimeTypeModel.MetaTypeFinder, type);
                        if (winner < 0)
                        {
                            this.ThrowIfFrozen();
                            key     = this.types.Add(metaType);
                            weAdded = true;
                        }
                        else
                        {
                            key = winner;
                        }
                        if (weAdded)
                        {
                            metaType.ApplyDefaultBehaviour();
                            metaType.Pending = false;
                        }
                    }
                    finally
                    {
                        this.ReleaseLock(opaqueToken);
                    }
                    return(key);
                }
                return(key);
            }
            if (shouldAdd && !addWithContractOnly)
            {
                throw MetaType.InbuiltType(type);
            }
            return(-1);
        }