示例#1
0
        /// <summary>
        /// 把一个对象序列化到指定流中
        /// </summary>
        /// <param name="stream"></param>
        /// <param name="obj"></param>
        public void Serialize(Stream stream, object obj)
        {
            if (obj == null) throw new ArgumentNullException("obj");

            WriteContext context = new WriteContext();
            context.Formatter = this;
            context.Writer = new BinaryWriterX(stream);
            context.Data = obj;
            context.Type = obj.GetType();

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

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

            //RefObjects = null;

            // 使用默认设置写入头部
            if (!Head.Config.NoHead)
            {
                Head.AssemblyName = context.Type.Assembly.FullName;
                Head.TypeName = context.Type.FullName;
                //WriteMember(writer, Head, config, node.Add("Head", Head.GetType()));
                WriteMember(context.Clone(Head, Head.GetType(), null, "Head") as WriteContext);

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

            // 写入主体
            //WriteMember(writer, obj, config, node.Add("Body", obj.GetType()));
            WriteMember(context.Clone(obj, context.Type, null, "Body") as WriteContext);
        }
示例#2
0
        void WriteArray(WriteContext context)
        {
            // 先写元素个数
            Array arr = context.Data as Array;
            // 特性指定了长度,这里就不需要再写入长度了
            if (context.Config.Size <= 0) context.Writer.WriteEncoded(arr.Length);

            // 特殊处理字节数组
            if (context.Type == typeof(Byte[]))
            {
                context.Writer.Write((Byte[])context.Data);
                return;
            }

            Int32 n = 0;
            foreach (Object item in arr)
            {
                Type type = null;
                if (item != null) type = item.GetType();
                WriteMember(context.Clone(item, type, type, n++.ToString()) as WriteContext);
            }
        }
示例#3
0
        void WriteEnumerable(WriteContext context)
        {
            // 先写元素个数
            IEnumerable arr = context.Data as IEnumerable;
            Int32 count = 0;
            foreach (Object item in arr)
            {
                count++;
            }
            // 特性指定了长度,这里就不需要再写入长度了
            if (context.Config.Size <= 0) context.Writer.WriteEncoded(count);

            Int32 n = 0;
            foreach (Object item in arr)
            {
                Type type = null;
                if (item != null) type = item.GetType();
                WriteMember(context.Clone(item, type, type, n++.ToString()) as WriteContext);
            }
        }
示例#4
0
        void WriteObjectRef(WriteContext context)
        {
            //// 检测循环引用
            //if (RefObjects == null) RefObjects = new Dictionary<Object, Int32>();

            //if (RefObjects.ContainsKey(context.Data))
            //    throw new InvalidOperationException("检测到循环引用!" + context.Node);

            //RefObjects.Add(context.Data, RefObjects.Count + 1);

            // 写入一个字节表示当前对象不为空
            // 实际上,还可以建立一个只能容纳255个类型的数组,这个字节用于表示类型
            if (!context.Config.UseRefObject && context.Node.Depth > 1 && !context.Config.NotNull) context.Writer.Write((Byte)1);

            Type type = context.Type;
            // 对于对象引用型的字段,需要合并上类上的设置
            context.Config = context.Config.CloneAndMerge(type);

            // 反射得到所有需要序列化的字段或属性
            MemberInfo[] mis = FindAllSerialized(type, context.Config.SerialProperty);
            if (mis != null && mis.Length > 0)
            {
                // 先获取类特性,后获取成员特性,所以,成员特性优先于类特性
                foreach (MemberInfo item in mis)
                {
                    if (item is FieldInfo)
                    {
                        FieldInfo fi = item as FieldInfo;
                        Object obj = FieldInfoX.Create(fi).GetValue(context.Data);
                        type = obj == null ? fi.FieldType : obj.GetType();
                        WriteMember(context.Clone(obj, type, item) as WriteContext);
                    }
                    else
                    {
                        PropertyInfo pi = item as PropertyInfo;
                        Object obj = PropertyInfoX.Create(pi).GetValue(context.Data);
                        type = obj == null ? pi.PropertyType : obj.GetType();
                        WriteMember(context.Clone(obj, type, item) as WriteContext);
                    }
                }
            }
        }