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); }
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); }