Code Monkey home page Code Monkey logo

binaryformatter's Introduction

Łukasz Pyrzyk

Software Engineer, Dotnetos, Microsoft MVP

twitter linkedin blog

I’m a Software Engineer specialized in backend services and .NET technology. I love to do and speak about performance and optimizations. Moreover, I’m a speaker (more than a blogger) and an active Twitter user.

Anurag's github stats Top Langs

binaryformatter's People

Contributors

lukasz-pyrzyk avatar ypermitin avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

binaryformatter's Issues

Restructure the solution

Move main project and the tests into the root of the solution. This will speed up the development

Add support for NULL values

This test doesn't pass, because NULL values aren't serializing.

List<string> value = new List<string>();
value.Add("lorem ipsum");
value.Add(null);
value.Add("Кто не ходит, тот и не падает.");

BinaryConverter converter = new BinaryConverter();
byte[] bytes = converter.Serialize(value);
List<string> deserializedValue = converter.Deserialize<List<string>>(bytes);

Assert.Equal(value, deserializedValue);

Can't deserialize complex objects

Really like the project, but I can't Deserialize the following objects:

  public class SerializableColumn
  {
    public string Name { get; set; }
    public string Value { get; set;}
  }

  public class SerializableRow
  {
    public IEnumerable<SerializableColumn> Data { get; set;}
  }

  public class CompositeSerializableRow
  {
    public SerializableRow MasterRow { get; set; }
    public IEnumerable<SerializableRow> DetailRows { get; set; }
  }

Here is the test code:

      var serializableRow = new CompositeSerializableRow();
      serializableRow.MasterRow = new SerializableRow();
      serializableRow.MasterRow.Data = new[] { new SerializableColumn { Name = "Key", Value = "12345" }, new SerializableColumn { Name = "TestMasterName0", Value = "TestMasterValue0" } };
      serializableRow.DetailRows = new[] { new SerializableRow { Data = new[] { new SerializableColumn { Name = "TestDetailName0", Value = "TestDetailValue0" }, new SerializableColumn { Name = "TestDetailName1", Value = "TestDetailValue1" } } } };

      var rowBytes = serializer.Serialize(serializableRow);
      var row = serializer.Deserialize<CompositeSerializableRow>(rowBytes);

I downloaded the source and stepped through IEnumerableConverter.ProcessDeserialize and it appears the offset is off by 2 on line 65:

int sizeTypeInfo = BitConverter.ToInt32(stream, offset);

I will do a more thorough debug session later, but thought you might have a quicker insight into the issue.

Thanks.

Release 1.2.0

Let's create last release 1.2.0 before 2.0 will be ready.

Exclude virtual property of object from serialization

It is reason of "OutOfMemory" exception.

Sample:

public class Element
{
    public string Name { get; set; }
    public string GroupID { get; set; }
    public virtual List<Group> Groups { get; }
}

public class Group
{
    public string Name { get; set; }
    public virtual List<Element> Elements { get; }
}

If we will try to serialize object "Element", then we get a recursion.

Improve current protocol of save serialized value

Current:
image
New:
image
Yellow color is means, that this block is optional. Info about type is necessary only for valued types. For primitive values an internal type will enough.

Note: also needed to fix current way to save info about type in IEnumerable serialization in to new way.
Current:
image

In the block of type info we need to save type name and special ID as you told before.

Shared unit test for all converters

Maintenance of the tests for specific converters (like IntConverter) is quite challenging.
What do you think about creating base class for such unit tests? Something like this.

    public class BoolConverterTests : BaseTest<bool>
    {
        public override bool Value => true;

        [Fact]
        public void RunTest()
        {
            CanSerializeAndDeserialize();
        }
    }

    public abstract class BaseTest<T>
    {
        public abstract T Value { get; }

        protected void CanSerializeAndDeserialize()
        {
            var converter = new BinaryConverter();
            byte[] bytes = converter.Serialize(Value);

            T after = converter.Deserialize<T>(bytes);
            Assert.Equal(Value, after);
        }
    }

It would be even better to do it in following way

    public class BoolConverterTests : BaseTest<bool>
    {
        public override bool Value => true;
    }

    public abstract class BaseTest<T>
    {
        public abstract T Value { get; }

        [Fact]
        public void CanSerializeAndDeserialize()
        {
            var converter = new BinaryConverter();
            byte[] bytes = converter.Serialize(Value);

            T after = converter.Deserialize<T>(bytes);
            Assert.Equal(Value, after);
        }
    }

However, XUnit can't find tests with Fact in the parent class ;/

CC @YPermitin

Error by deserialize

The following code causes exception.

    enum Enum
    {
        Item1,
        Item2,
        Item3
    }

    class ClassA
    {
        public Enum Enum { get; set; }
        public bool Bool { get; set; }
    }

    class Program
    {
        static void Main(string[] args)
        {
            var classA = new ClassA
            {
                Bool = true,
                Enum = Enum.Item2
            };

            var binarySerialize = new BinaryConverter();

            var data = binarySerialize.Serialize(classA);
            var classADeserialize = binarySerialize.Deserialize<ClassA>(data);  **ArgumentException**

            Console.ReadKey();
        }
    }

System.ArgumentException: 'Object of type 'System.Int32' cannot be converted to type 'System.Boolean'.'

If the Bool property is defined to the top, there will be no exception, but Enum is not set in Item2

 class ClassA
  {
      public bool Bool { get; set; }
      public Enum Enum { get; set; }
  }

If you add one more property to the end (example string property) there will be an exception.

    class ClassA
    {
        public bool Bool { get; set; }
        public Enum Enum { get; set; }
        public string String { get; set; }
    }

System.ArgumentException: 'Object of type 'System.Int32' cannot be converted to type 'System.String'.'

Deserializing object with byte data is failing

I have an object that I am attempting to Deserialize. If this object contains a byte field then an error is thrown. I am running this in a xamarin mobile project. I am using version 2.1.0 of BinaryFormatter. Here are the details:

The object:
[Serializable]
public class StreamMessage : Message
{
public string StreamName;
public int StreamType;
public float StreamSize;
public byte StreamContent;

    public StreamMessage()
    {
        MessageType = Constants.MESSAGE_TYPE_STREAM;
    }
}

The deserialization code I am using :
public static Object ByteArrayToObject(byte[] arrBytes)
{
var obj = new Object();

        try
        {
            var binForm = new BinaryConverter();
            obj         = binForm.Deserialize<Object>(arrBytes);
        }
        catch (Exception err) {
            //This is the exception thrown
        }

        return obj;
    }

And finally the stack trace:
{System.InvalidOperationException: Sequence contains no matching element
at System.Linq.Enumerable.First[TSource] (System.Collections.Generic.IEnumerable1[T] source, System.Func2[T,TResult] predicate) [0x00011] in <65f4a23934a3468fae9abe3139b55169>:0
at BinaryFormatter.ConvertersSelector.ForSerializedType (BinaryFormatter.Types.SerializedType type) [0x0001b] in <08134ddd0b7642c49f61d03cbafc56eb>:0
at BinaryFormatter.TypeConverter.CustomObjectConverter.DeserializeProperty[T] (System.Reflection.PropertyInfo property, T& instance, System.Byte[] stream, System.Int32& offset) [0x000e9] in <08134ddd0b7642c49f61d03cbafc56eb>:0
at BinaryFormatter.TypeConverter.CustomObjectConverter.ProcessDeserialize (System.Byte[] bytes, System.Type sourceType, System.Int32& offset) [0x00029] in <08134ddd0b7642c49f61d03cbafc56eb>:0
at BinaryFormatter.TypeConverter.BaseTypeConverter1[T].Deserialize (System.Byte[] bytes) [0x00029] in <08134ddd0b7642c49f61d03cbafc56eb>:0 at BinaryFormatter.TypeConverter.BaseTypeConverter1[T].DeserializeToObject (System.Byte[] stream) [0x00000] in <08134ddd0b7642c49f61d03cbafc56eb>:0
at BinaryFormatter.BinaryConverter.Deserialize[T] (System.Byte[] stream) [0x000ce] in <08134ddd0b7642c49f61d03cbafc56eb>:0
at Mobile.Core.Utility.Utilities.ByteArrayToObject (System.Byte[] arrBytes) [0x0000e] in /Users/currentuser/projects/mobile/Mobile.Core/Utility/Utilities.cs:33 }

Thanks,
Allan

Release 2.0.0

I'm thinking about earlier release of the 2.0, because remaining stories are about adding more types, where the biggest change in protocol is already done. Am I wrong @YPermitin ?

Use bash scripts on the appveyor

Currently configuration appveyor looks as follow:

build_script:
- cmd: >-
    dotnet restore

    dotnet build
test_script:
- cmd: dotnet test .\tests\BinaryFormatterTests\BinaryFormatterTests.csproj

It would be better to reuse bash scripts from ./scripts folder.

Serialization and deserialization can only use the same class

        private class LogBook
        {
            public long Id { get; set; }

            public string Name { get; set; }
        }

        private class LogEntry
        {
            public long Id { get; set; }

            public string Name { get; set; }
        }

The following code does not work, do you have any good suggestions?

         var log = new LogBook { Id = 1, Name = "abc" };
        var bytes = binaryConverter.Serialize(log);
       
        //error occurred
        var log2 = binaryConverter.Deserialize<LogEntry>(bytes);

Improve decimal converter

Current one converts value to string and uses StringConverter. This can be done better...

For example, use

int[] slices = decimal.GetBits(obj);

and add all slices to the stream

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.