简体   繁体   中英

Fast way to get the length of serialized data using ProtoBuf-net?

Let's say I have a Person class. It has an editable Notes property.
I want to serialize the Person instance to a fixed size buffer, thus the Notes cannot be infinite long.
In the UI, I use a TextBox to let user edit the notes. I want to dynamically update a label saying how many more characters you can write.

This is my current implementation, is there any faster method? (I'm using rs282)

    public Int32 GetSerializedLength()
    {
        Byte[] data;
        using (MemoryStream ms = new MemoryStream())
        {
            Serializer.SerializeWithLengthPrefix<Person>(ms, this, PrefixStyle.Base128);
            data = ms.ToArray();
        }
        using (MemoryStream ms = new MemoryStream(data))
        { 
            Int32 length = 0;
            if (Serializer.TryReadLengthPrefix(ms, PrefixStyle.Base128, out length))
                return length;
            else
                return -1;
        }
    }

EDIT: I'm confused about the internal lengh of the serialized data and the total length of the serialized data.
Here is my final version:

    private static MemoryStream _ms = new MemoryStream();
    public static Int64 GetSerializedLength(Person person)
    {
        if(null == person) return 0;
        _ms.SetLength(0);
        Serializer.Serialize<Person>(_ms, person);
        return _ms.Length;
    }

With the edit, it sounds like you want the length without serializing it (since if you want the length with serializing it, you'd just serialize it and check the .Length ).

Basically, no - this isn't available. I know that some of the other implementations build this data eagerly, that is in part because they are constructing the buffered data all the time, where-as protobuf-net works from an object graph.

protobuf-net does not do this - it builds the data by discovery during a single pass over the object graph. Is there a specific purpose you have in mind? Things can always be added (with effort, though).


Re the issue of a notes (string) field that you don't want to be over-sized; as a sanity check, note that protubuf uses UTF8 or string data, so personally I would just do:

if(theText.Length > MAX || Encoding.UTF8.GetByteCount(theText) > MAX
       || GetSerializedLength(obj) > MAX)
{
        //
}

note we've checked this a bit more cheaply in the obvious cases

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM