/// <summary>
 /// 构造
 /// </summary>
 /// <param name="context"></param>
 public ProtocolDeserializingEventArgs(ReadContext context)
 {
     Context = context;
 }
        /// <summary>
        /// 反序列化后触发
        /// </summary>
        /// <param name="context"></param>
        protected virtual void OnDeserialized(ReadContext context)
        {
            // 事件由外部动态指定,拥有优先处理权
            if (Deserialized != null) Deserialized(this, new ProtocolDeserializedEventArgs(context));

            IProtocolSerializable custom = context.GetCustomInterface();
            if (custom != null) custom.OnDeserialized(context);
        }
        /// <summary>
        /// 为指定类型创建实例时触发
        /// </summary>
        /// <remarks>当内部自定义后外部事件同时存在时,优先外部事件</remarks>
        /// <param name="context"></param>
        /// <param name="type"></param>
        /// <returns></returns>
        protected virtual Object OnCreateInstance(ReadContext context, Type type)
        {
            Object obj = null;

            if (CreateInstance != null)
            {
                ProtocolCreateInstanceEventArgs e = new ProtocolCreateInstanceEventArgs();
                e.Context = context;
                e.Type = type;
                CreateInstance(this, e);
                obj = e.Obj;
            }

            if (obj == null)
            {
                IProtocolSerializable custom = context.GetCustomInterface();
                if (custom != null) obj = custom.OnCreateInstance(context, type);
            }

            return obj;
        }
        /// <summary>
        /// 从指定流读取数据填充到指定对象
        /// </summary>
        /// <param name="stream"></param>
        /// <param name="obj"></param>
        /// <returns></returns>
        public Object Deserialize(Stream stream, Object obj)
        {
            ReadContext context = new ReadContext();
            context.Formatter = this;
            context.Reader = new BinaryReaderX(stream);

            // 树,用于记录分析所到达的位置
            context.Node = new ProtocolTreeNode(null, null);
            context.Node.Context = context;

            Type type = null;
            if (obj != null) type = obj.GetType();

            //context.Config = FormatterConfig.Default;
            context.Config = Head.Config;

            // 使用默认设置读取头部
            if (!Head.Config.NoHead)
            {
                ReadMember(context.Clone(Head, Head.GetType(), null, "Head") as ReadContext);
                OnDeserialized(context);

                //// 只有使用了头部,才使用头部设置信息,否则使用默认设置信息,因为远端需要正确识别数据
                //context.Config = Head.Config;
            }

            if (type == null)
            {
                // 读取类名
                Assembly asm = Assembly.Load(Head.AssemblyName);
                if (asm == null) throw new Exception("无法找到程序集" + Head.AssemblyName + "!");

                type = asm.GetType(Head.TypeName);
                if (type == null) throw new Exception("无法找到类" + Head.TypeName + "!");
            }

            context.Type = type;
            context.Node.Type = type;

            if (obj == null) obj = Activator.CreateInstance(type);
            context.Data = obj;

            ReadMember(context.Clone(obj, type, null, "Body") as ReadContext);
            OnDeserialized(context);

            return obj;
        }
        /// <summary>
        /// 反序列化前触发
        /// </summary>
        /// <param name="context"></param>
        /// <returns>是否允许反序列化当前字段或属性</returns>
        protected virtual Boolean OnDeserializing(ReadContext context)
        {
            Boolean b = true;

            // 事件由外部动态指定,拥有优先处理权
            if (Deserializing != null)
            {
                ProtocolDeserializingEventArgs e = new ProtocolDeserializingEventArgs(context);
                e.Cancel = false;
                Deserializing(this, e);
                b = !e.Cancel;
            }

            IProtocolSerializable custom = context.GetCustomInterface();
            if (custom != null) b = custom.OnDeserializing(context);

            return b;
        }
        Array ReadArray(ReadContext context, Type elementType, Int32 n)
        {
            Array arr = Array.CreateInstance(elementType, n);

            for (int i = 0; i < n; i++)
            {
                Object obj = ReadMember(context.Clone(null, elementType, elementType, i.ToString()) as ReadContext);
                arr.SetValue(obj, i);

                OnDeserialized(context);
            }

            return arr;
        }
        Object ReadEnumerable(ReadContext context)
        {
            Int32 n = context.Config.Size;
            if (n <= 0) n = context.Reader.ReadEncodedInt32();

            if (n <= 0) return null;

            Type elementType = context.Type;
            if (context.Type.HasElementType)
                elementType = context.Type.GetElementType();
            else if (context.Type.IsGenericType)
            {
                Type[] ts = context.Type.GetGenericArguments();
                if (ts != null && ts.Length > 0) elementType = ts[0];
            }
            Array arr = ReadArray(context, elementType, n);
            if (arr == null) return null;

            context.Data = Activator.CreateInstance(context.Type, arr);

            return context.Data;
        }
        Object ReadObjectRef(ReadContext context)
        {
            if (!context.Config.UseRefObject)
            {
                // 不使用引用对象的时候,这里就需要判断了
                if (context.Node.Depth > 1 && !context.Config.NotNull)
                {
                    // 读取一个字节,探测是否为空
                    Byte b = context.Reader.ReadByte();
                    if (b == 0)
                    {
                        //context.Data = null;
                        return null;
                    }
                }
            }

            // 创建
            if (context.Data == null)
            {
                context.Data = OnCreateInstance(context, context.Type);
                if (context.Data == null) context.Data = Activator.CreateInstance(context.Type);
            }

            // 添加对象到对象集合
            if (context.Config.UseRefObject) context.Objects.Add(context.Data);

            // 先获取类特性,后获取成员特性,所以,成员特性优先于类特性
            context.Config = context.Config.CloneAndMerge(context.Type);

            MemberInfo[] mis = FindAllSerialized(context.Type, context.Config.SerialProperty);
            if (mis != null && mis.Length > 0)
            {
                foreach (MemberInfo item in mis)
                {
                    Object obj = null;
                    if (item is FieldInfo)
                    {
                        FieldInfo fi = item as FieldInfo;
                        FieldInfoX fix = fi;
                        // 只有Object类型才计算值
                        if (Type.GetTypeCode(fi.FieldType) == TypeCode.Object) obj = fix.GetValue(context.Data);
                        obj = ReadMember(context.Clone(obj, fi.FieldType, item) as ReadContext);
                        fix.SetValue(context.Data, obj);

                        OnDeserialized(context);
                    }
                    else
                    {
                        PropertyInfo pi = item as PropertyInfo;
                        PropertyInfoX pix = pi;
                        // 只有Object类型才计算值
                        if (Type.GetTypeCode(pi.PropertyType) == TypeCode.Object) obj = pix.GetValue(context.Data);
                        obj = ReadMember(context.Clone(obj, pi.PropertyType, item) as ReadContext);
                        if (pi.GetSetMethod() != null) pix.SetValue(context.Data, obj);

                        OnDeserialized(context);
                    }
                }
            }
            return context.Data;
        }
        Object ReadArray(ReadContext context)
        {
            Int32 n = context.Config.Size;
            if (n <= 0) n = context.Reader.ReadEncodedInt32();
            if (n <= 0) return null;

            // 特殊处理字节数组
            if (context.Type == typeof(Byte[])) return context.Reader.ReadBytes(n);

            Type elementType = context.Type.GetElementType();

            return ReadArray(context, elementType, n);
        }
        private Object ReadMemberInternal(ReadContext context)
        {
            BinaryReaderX reader = context.Reader;
            Boolean encodeInt = context.Config.EncodeInt;

            // 基础类型
            Object data = null;
            if (reader.TryReadValue(context.Type, encodeInt, out data))
            {
                context.Data = data;
                return data;
            }

            #region 数组、枚举、值类型、对象
            if (context.Config.UseRefObject)
            {
                // 对于非基本类型,先写入对象引用计数
                if (context.Node.Depth > 1 && !context.Config.NotNull)
                {
                    Int32 n = reader.ReadEncodedInt32();
                    // 计数0表示是空对象
                    if (n == 0)
                    {
                        context.Data = null;
                        return null;
                    }

                    // 从对象集合中找到对象,无效反序列化
                    if (n <= context.Objects.Count)
                    {
                        context.Data = context.Objects[n - 1];
                        return context.Data;
                    }
                    //else if (n == context.Objects.Count + 1)
                    //{
                    //    // 该对象的第一个引用
                    //}
                    //else
                    //    throw new InvalidOperationException("数据异常,从对象集合中找到对象!");
                }
            }

            if (context.Type.IsArray)
            {
                return ReadArray(context);
            }
            else if (context.Data is IEnumerable || typeof(IEnumerable).IsAssignableFrom(context.Type))
            {
                return ReadEnumerable(context);
            }
            else if (context.Type.IsValueType)
            {
                //if (context.Type == typeof(Guid)) return new Guid(reader.ReadBytes(16));

                return ReadObjectRef(context);
            }
            else
            {
                if (context.Type == typeof(IPAddress))
                {
                    Int32 p = 0;
                    if (!encodeInt)
                        p = reader.ReadInt32();
                    else
                        p = reader.ReadEncodedInt32();
                    //if (p <= -1) p = (Int64)(UInt32)p;
                    //context.Data = new IPAddress(p);
                    Byte[] buffer = reader.ReadBytes(p);
                    context.Data = new IPAddress(buffer);
                    return context.Data;
                }

                return ReadObjectRef(context);
            }

            #endregion
        }
        /// <summary>
        /// 读取对象
        /// </summary>
        /// <remarks>
        /// 非对象类型直接返回数据;
        /// 对象类型且参数context.Data不为空时,填充context.Data;
        /// 对象类型且参数context.Data为空时,创建对象,填充后返回
        /// </remarks>
        /// <remarks>
        /// 分为几种情况:
        /// 1,空引用直接写入0
        /// 2,基本值类型直接写入值
        /// 3,非基本值类型先查找是否已有引用,已有则写入引用计数(从1开始,因为0表示空引用),没有则添加到引用集合,再写入引用计数
        /// 4,数组和枚举类型先写入元素个数,再依次写入元素
        /// 5,对象类型,反射得到属性和字段,一个个写入
        /// 值得注意的是,数据和枚举本也使用引用计数防止重复引用,同时包含引用计数和元素个数
        /// </remarks>
        /// <param name="context"></param>
        /// <returns></returns>
        public Object ReadMember(ReadContext context)
        {
            //WriteLog(context.Node.ToString());

            if (!OnDeserializing(context)) return context.Data;

            Stream stream = context.Reader.BaseStream;
            Int64 pos = stream.Position;

            Object data = ReadMemberInternal(context);

            Int64 pos2 = stream.Position;
            if (pos2 > pos)
            {
                stream.Seek(pos, SeekOrigin.Begin);
                Byte[] buffer = new Byte[pos2 - pos];
                stream.Read(buffer, 0, buffer.Length);

                WriteLog("{0} [{1}] {2}", context.Node.ToString(), buffer.Length, BitConverter.ToString(buffer).Replace("-", " "));
            }

            return data;
        }
Exemple #12
0
            object IProtocolSerializable.OnCreateInstance(ReadContext context, Type type)
            {
                if (type == typeof(IPEndPoint)) return new IPEndPoint(IPAddress.Any, 0);

                return null;
            }
Exemple #13
0
 void IProtocolSerializable.OnDeserialized(ReadContext context)
 {
 }
Exemple #14
0
 bool IProtocolSerializable.OnDeserializing(ReadContext context)
 {
     return true;
 }