diff --git a/UIX/Microsoft/Iris/Debug/BsonFormatter.cs b/UIX/Microsoft/Iris/Debug/BsonFormatter.cs new file mode 100644 index 0000000..0b02926 --- /dev/null +++ b/UIX/Microsoft/Iris/Debug/BsonFormatter.cs @@ -0,0 +1,87 @@ +using Newtonsoft.Json; +using Newtonsoft.Json.Bson; +using System; +using System.IO; +using System.Runtime.Serialization; + +namespace Microsoft.Iris.Debug; + +internal class BsonFormatter : IFormatter +{ + private readonly JsonSerializer _serializer; + + public ISurrogateSelector SurrogateSelector { get; set; } + + public SerializationBinder Binder { get; set; } + + public StreamingContext Context { get; set; } + + public BsonFormatter(JsonSerializerSettings settings = null) : this(new StreamingContext(StreamingContextStates.All), settings) + { + } + + public BsonFormatter(StreamingContext context, JsonSerializerSettings settings = null) + { + Context = context; + + settings ??= new() + { + ReferenceLoopHandling = ReferenceLoopHandling.Ignore, + Converters = new JsonConverter[] + { + new BsonFallbackConverter() + } + }; + _serializer = JsonSerializer.Create(settings); + } + + public object Deserialize(Stream serializationStream) + { + using BsonDataReader reader = new(serializationStream) + { + CloseInput = false + }; + return _serializer.Deserialize(reader); + } + + public void Serialize(Stream serializationStream, object graph) + { + using BsonDataWriter writer = new(serializationStream); + _serializer.Serialize(writer, graph); + writer.Flush(); + } +} + +internal class BsonFallbackConverter : JsonConverter +{ + public override bool CanConvert(Type objectType) + { + return !objectType.Attributes.HasFlag(System.Reflection.TypeAttributes.Serializable) + || objectType == typeof(uint) || objectType == typeof(ulong); + } + + public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) + { + if (objectType == typeof(uint)) + return Convert.ToUInt32(existingValue); + else if (objectType == typeof(ulong)) + return Convert.ToUInt64(existingValue); + else + return existingValue?.ToString(); + } + + public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) + { + var objectType = value?.GetType(); + object serializedValue; + + if (objectType == typeof(uint)) + serializedValue = BitConverter.GetBytes((uint)value); + else if (objectType == typeof(ulong)) + serializedValue = BitConverter.GetBytes((ulong)value); + else + serializedValue = value?.ToString(); + + serializer.Serialize(writer, serializedValue); + } +} diff --git a/UIX/Microsoft/Iris/Debug/Data/InterpreterObject.cs b/UIX/Microsoft/Iris/Debug/Data/InterpreterObject.cs index 6c3fb26..143ee60 100644 --- a/UIX/Microsoft/Iris/Debug/Data/InterpreterObject.cs +++ b/UIX/Microsoft/Iris/Debug/Data/InterpreterObject.cs @@ -4,7 +4,7 @@ using System.Runtime.Serialization; namespace Microsoft.Iris.Debug.Data; [Serializable] -public class InterpreterObject : ISerializable +public class InterpreterObject { public string Name { get; set; } @@ -16,8 +16,6 @@ public class InterpreterObject : ISerializable public int TableIndex { get; set; } = -1; - protected bool CanSerializeValue => Value is ISerializable; - public InterpreterObject(string name, Type type, object value, InstructionObjectSource source, int tableIndex = -1) { Name = name; @@ -31,29 +29,7 @@ public class InterpreterObject : ISerializable { } - protected InterpreterObject(SerializationInfo info, StreamingContext context) - { - Name = info.GetString(nameof(Name)); - Type = Type.GetType(info.GetString(nameof(Type)), false); - Source = (InstructionObjectSource)info.GetByte(nameof(Source)); - TableIndex = info.GetInt32(nameof(TableIndex)); - - bool canSerializeValue = info.GetBoolean(nameof(CanSerializeValue)); - Type valueSerializeType = canSerializeValue ? Type : typeof(string); - Value = info.GetValue(nameof(Value), valueSerializeType); - } - public override string ToString() => $"{Type} {Value}"; - - public void GetObjectData(SerializationInfo info, StreamingContext context) - { - info.AddValue(nameof(Name), Name); - info.AddValue(nameof(Type), Type.FullName); - info.AddValue(nameof(Source), (byte)Source); - info.AddValue(nameof(TableIndex), TableIndex); - info.AddValue(nameof(CanSerializeValue), CanSerializeValue); - info.AddValue(nameof(Value), CanSerializeValue ? Value : Value?.ToString()); - } } /// diff --git a/UIX/Microsoft/Iris/Debug/FallbackSerializer.cs b/UIX/Microsoft/Iris/Debug/FallbackSerializer.cs deleted file mode 100644 index da1a25c..0000000 --- a/UIX/Microsoft/Iris/Debug/FallbackSerializer.cs +++ /dev/null @@ -1,30 +0,0 @@ -using System; -using System.Runtime.Serialization; - -namespace Microsoft.Iris.Debug; - -internal class FallbackSerializer : ISerializationSurrogate -{ - public void GetObjectData(object obj, SerializationInfo info, StreamingContext context) - { - info.AddValue("ToString", obj?.ToString()); - } - - public object SetObjectData(object obj, SerializationInfo info, StreamingContext context, ISurrogateSelector selector) - { - return info.GetString("ToString"); - } -} - -internal class FallbackSurrogateSelector : SurrogateSelector -{ - public override ISerializationSurrogate GetSurrogate(Type type, StreamingContext context, out ISurrogateSelector selector) - { - selector = this; - - if (type.Attributes.HasFlag(System.Reflection.TypeAttributes.Serializable)) - return null; - - return new FallbackSerializer(); - } -} \ No newline at end of file diff --git a/UIX/Microsoft/Iris/Debug/ZmqDebuggerServer.cs b/UIX/Microsoft/Iris/Debug/ZmqDebuggerServer.cs index de44975..cfe2443 100644 --- a/UIX/Microsoft/Iris/Debug/ZmqDebuggerServer.cs +++ b/UIX/Microsoft/Iris/Debug/ZmqDebuggerServer.cs @@ -55,5 +55,5 @@ internal class ZmqDebuggerServer : IDebuggerServer, IDisposable _pubSocket.SendMultipartBytes(_messageFrame); } - internal static IFormatter CreateFormatter() => new BinaryFormatter(new FallbackSurrogateSelector(), new(StreamingContextStates.Remoting)); + internal static IFormatter CreateFormatter() => new BsonFormatter(new StreamingContext(StreamingContextStates.Remoting)); } diff --git a/UIX/UIX.csproj b/UIX/UIX.csproj index 1ae1524..fd36702 100644 --- a/UIX/UIX.csproj +++ b/UIX/UIX.csproj @@ -10,7 +10,9 @@ - + + +