/// <summary> /// Formats nullable type /// </summary> /// <param name="nullableType"></param> /// <returns></returns> public override string FormatNullableType(NullableTypeDescriptor nullableType) { return(nullableType.TypeArgument.FormatType(this)); }
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()); }
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(); }
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); }
/// <summary> /// Formats a nullable type /// </summary> /// <param name="nullableType"></param> /// <returns></returns> public abstract string FormatNullableType(NullableTypeDescriptor nullableType);