public uint GetBoxId(object o) { uint boxId; if (o == null) { boxId = 0; } else { if (object2BoxId.TryGetValue(o, out boxId)) { return(boxId); } var type = o.GetType(); var typeInfo = StaticCache.GetTypeInfo(type); if (typeInfo.Transformer == null) { throw new ArgumentException("Cannot serialize object of type " + o.GetType()); } boxId = ++BoxCount; typeInfo.Used++; object2BoxId.Add(o, boxId); var box = typeInfo.Transformer.CreateBox(o, this); boxId2Box.Add(boxId, box); objectsToProcess.Enqueue(Tuple.Create(o, box)); } return(boxId); }
public object CreateInstance(Type type) { try { return(StaticCache.GetTypeInfo(type).GetConstructor()()); } catch (Exception e) { throw new PersistenceException("Deserialization failed.", e); } }
public static Bundle ToBundle(object root, out SerializationInfo info, CancellationToken cancellationToken = default(CancellationToken)) { StaticCache.UpdateRegisteredTypes(); var mapper = new Mapper { CancellationToken = cancellationToken }; var bundle = new Bundle(); info = new SerializationInfo(); var sw = new Stopwatch(); sw.Start(); bundle.RootBoxId = mapper.GetBoxId(root); while (mapper.objectsToProcess.Any()) { if (cancellationToken.IsCancellationRequested) { return(bundle); } var tuple = mapper.objectsToProcess.Dequeue(); var o = tuple.Item1; var box = tuple.Item2; var transformer = mapper.GetTransformer(mapper.GetTypeMetadata(box.TypeMetadataId).TransformerId); transformer.FillBox(box, o, mapper); } bundle.TransformerGuids.AddRange(mapper.transformers.GetValues().Select(x => x.Guid).Select(x => ByteString.CopyFrom(x.ToByteArray()))); bundle.TypeGuids.AddRange(mapper.types.GetValues().Select(x => ByteString.CopyFrom(StaticCache.GetGuid(x).ToByteArray()))); bundle.StorableTypeMetadata.AddRange(mapper.storableTypeLayouts.GetValues().Select(l => StorableTypeLayoutToMetadata(l, mapper))); bundle.ArrayMetadata.AddRange(mapper.arrayMetadata.GetValues()); bundle.TypeMetadata.AddRange(mapper.typeMetadata.GetValues()); bundle.Boxes.AddRange(mapper.boxId2Box.OrderBy(x => x.Key).Select(x => x.Value)); bundle.Strings.AddRange(mapper.strings.GetValues()); sw.Stop(); info.Duration = sw.Elapsed; info.NumberOfSerializedObjects = mapper.object2BoxId.Keys.Count; info.SerializedTypes = mapper.types.GetValues(); return(bundle); }
private static void ExecuteAfterDeserializationHooks(IEnumerator <object> e) { var emptyArgs = new object[0]; while (e.MoveNext()) { var obj = e.Current; if (obj == null || !StorableTypeAttribute.IsStorableType(obj.GetType())) { continue; } var typeList = new LinkedList <Type>(); for (var type = obj.GetType(); type != null; type = type.BaseType) { typeList.AddFirst(type); } foreach (var type in typeList) { if (!StorableTypeAttribute.IsStorableType(type)) { continue; } var typeInfo = StaticCache.GetTypeInfo(type); foreach (var hook in typeInfo.AfterDeserializationHooks) { try { hook.Invoke(obj, emptyArgs); } catch (TargetInvocationException t) { throw t.InnerException; } } } } }
public static object ToObject(Bundle bundle, out SerializationInfo info, CancellationToken cancellationToken = default(CancellationToken)) { StaticCache.UpdateRegisteredTypes(); var mapper = new Mapper { CancellationToken = cancellationToken }; info = new SerializationInfo(); var sw = new Stopwatch(); sw.Start(); mapper.transformers = new Index <ITransformer>(bundle.TransformerGuids.Select(x => new Guid(x.ToByteArray())).Select(StaticCache.GetTransformer)); var types = new List <Type>(); var unknownTypeGuids = new List <Guid>(); for (int i = 0; i < bundle.TypeGuids.Count; i++) { var x = bundle.TypeGuids[i]; var guid = new Guid(x.ToByteArray()); if (StaticCache.TryGetType(guid, out Type type)) { types.Add(type); } else { unknownTypeGuids.Add(guid); types.Add(null); } } mapper.types = new Index <Type>(types); mapper.typeMetadata = new Index <TypeMetadata>(bundle.TypeMetadata); mapper.boxId2Box = bundle.Boxes.Select((b, i) => new { Box = b, Index = i }).ToDictionary(k => (uint)k.Index + 1, v => v.Box); mapper.strings = new Index <string>(bundle.Strings); mapper.storableTypeLayouts = new Index <StorableTypeLayout>(bundle.StorableTypeMetadata.Select(l => StorableTypeMetadataToLayout(l, mapper))); mapper.arrayMetadata = new Index <ArrayMetadata>(bundle.ArrayMetadata); var boxes = bundle.Boxes; for (int i = boxes.Count - 1; i >= 0; i--) { if (cancellationToken.IsCancellationRequested) { return(null); } mapper.GetObject((uint)i + 1); } for (int i = boxes.Count; i > 0; i--) { if (cancellationToken.IsCancellationRequested) { return(null); } var box = mapper.boxId2Box[(uint)i]; var o = mapper.boxId2Object[(uint)i]; if (o == null) { continue; } var transformer = mapper.GetTransformer(mapper.GetTypeMetadata(box.TypeMetadataId).TransformerId); transformer.FillFromBox(o, box, mapper); } var root = mapper.GetObject(bundle.RootBoxId); ExecuteAfterDeserializationHooks(mapper.boxId2Object.Values.GetEnumerator()); sw.Stop(); info.Duration = sw.Elapsed; info.NumberOfSerializedObjects = mapper.boxId2Object.Values.Count; info.SerializedTypes = types; info.UnknownTypeGuids = unknownTypeGuids; return(root); }