public EventSerializer(ITypeNameMapper typeNameMapper = null, ITypeConvertorGenerator typeConvertorGenerator = null) { TypeNameMapper = typeNameMapper ?? new FullNameTypeMapper(); ConvertorGenerator = typeConvertorGenerator ?? new DefaultTypeConvertorGenerator(); _id2Info.Add(null); // 0 = null _id2Info.Add(null); // 1 = back reference foreach (var predefinedType in BasicSerializersFactory.TypeDescriptors) { var infoForType = new SerializerTypeInfo { Id = _id2Info.Count, Descriptor = predefinedType }; _typeOrDescriptor2Info[predefinedType] = infoForType; _id2Info.Add(infoForType); _typeOrDescriptor2Info[predefinedType.GetPreferedType()] = infoForType; var descriptorMultipleNativeTypes = predefinedType as ITypeDescriptorMultipleNativeTypes; if (descriptorMultipleNativeTypes == null) continue; foreach (var type in descriptorMultipleNativeTypes.GetNativeTypes()) { _typeOrDescriptor2Info[type] = infoForType; } } while (_id2Info.Count < ReservedBuildinTypes) _id2Info.Add(null); }
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; if (!desc.FinishBuildFromType(this)) { throw new BTDBException("Don't know how to serialize type " + type.ToSimpleName()); } return desc; }
public void StoreNewDescriptors(object obj) { if (obj == null) return; for (var i = 0; i < _visited.Count; i++) { if (_visited[i] == obj) return; } _visited.Add(obj); SerializerTypeInfo info; var knowDescriptor = obj as IKnowDescriptor; if (knowDescriptor != null) { if (!_typeOrDescriptor2Info.TryGetValue(knowDescriptor.GetDescriptor(), out info)) { info = new SerializerTypeInfo { Id = 0, Descriptor = knowDescriptor.GetDescriptor() }; _typeOrDescriptor2InfoNew[knowDescriptor.GetDescriptor()] = info; } } else { if (!_typeOrDescriptor2Info.TryGetValue(obj.GetType(), out info)) { var desc = Create(obj.GetType()); info = _typeOrDescriptor2InfoNew[desc]; } } if (info.NestedObjGatherer == null) { info.NestedObjGatherer = BuildNestedObjGatherer(info.Descriptor, knowDescriptor == null ? obj.GetType() : null); } info.NestedObjGatherer(obj, 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; 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(); }