Exemplo n.º 1
0
        /// <summary>
        /// Writes a protocol-buffer representation of the given instance to the supplied stream,
        /// with a length-prefix. This is useful for socket programming,
        /// as DeserializeWithLengthPrefix/MergeWithLengthPrefix can be used to read the single object back
        /// from an ongoing stream.
        /// </summary>
        /// <typeparam name="T">The type being serialized.</typeparam>
        /// <param name="instance">The existing instance to be serialized (cannot be null).</param>
        /// <param name="style">How to encode the length prefix.</param>
        /// <param name="destination">The destination stream to write to.</param>
        /// <param name="tag">The tag used as a prefix to each record (only used with base-128 style prefixes).</param>
        public static void SerializeWithLengthPrefix <T>(Stream destination, T instance, PrefixStyle style, int tag)
        {
            if (style == PrefixStyle.None)
            {
                Serialize <T>(destination, instance);
                return;
            }
            using (MemoryStream ms = new MemoryStream())
            {
                Serialize <T>(ms, instance);
                byte[] tmp = new byte[20];
                int    len;
                switch (style)
                {
                case PrefixStyle.Base128:
                    len = 0;
                    if (tag > 0)
                    {
                        uint prefix = GetFieldToken(tag, WireType.String);
                        len += SerializationContext.EncodeUInt32(prefix, tmp, 0);
                    }
                    len += SerializationContext.EncodeUInt32((uint)ms.Length, tmp, len);
                    break;

                case PrefixStyle.Fixed32:
                    SerializationContext.EncodeUInt32Fixed((uint)ms.Length, tmp, 0);
                    len = 4;
                    break;

                default:
                    throw new NotSupportedException("Invalid prefix style: " + style);
                }
                destination.Write(tmp, 0, len);
                destination.Write(ms.GetBuffer(), 0, (int)ms.Length);
            }
            destination.Flush();
        }