michaeledgar / protobuf-net

Automatically exported from code.google.com/p/protobuf-net
0 stars 0 forks source link

Doing packed serialization for arrays of doubles #349

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
Hello,

I trying to use the low-level  ProtoWriter.Write methods to do packed enconding 
of a list of doubles. I'm getting an exception when trying to write because 
Fixed64 wire type is not supported for packed. Is there a better way to do this?

Thanks

Original issue reported on code.google.com by unclepau...@gmail.com on 15 Jan 2013 at 5:13

GoogleCodeExporter commented 9 years ago
Take a look at ListDecorator.Write; basically, there's a call to SetPackedField 
and a sub-item token. Or I can come up with a standalone example if you prefer?

Original comment by marc.gravell on 15 Jan 2013 at 7:56

GoogleCodeExporter commented 9 years ago
Marc,

Thanks for quick reply. I really admire your skills.

ListDecorator.Write is where i found the code. But it does not seem to work 
with writeDouble(). Maybe i'm doing something wrong. If not to hard, could you 
send me a working sample?

Thanks in Advance

Paul Kotlyar

Original comment by unclepau...@gmail.com on 15 Jan 2013 at 8:02

GoogleCodeExporter commented 9 years ago
Ok; it'll have to wait until tomorrow, though: I'm not at a PC right now

Original comment by marc.gravell on 15 Jan 2013 at 8:14

GoogleCodeExporter commented 9 years ago

    using ProtoBuf;
    using System;
    using System.IO;
    [ProtoContract]
    class Foo
    {
        [ProtoMember(1, IsPacked = true)]
        public double[] Data { get; set; }

        static void Main()
        {
            var arr = new double[] {123.45, 678.90};

            // first figure out what we're aiming for
            var obj = new Foo { Data = arr };
            using (var ms = new MemoryStream())
            {
                Serializer.Serialize(ms, obj);
                Console.WriteLine(BitConverter.ToString(ms.GetBuffer(),0,(int)ms.Length));
            }

            // now try to do it manually
            using (var ms = new MemoryStream())
            {
                using (var writer = new ProtoWriter(ms, null, null))
                {
                    ProtoWriter.WriteFieldHeader(1, WireType.String, writer);
                    var tok = ProtoWriter.StartSubItem(null, writer);
                    foreach (var val in arr)
                    {
                        ProtoWriter.SetPackedField(1, writer);

                        // the next two lines are what we would do anyway if it wasn't "packed"
                        ProtoWriter.WriteFieldHeader(1, WireType.Fixed64, writer);
                        ProtoWriter.WriteDouble(val, writer);
                    }
                    ProtoWriter.EndSubItem(tok, writer);                
                }
                Console.WriteLine(BitConverter.ToString(ms.GetBuffer(), 0, (int)ms.Length));
            }
        }

    }

Original comment by marc.gravell on 16 Jan 2013 at 9:38

GoogleCodeExporter commented 9 years ago
Works like a charm! Thanks Marc.I don't know if you hear this enough, but the 
community really appreciates your efforts.

Thanks

Paul

Original comment by unclepau...@gmail.com on 16 Jan 2013 at 1:57

GoogleCodeExporter commented 9 years ago
Just in case you're wondering about the slightly odd repetition: this allows an 
awful lot of downstream code to remain the same, with only the array/list code 
having to know about "packed", rather than the value-based code (which could be 
several levels of decorator away).

Original comment by marc.gravell on 16 Jan 2013 at 2:08

GoogleCodeExporter commented 9 years ago

Original comment by marc.gravell on 16 Jan 2013 at 2:08

GoogleCodeExporter commented 9 years ago
I have no complaints about the api. I care about serialization performance, and 
it is outstanding.

Thanks Again

Original comment by unclepau...@gmail.com on 16 Jan 2013 at 2:20