/// <summary> /// 序列化一个对象到Byte数组,无法序列化,将抛出ArgumentException异常 /// </summary> /// <param name="obj">对象</param> /// <param name="writeToBytes">将要在这个数组基础上开始写入,指定Null表示新建一个数组</param> /// <param name="startIndex">将要从数组的哪个位置开始写入</param> /// <param name="maxWriteSize">最大允许的写入长度</param> /// <param name="fullLengthSchema">是否完整包含每个子对象的长度</param> /// <returns>返回有效大小</returns> public static int SerializeTo(object obj, ref byte[] writeToBytes, int startIndex, int maxWriteSize, bool fullLengthSchema = true) { //try { bool isFieldNullable = false; //数据块 ZipBytesWriter bwData; if (writeToBytes != null) { bwData = new ZipBytesWriter(writeToBytes, startIndex, maxWriteSize); } else { bwData = new ZipBytesWriter(maxWriteSize); } //写标识头 bwData.Write((fullLengthSchema) ? Byte_One : Byte_Zero); if (obj == null) { if (fullLengthSchema) { bwData.Write((ushort)1); } bwData.Write(Byte_Zero); writeToBytes = bwData.Bytes; return(bwData.EffectiveBytesLength); } int metablockStart = 0; int metablockLen = 0; Stack <SerializeInfo> bufStack = new Stack <SerializeInfo>(); bufStack.Push(new SerializeInfo(obj, isFieldNullable, bwData.EffectiveBytesLength)); if (fullLengthSchema) { bwData.Write(DefaultFieldLen); } while (bufStack.Count > 0) { SerializeInfo nowSerializeInfo = bufStack.Peek(); if (nowSerializeInfo.TheObject == null) { bwData.WriteNullHead(true); //写入null bufStack.Pop(); if (fullLengthSchema) { metablockStart = nowSerializeInfo.ByteStartIndexOrEndPoint; metablockLen = bwData.EffectiveBytesLength - metablockStart - 2; ZipBytesWriter.WriteAtUshort(bwData.Bytes, metablockStart, (ushort)metablockLen); } } else { if (nowSerializeInfo.TheType == null) //未检查过 { if (nowSerializeInfo.IsNullable) { bwData.WriteNullHead(false); } nowSerializeInfo.TheType = nowSerializeInfo.TheObject.GetType(); //是基础元素 if (BytesHelper.TryWriteBytes(nowSerializeInfo.TheObject, nowSerializeInfo.TheType, bwData)) { bufStack.Pop(); if (fullLengthSchema) { metablockStart = nowSerializeInfo.ByteStartIndexOrEndPoint; metablockLen = bwData.EffectiveBytesLength - metablockStart - 2; if (metablockLen > ushort.MaxValue) { throw new Exception("序列化的子字段大小超出65535:" + nowSerializeInfo.FieldInfos[nowSerializeInfo.Index - 1].FieldName); } ZipBytesWriter.WriteAtUshort(bwData.Bytes, metablockStart, (ushort)metablockLen); } } else //不是基础元素 { if (nowSerializeInfo.TheType.IsArray) { nowSerializeInfo.IsArray = true; nowSerializeInfo.Length_FieldInfo = (nowSerializeInfo.TheObject as Array).Length; //写入数组长度 bwData.WriteArrayHead(nowSerializeInfo.Length_FieldInfo); } else if (nowSerializeInfo.TheType.GetInterface("IList`1", false) != null) { nowSerializeInfo.IsIList = true; nowSerializeInfo.Length_FieldInfo = (nowSerializeInfo.TheObject as IList).Count; //写入数组长度 bwData.WriteArrayHead(nowSerializeInfo.Length_FieldInfo); } else if (nowSerializeInfo.TheType.GetInterface("IDictionary`2", false) != null) { nowSerializeInfo.IsIDictionary = true; IDictionary id = nowSerializeInfo.TheObject as IDictionary; int dLength = id.Count; nowSerializeInfo.Length_FieldInfo = dLength * 2; object[] kvs = new object[nowSerializeInfo.Length_FieldInfo]; id.Keys.CopyTo(kvs, 0); id.Values.CopyTo(kvs, dLength); nowSerializeInfo.TheObject = kvs; //写入数组长度 bwData.WriteArrayHead(nowSerializeInfo.Length_FieldInfo); } else { bwData.WriteNullHead(false); DynamicFieldInfo[] fis; lock (FI_Lookup) { if (FI_Lookup.ContainsKey(nowSerializeInfo.TheType)) { fis = FI_Lookup[nowSerializeInfo.TheType]; } else { PropertyInfo[] fi = nowSerializeInfo.TheType.GetProperties(AllInstanceBindingFlags).OrderBy(c => c.Name).ToArray(); List <DynamicFieldInfo> tempFis = new List <DynamicFieldInfo>(); for (int i = 0; i < fi.Length; i++) { PropertyInfo fiNow = fi[i]; object[] at = fiNow.GetCustomAttributes(typeof(System.NonSerializedAttribute), true); if (at.Length == 0) { tempFis.Add(new DynamicFieldInfo() { TheField = fiNow }); } } fis = tempFis.ToArray(); FI_Lookup.Add(nowSerializeInfo.TheType, fis); } } nowSerializeInfo.FieldInfos = fis; nowSerializeInfo.Length_FieldInfo = fis.Length; } if (nowSerializeInfo.Length_FieldInfo == 0) //虽然不是基础元素,但没有可序列化的字段 { bufStack.Pop(); if (fullLengthSchema) { metablockStart = nowSerializeInfo.ByteStartIndexOrEndPoint; metablockLen = bwData.EffectiveBytesLength - metablockStart - 2; if (metablockLen > ushort.MaxValue) { throw new Exception("序列化的子字段大小超出65535:" + nowSerializeInfo.FieldInfos[nowSerializeInfo.Index - 1].FieldName); } ZipBytesWriter.WriteAtUshort(bwData.Bytes, metablockStart, (ushort)metablockLen); } } else { nowSerializeInfo.Index = 0; isFieldNullable = false; object innerObject = nowSerializeInfo.GetInnerField(ref isFieldNullable); nowSerializeInfo.Index++; bufStack.Push(new SerializeInfo(innerObject, isFieldNullable, bwData.EffectiveBytesLength)); if (fullLengthSchema) { bwData.Write(DefaultFieldLen); } } } } else //上次检查过 { if (nowSerializeInfo.Length_FieldInfo == nowSerializeInfo.Index) //检查完了 { bufStack.Pop(); if (fullLengthSchema) { metablockStart = nowSerializeInfo.ByteStartIndexOrEndPoint; metablockLen = bwData.EffectiveBytesLength - metablockStart - 2; if (metablockLen > ushort.MaxValue) { throw new Exception("序列化的子字段大小超出65535:" + nowSerializeInfo.FieldInfos[nowSerializeInfo.Index - 1].FieldName); } ZipBytesWriter.WriteAtUshort(bwData.Bytes, metablockStart, (ushort)metablockLen); } } else { isFieldNullable = false; object innerObject = nowSerializeInfo.GetInnerField(ref isFieldNullable); nowSerializeInfo.Index++; bufStack.Push(new SerializeInfo(innerObject, isFieldNullable, bwData.EffectiveBytesLength)); if (fullLengthSchema) { bwData.Write(DefaultFieldLen); } } } } } writeToBytes = bwData.Bytes; return(bwData.EffectiveBytesLength); } //catch (Exception ee) { //throw new SerializeException(obj.GetType().ToString() + "Data bytes and type not match:" + ee.Message); } }
/// <summary> /// 尝试直接序列化基础值类型(包括其数组) /// </summary> /// <param name="value">对象</param> /// <param name="type">对象的类型</param> /// <param name="theByteWriter">写入Write</param> /// <returns>能否执行</returns> public static bool TryWriteBytes(object value, Type type, ZipBytesWriter theByteWriter) { if (value == null) { return false; } if (type.IsEnum) { type = type.GetFields()[0].FieldType; } if (type == Type_Bool) { theByteWriter.Write((bool)value); return true; } if (type == Type_Byte) { theByteWriter.Write((byte)value); return true; } if (type == Type_SByte) { theByteWriter.Write((sbyte)value); return true; } if (type == Type_UInt16) { theByteWriter.Write((UInt16)value); return true; } if (type == Type_Int16) { theByteWriter.Write((Int16)value); return true; } if (type == Type_Char) { theByteWriter.Write((Char)value); return true; } if (type == Type_UInt32) { theByteWriter.Write((UInt32)value); return true; } if (type == Type_Int32) { theByteWriter.Write((Int32)value); return true; } if (type == Type_UInt64) { theByteWriter.Write((UInt64)value); return true; } if (type == Type_Int64) { theByteWriter.Write((Int64)value); return true; } if (type == Type_Single) { theByteWriter.Write((Single)value); return true; } if (type == Type_Double) { theByteWriter.Write((Double)value); return true; } if (type == Type_Decimal) { theByteWriter.Write((Decimal)value); return true; } if (type == Type_Guid) { theByteWriter.Write((Guid)value); return true; } if (type == Type_DateTime) { theByteWriter.Write((DateTime)value); return true; } if (type == Type_TimeSpan) { theByteWriter.Write((TimeSpan)value); return true; } if (type == Type_String) { theByteWriter.Write((String)value); return true; } if (type.IsArray) { Type elemtT = type.GetElementType(); if (elemtT.IsEnum) { #if Server || WP type = elemtT.GetFields()[0].FieldType; type = type.MakeArrayType(); #else Type elemtUnderType = null; FieldInfo elemtValueField = null; elemtValueField = elemtT.GetFields()[0]; elemtUnderType = elemtValueField.FieldType; type = elemtUnderType.MakeArrayType(); Array oArray = value as Array; int arrayLength = oArray.Length; Array newArray = Array.CreateInstance(elemtUnderType, arrayLength); Array.Copy(oArray, 0, newArray, 0, arrayLength); value = newArray; #endif } } if (type == Type_Bools) { theByteWriter.Write((bool[])value); return true; } if (type == Type_Bytes) { theByteWriter.Write((byte[])value, ((byte[])value).Length); return true; } if (type == Type_SBytes) { theByteWriter.Write((sbyte[])value); return true; } if (type == Type_UInt16s) { theByteWriter.Write((UInt16[])value); return true; } if (type == Type_Int16s) { theByteWriter.Write((Int16[])value); return true; } if (type == Type_Chars) { theByteWriter.Write((Char[])value); return true; } if (type == Type_UInt32s) { theByteWriter.Write((UInt32[])value); return true; } if (type == Type_Int32s) { theByteWriter.Write((Int32[])value); return true; } if (type == Type_UInt64s) { theByteWriter.Write((UInt64[])value); return true; } if (type == Type_Int64s) { theByteWriter.Write((Int64[])value); return true; } if (type == Type_Singles) { theByteWriter.Write((Single[])value); return true; } if (type == Type_Doubles) { theByteWriter.Write((Double[])value); return true; } if (type == Type_Decimals) { theByteWriter.Write((Decimal[])value); return true; } if (type == Type_Guids) { theByteWriter.Write((Guid[])value); return true; } if (type == Type_DateTimes) { theByteWriter.Write((DateTime[])value); return true; } if (type == Type_TimeSpans) { theByteWriter.Write((TimeSpan[])value); return true; } return false; }