/// <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); }
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); } }
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); } }
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); } } } }