diff --git a/samples/HessianReader/HessianReader.csproj b/samples/HessianReader/HessianReader.csproj index 1178b9f..5f6fbcb 100644 --- a/samples/HessianReader/HessianReader.csproj +++ b/samples/HessianReader/HessianReader.csproj @@ -16,4 +16,13 @@ + + + PreserveNewest + + + PreserveNewest + + + diff --git a/samples/HessianReader/Program.cs b/samples/HessianReader/Program.cs index f7518e6..ebade53 100644 --- a/samples/HessianReader/Program.cs +++ b/samples/HessianReader/Program.cs @@ -24,29 +24,27 @@ namespace HessianReader Console.WriteLine("---------------------------------------------------------------"); - - var serializer = new DataContractHessianSerializer(typeof (RpcRequest)); using (var stream1 = new MemoryStream(myBinary)) { - var ds = new Hessian.Deserializer(stream1); - Hessian.ClassDef def = ds.ReadClassDefinition(); - Console.WriteLine(JsonConvert.SerializeObject(def)); - Console.WriteLine(ds.ReadValue()); - //Console.WriteLine(ds.ReadLong()); - //Console.WriteLine(ds.ReadString()); - //Console.WriteLine(ds.ReadString()); - //Console.WriteLine(ds.ReadString()); - //Console.WriteLine(ds.ReadString()); - //Console.WriteLine(ds.ReadValue()); - //Console.WriteLine(ds.ReadValue()); - Console.WriteLine(JsonConvert.SerializeObject(def)); + var s = new Hessian.Deserializer(stream1); + var a = s.ReadValue(); + Console.WriteLine(a); + a = s.ReadValue(); + Console.WriteLine(a); + Console.WriteLine(JsonConvert.SerializeObject(a)); + a = s.ReadValue(); + Console.WriteLine(a); + Console.WriteLine(JsonConvert.SerializeObject(a)); + a = s.ReadValue(); + Console.WriteLine(a); + Console.WriteLine(JsonConvert.SerializeObject(a)); } return; - + RpcRequest req = new RpcRequest { RequestId = "71565f61-94e8-4dcf-9760-f2fb73a6886a", CreateMillisTime = 1547621183585, diff --git a/src/Hessian.NET/HessianInputReader.cs b/src/Hessian.NET/HessianInputReader.cs index 0817baf..55ff1ac 100644 --- a/src/Hessian.NET/HessianInputReader.cs +++ b/src/Hessian.NET/HessianInputReader.cs @@ -355,9 +355,9 @@ namespace Hessian.Net return ReadInt32(); } - public byte? Peek() + public byte ReadByte() { - return this.Stream. + return (byte)Stream.ReadByte(); } protected void ReadLeadingByte() diff --git a/src/Hessian.NET/HessianSerializationScheme.cs b/src/Hessian.NET/HessianSerializationScheme.cs index 663e13d..f8caf1b 100644 --- a/src/Hessian.NET/HessianSerializationScheme.cs +++ b/src/Hessian.NET/HessianSerializationScheme.cs @@ -1,4 +1,5 @@ using System; +using System.Collections; using System.Collections.Generic; using System.Reflection; using System.Runtime.Serialization; @@ -54,12 +55,11 @@ namespace Hessian.Net if (IsListType(info)) { - return new ListElement(info); + return new ListElement(type, catalog, factory); } return BuildSerializationObject(type, catalog, factory); } - - + private static ISerializationElement BuildSerializationObject(Type type, IDictionary catalog, IObjectSerializerFactory factory) { ISerializationElement existing; @@ -123,7 +123,7 @@ namespace Hessian.Net public static bool IsListType(TypeInfo typeInfo) { - return typeInfo.IsArray && typeInfo.HasElementType; + return typeof(IEnumerable).IsAssignableFrom(typeInfo); } } } \ No newline at end of file diff --git a/src/Hessian.NET/ListElement.cs b/src/Hessian.NET/ListElement.cs index a627392..474d75f 100644 --- a/src/Hessian.NET/ListElement.cs +++ b/src/Hessian.NET/ListElement.cs @@ -2,16 +2,24 @@ using System; using System.Collections.Generic; using System.IO; + namespace Hessian.Net { public class ListElement: ISerializationElement { - public ListElement(Type listType) + private readonly IDictionary _catalog; + private readonly IObjectSerializerFactory _factory; + public ListElement(Type listType, IDictionary catalog, IObjectSerializerFactory factory) { - this.ObjectType = listType.GetElementType(); + this.ObjectType = listType; + this._catalog = catalog; + this._factory = factory; } - + private readonly Lazy listTypeResolver = new Lazy(); + public Type ObjectType { get; } + public ISerializationElement ChildSerializationElement { get; } + public void Serialize(HessianOutputWriter writer, object graph, HessianSerializationContext context) { throw new NotImplementedException(); @@ -19,106 +27,112 @@ namespace Hessian.Net public object Deserialize(HessianInputReader reader, HessianSerializationContext context) { + object ret=null; var preamble = reader.BeginList(); switch (preamble) { case ObjectPreamble.FixList: + ret =ReadFixList(reader, context); break; case ObjectPreamble.VarList: + ret = ReadVarList(reader, context); break; case ObjectPreamble.FixListUntyped: + ret = ReadFixListUntyped(reader, context); break; case ObjectPreamble.VarListUntyped: + ret = ReadVarListUntyped(reader, context); break; case ObjectPreamble.CompactFixList: + ret = ReadCompactFixList(reader, context); break; case ObjectPreamble.CompactFixListUntyped: + ret = ReadCompactFixListUntyped(reader, context); break; - } - + } reader.EndList(); + return ret; } - private string ReadTypeName(HessianInputReader reader) + private string ReadTypeName(HessianInputReader reader) { - reader.re - var tag = reader.Peek(); - - if (!tag.HasValue) { - throw new EndOfStreamException(); - } + + var tag = reader.ReadByte(); + + // A type name is either a string, or an integer reference to a // string already read and stored in the type-name ref map. if ((tag >= 0x00 && tag < 0x20) || (tag >= 0x30 && tag < 0x34) || tag == 0x52 || tag == 0x53) { - var typeName = ReadString(); - typeNameRefs.Add(typeName); + + var typeName = reader.ReadString(); return typeName; } - return typeNameRefs.Get(ReadInteger()); + throw new HessianSerializerException(); + } #region List - private IList ReadVarList() + private IList ReadVarList(HessianInputReader reader, HessianSerializationContext context) { reader.ReadByte(); - var type = ReadTypeName(); - return ReadListCore(type: type); + var type = ReadTypeName(reader); + return ReadListCore(reader, context, type: type); } - private IList ReadFixList() + private IList ReadFixList(HessianInputReader reader, HessianSerializationContext context) { reader.ReadByte(); - var type = ReadTypeName(); - var length = ReadInteger(); - return ReadListCore(length, type); + var type = ReadTypeName(reader); + var length = reader.ReadInt32(); + return ReadListCore(reader, context, length, type); } - private IList ReadVarListUntyped() + private IList ReadVarListUntyped(HessianInputReader reader, HessianSerializationContext context) { reader.ReadByte(); - return ReadListCore(); + return ReadListCore(reader, context); } - private IList ReadFixListUntyped() + private IList ReadFixListUntyped(HessianInputReader reader, HessianSerializationContext context) { reader.ReadByte(); - var length = ReadInteger(); - return ReadListCore(length); + var length = reader.ReadInt32(); + return ReadListCore(reader, context, length); } - private IList ReadCompactFixList() + private IList ReadCompactFixList(HessianInputReader reader, HessianSerializationContext context) { var tag = reader.ReadByte(); var length = tag - 0x70; - var type = ReadTypeName(); - return ReadListCore(length, type); + var type = ReadTypeName(reader); + return ReadListCore(reader, context, length, type); } - private IList ReadCompactFixListUntyped() + private IList ReadCompactFixListUntyped(HessianInputReader reader, HessianSerializationContext context) { var tag = reader.ReadByte(); var length = tag - 0x70; - return ReadListCore(length); + return ReadListCore(reader, context, length); } - private IList ReadListCore(int? length = null, string type = null) + private IList ReadListCore(HessianInputReader reader, HessianSerializationContext context, int? length = null, string type = null) { var list = GetListIntance(type, length); - objectRefs.Add(list); + //objectRefs.Add(list); if (length.HasValue) { - PopulateFixLengthList(list, length.Value); + PopulateFixLengthList(reader, context, list, length.Value); } else { - PopulateVarList(list); + PopulateVarList(reader, context, list); } return list; } @@ -140,25 +154,23 @@ namespace Hessian.Net return list; } - private void PopulateFixLengthList(IList list, int length) + private void PopulateFixLengthList(HessianInputReader reader, HessianSerializationContext context, IList list, int length) { for (var i = 0; i < length; ++i) { - list.Add(ReadValue()); + //ObjectElement objectElement = new ObjectElement() + list.Add(this.ChildSerializationElement.Deserialize(reader,context)); } } - private void PopulateVarList(IList list) + private void PopulateVarList(HessianInputReader reader, HessianSerializationContext context, IList list) { while (true) { - var tag = reader.Peek(); - if (!tag.HasValue) { - throw new EndOfStreamException(); - } + var tag = reader.ReadByte(); if (tag == 'Z') { reader.ReadByte(); break; } - list.Add(ReadValue()); + list.Add(this.ChildSerializationElement.Deserialize(reader, context)); } } diff --git a/src/Hessian.NET/ListTypeResolver.cs b/src/Hessian.NET/ListTypeResolver.cs new file mode 100644 index 0000000..5345603 --- /dev/null +++ b/src/Hessian.NET/ListTypeResolver.cs @@ -0,0 +1,66 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Text; + +namespace Hessian.Net +{ + public class ListTypeResolver + { + private readonly Dictionary>> constructors = new Dictionary>>(); + private readonly Dictionary>> length_constructors = new Dictionary>>(); + private readonly Func> empty_list_ctor = () => new List(); + private readonly Func> empty_list_ctor_with_length = length => new List(length); + + public ListTypeResolver() + { + constructors.Add("System.Collections.ArrayList", empty_list_ctor); + constructors.Add("System.Collections.List", empty_list_ctor); + constructors.Add("System.Collections.IList", empty_list_ctor); + constructors.Add("System.Collections.Generic.List`1", empty_list_ctor); + constructors.Add("System.Collections.Generic.IList`1", empty_list_ctor); + constructors.Add("System.Collections.ObjectModel.Collection`1", () => new Collection()); + constructors.Add("java.util.List", empty_list_ctor); + constructors.Add("java.util.Vector", empty_list_ctor); + constructors.Add("java.util.ArrayList", empty_list_ctor); + constructors.Add("java.util.LinkedList", empty_list_ctor); + + length_constructors.Add("System.Collections.List", empty_list_ctor_with_length); + length_constructors.Add("System.Collections.IList", empty_list_ctor_with_length); + length_constructors.Add("System.Collections.Generic.List`1", empty_list_ctor_with_length); + length_constructors.Add("System.Collections.Generic.IList`1", empty_list_ctor_with_length); + length_constructors.Add("java.util.List", empty_list_ctor_with_length); + length_constructors.Add("java.util.Vector", empty_list_ctor_with_length); + length_constructors.Add("java.util.ArrayList", empty_list_ctor_with_length); + length_constructors.Add("java.util.LinkedList", empty_list_ctor_with_length); + } + + public bool TryGetListInstance(string type, out IList list) + { + list = null; + + Func> ctor; + if (!constructors.TryGetValue(type, out ctor)) + { + return false; + } + + list = ctor(); + return true; + } + + public bool TryGetListInstance(string type, int length, out IList list) + { + list = null; + + Func> ctor; + if (!length_constructors.TryGetValue(type, out ctor)) + { + return false; + } + + list = ctor(length); + return true; + } + } +} diff --git a/src/Hessian.NET/ObjectElement.cs b/src/Hessian.NET/ObjectElement.cs index 0584805..bc7de2f 100644 --- a/src/Hessian.NET/ObjectElement.cs +++ b/src/Hessian.NET/ObjectElement.cs @@ -38,6 +38,10 @@ namespace Hessian.Net { get; } + public ObjectElement() + { + + } public ObjectElement(Type objectType, IList objectProperties) { @@ -95,6 +99,8 @@ namespace Hessian.Net var className = reader.ReadString(); var propertiesCount = reader.ReadInt32(); + + if (!String.Equals(ClassName, className)) { throw new HessianSerializerException(); diff --git a/src/Hessian.NET/TypeResolver.cs b/src/Hessian.NET/TypeResolver.cs new file mode 100644 index 0000000..6c3e459 --- /dev/null +++ b/src/Hessian.NET/TypeResolver.cs @@ -0,0 +1,10 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Hessian.NET +{ + class TypeResolver + { + } +} diff --git a/src/Hessian/PeekStream.cs b/src/Hessian/PeekStream.cs index f03f496..98b5594 100644 --- a/src/Hessian/PeekStream.cs +++ b/src/Hessian/PeekStream.cs @@ -84,7 +84,7 @@ namespace Hessian Conditions.CheckLess(offset, buffer.Length, "offset"); Conditions.CheckGreaterOrEqual(count, 0, "count"); Conditions.CheckArgument( - offset + count < buffer.Length, + offset + count <= buffer.Length, "Buffer is not big enough to contain the requested amount of data at the given offset."); if (count == 0) {