コード例 #1
0
ファイル: ProtoUtils.cs プロジェクト: xgray/dotnet
        /// <summary>
        /// Tries deserialize a tuple from stream
        /// </summary>
        /// <typeparam name="T">tuple type</typeparam>
        /// <param name="tuple">tuple object</param>
        /// <param name="stream">the stream to read the tuple</param>
        /// <returns>true when success</returns>
        public static void Deserialize <T>(this Stream stream, T proto, ProtoSchema schema)
        {
            try
            {
                using (BinaryReader reader = new BinaryReader(stream, Encoding.UTF8, true))
                {
                    int    bitLen   = reader.ReadByte();
                    byte[] bitmasks = reader.ReadBytes(bitLen);

                    foreach (IProtoColumn column in schema.Columns)
                    {
                        if (bitmasks.GetBitmask(column.ID))
                        {
                            object value = column.Read(reader);
                            proto.SetValue(column, value);
                        }
                        else
                        {
                            proto.SetValue(column, column.DefaultValue);
                        }
                    }
                }
            }
            catch (EndOfStreamException)
            {
                throw new ProtoException(ProtoErrorCode.DataCorrupted);
            }
        }
コード例 #2
0
ファイル: ProtoUtils.cs プロジェクト: xgray/dotnet
        /// <summary>
        /// Serialize a tuple into stream.
        ///
        /// The following data are writen into the stream
        /// 1. bitmask bytes length
        /// 2. bitmarks bytes
        /// 3. serialized value for each column in columns masks.
        ///
        /// </summary>
        /// <typeparam name="T">tuple type</typeparam>
        /// <param name="tuple">tuple object</param>
        /// <param name="stream">the stread to write the tuple into</param>
        /// <param name="columnMasks">column masks for serialized columns</param>
        public static void Serialize <T>(this Stream stream, T proto, ProtoSchema schema)
        {
            using (BinaryWriter writer = new BinaryWriter(stream, Encoding.UTF8, true))
            {
                int    bitPos   = (int)stream.Position;
                byte[] bitmarks = new byte[schema.ColumnMasks.Length];
                writer.Write((byte)bitmarks.Length);
                writer.Write(bitmarks, 0, bitmarks.Length);

                for (int index = 0; index < schema.Columns.Length; index++)
                {
                    IProtoColumn column = schema.Columns[index];
                    if (column.ID >= schema.ColumnMasks.Length * 8)
                    {
                        break;
                    }

                    if (!schema.ColumnMasks.GetBitmask(column.ID))
                    {
                        bitmarks.SetBitmask(column.ID, false);
                        continue;
                    }

                    object value = proto.GetValue(column);
                    if (CommonUtils.Equals(value, column.DefaultValue))
                    {
                        bitmarks.SetBitmask(column.ID, false);
                    }
                    else
                    {
                        bitmarks.SetBitmask(column.ID, true);
                        column.Write(writer, value);
                    }
                }

                int endPos = (int)stream.Position;
                stream.Position = bitPos;

                writer.Write((byte)bitmarks.Length);
                writer.Write(bitmarks, 0, bitmarks.Length);

                stream.Position = endPos;
            }
        }