/// <summary> /// 将一个IntellectObject数组转换成byte数组的形式 /// </summary> /// <param name="value">值</param> /// <exception cref="UnexpectedValueException">结果错误</exception> /// <exception cref="ArgumentNullException">参数不能为空</exception> public static byte[] BindIntellectObjectArray(IntellectObject[] value) { if (value == null) { throw new ArgumentNullException("value"); } MemoryAllotter.Instance.Initialize(); IMemorySegmentProxy proxy = MemorySegmentProxyFactory.Create(); proxy.WriteUInt32((uint)value.Length); for (int i = 0; i < value.Length; i++) { IntellectObject elementObj = value[i]; if (elementObj == null) { proxy.WriteUInt16(0); } else { MemoryPosition currentPostion = proxy.GetPosition(); proxy.Skip(2U); int length = IntellectObjectEngine.ToBytes(elementObj, proxy); proxy.WriteBackUInt16(currentPostion, (ushort)length); } } return(proxy.GetBytes()); }
/// <summary> /// 将一个IntellectObject转换成byte数组的形式 /// </summary> /// <param name="value">值</param> /// <exception cref="ArgumentNullException">参数不能为空</exception> public static byte[] BindIntellectObject(IntellectObject value) { if (value == null) { throw new ArgumentNullException("value"); } value.Bind(); return(value.Body); }
/// <summary> /// 将一个IntellectObject数组转换成byte数组的形式 /// </summary> /// <param name="value">值</param> /// <exception cref="UnexpectedValueException">结果错误</exception> /// <exception cref="ArgumentNullException">参数不能为空</exception> private static byte[] BindIntellectObjectArrayMethod(IntellectObject[] value) { if (value == null) { throw new ArgumentNullException("value"); } List <byte[]> byteList = new List <byte[]>(); int totalLength = value.Length * 2 + 4; byte[] placeHolderByte = { 0x00, 0x00 }; for (int i = 0; i < value.Length; i++) { IntellectObject elementObj = value[i]; if (elementObj == null) { byteList.Add(placeHolderByte); continue; } elementObj.Bind(); if (!elementObj.IsBind) { throw new UnexpectedValueException("elementObj"); } byteList.Add(elementObj.Body); totalLength += elementObj.Body.Length; } byte[] bytes = new byte[totalLength]; int dstOffset = 0; Buffer.BlockCopy(BitConverter.GetBytes(value.Length), 0, bytes, dstOffset, 4); dstOffset += 4; for (int i = 0; i < byteList.Count; i++) { if (byteList[i] == placeHolderByte) { Buffer.BlockCopy(byteList[i], 0, bytes, dstOffset, 2); dstOffset += 2; } else { Buffer.BlockCopy(BitConverter.GetBytes(byteList[i].Length), 0, bytes, dstOffset, 2); dstOffset += 2; Buffer.BlockCopy(byteList[i], 0, bytes, dstOffset, byteList[i].Length); dstOffset += byteList[i].Length; } } if (bytes.Length != totalLength) { throw new UnexpectedValueException("value"); } return(bytes); }
/// <summary> /// 将一个智能对象转换为二进制元数据 /// </summary> /// <param name="obj">智能对象</param> /// <param name="proxy">内存段代理器</param> /// <returns>返回当前已经被序列化对象的总体长度</returns> internal static int ToBytes(IIntellectObject obj, IMemorySegmentProxy proxy) { //获取智能对象中的智能属性,并按照Id来排序 ToBytesAnalyseResult[] properties = Analyser.ToBytesAnalyser.Analyse(obj); if (properties.Length == 0) { return(-1); } MemoryPosition wrapperStartPosition = proxy.GetPosition(); proxy.Skip(4U); IIntellectTypeProcessor intellectTypeProcessor; for (int l = 0; l < properties.Length; l++) { ToBytesAnalyseResult property = properties[l]; //先检查完全缓存机制 if (property.HasCacheFinished) { property.CacheProcess(proxy, property.Attribute, property, obj, false, false); continue; } #region 普通类型判断 intellectTypeProcessor = IntellectTypeProcessorMapping.Instance.GetProcessor(property.Attribute.Id) ?? IntellectTypeProcessorMapping.Instance.GetProcessor(property.Property.PropertyType); if (intellectTypeProcessor != null) { //添加热缓存 IIntellectTypeProcessor processor = intellectTypeProcessor; property.CacheProcess = processor.Process; property.CacheProcess(proxy, property.Attribute, property, obj, false, false); property.HasCacheFinished = true; continue; } #endregion #region 枚举类型判断 //枚举类型 if (property.Property.PropertyType.GetTypeInfo().IsEnum) { //获取枚举类型 Type enumType = Enum.GetUnderlyingType(property.Property.PropertyType); intellectTypeProcessor = IntellectTypeProcessorMapping.Instance.GetProcessor(enumType); if (intellectTypeProcessor == null) { throw new NotSupportedException(string.Format(ExceptionMessage.EX_NOT_SUPPORTED_VALUE, property.Attribute.Id, property.Property.Name, property.Property.PropertyType)); } //添加热缓存 IIntellectTypeProcessor processor = intellectTypeProcessor; property.CacheProcess = processor.Process; property.CacheProcess(proxy, property.Attribute, property, obj, false, false); property.HasCacheFinished = true; continue; } #endregion #region 可空类型判断 Type innerType; if ((innerType = Nullable.GetUnderlyingType(property.Property.PropertyType)) != null) { intellectTypeProcessor = IntellectTypeProcessorMapping.Instance.GetProcessor(innerType); if (intellectTypeProcessor != null) { //添加热缓存 IIntellectTypeProcessor processor = intellectTypeProcessor; property.CacheProcess = delegate(IMemorySegmentProxy innerProxy, IntellectPropertyAttribute innerAttribute, ToBytesAnalyseResult innerAnalyseResult, object innerTarget, bool innerIsArrayElement, bool innerNullable) { processor.Process(innerProxy, innerAttribute, innerAnalyseResult, innerTarget, innerIsArrayElement, true); }; property.CacheProcess(proxy, property.Attribute, property, obj, false, true); property.HasCacheFinished = true; continue; } throw new NotSupportedException(string.Format(ExceptionMessage.EX_NOT_SUPPORTED_VALUE, property.Attribute.Id, property.Property.Name, property.Property.PropertyType)); } #endregion #region 智能对象类型判断 if (property.Property.PropertyType.GetTypeInfo().GetInterface(Consts.IntellectObjectFullName) != null) { //添加热缓存 property.CacheProcess = delegate(IMemorySegmentProxy innerProxy, IntellectPropertyAttribute innerAttribute, ToBytesAnalyseResult innerAnalyseResult, object innerTarget, bool innerIsArrayElement, bool innerNullable) { IntellectObject innerIntellectObj = innerAnalyseResult.GetValue <IntellectObject>(innerTarget); if (innerIntellectObj == null) { return; } innerProxy.WriteByte((byte)innerAttribute.Id); MemoryPosition startPos = innerProxy.GetPosition(); innerProxy.Skip(4); ToBytes(innerIntellectObj, innerProxy); MemoryPosition endPos = innerProxy.GetPosition(); innerProxy.WriteBackInt32(startPos, MemoryPosition.CalcLength(innerProxy.SegmentCount, startPos, endPos) - 4); }; property.CacheProcess(proxy, property.Attribute, property, obj, false, false); property.HasCacheFinished = true; continue; } #endregion #region 数组的判断 if (property.Property.PropertyType.IsArray) { if (!property.Property.PropertyType.HasElementType) { throw new NotSupportedException(string.Format(ExceptionMessage.EX_NOT_SUPPORTED_VALUE, property.Attribute.Id, property.Property.Name, property.Property.PropertyType)); } Type elementType = property.Property.PropertyType.GetElementType(); VT vt = FixedTypeManager.IsVT(elementType); //special optimize. IIntellectTypeProcessor arrayProcessor = ArrayTypeProcessorMapping.Instance.GetProcessor(property.Property.PropertyType); if (arrayProcessor != null) { property.CacheProcess = arrayProcessor.Process; } //is VT, but cannot find special processor. else if (vt != null) { throw new NotSupportedException(string.Format(ExceptionMessage.EX_NOT_SUPPORTED_VALUE, property.Attribute.Id, property.Property.Name, property.Property.PropertyType)); } else if (elementType.GetTypeInfo().IsSubclassOf(typeof(IntellectObject))) { //Add hot cache. property.CacheProcess = delegate(IMemorySegmentProxy innerProxy, IntellectPropertyAttribute innerAttribute, ToBytesAnalyseResult innerAnalyseResult, object innerTarget, bool innerIsArrayElement, bool innerNullable) { IIntellectObject[] array = innerAnalyseResult.GetValue <IIntellectObject[]>(innerTarget); if (array == null) { if (!innerAttribute.IsRequire) { return; } throw new PropertyNullValueException(string.Format(ExceptionMessage.EX_PROPERTY_VALUE, innerAttribute.Id, innerAnalyseResult.Property.Name, innerAnalyseResult.Property.PropertyType)); } //id(1) + total length(4) + rank(4) innerProxy.WriteByte((byte)innerAttribute.Id); MemoryPosition startPosition = innerProxy.GetPosition(); innerProxy.Skip(4U); innerProxy.WriteInt32(array.Length); for (int i = 0; i < array.Length; i++) { IIntellectObject element = array[i]; if (element == null) { innerProxy.WriteUInt16(0); } else { MemoryPosition innerStartObjPosition = innerProxy.GetPosition(); innerProxy.Skip(Size.UInt16); ToBytes(element, innerProxy); MemoryPosition innerEndObjPosition = innerProxy.GetPosition(); innerProxy.WriteBackUInt16(innerStartObjPosition, (ushort)(MemoryPosition.CalcLength(innerProxy.SegmentCount, innerStartObjPosition, innerEndObjPosition) - 2)); } } MemoryPosition endPosition = innerProxy.GetPosition(); innerProxy.WriteBackInt32(startPosition, MemoryPosition.CalcLength(innerProxy.SegmentCount, startPosition, endPosition) - 4); }; } else if (!(elementType == typeof(string)) && elementType.GetTypeInfo().IsSerializable) { throw new NotSupportedException(string.Format(ExceptionMessage.EX_NOT_SUPPORTED_VALUE, property.Attribute.Id, property.Property.Name, property.Property.PropertyType)); } else { intellectTypeProcessor = IntellectTypeProcessorMapping.Instance.GetProcessor(property.Attribute.Id) ?? IntellectTypeProcessorMapping.Instance.GetProcessor(elementType); if (intellectTypeProcessor == null) { throw new NotSupportedException(string.Format(ExceptionMessage.EX_NOT_SUPPORTED_VALUE, property.Attribute.Id, property.Property.Name, elementType)); } //Add hot cache. IIntellectTypeProcessor processor = intellectTypeProcessor; property.CacheProcess = delegate(IMemorySegmentProxy innerProxy, IntellectPropertyAttribute innerAttribute, ToBytesAnalyseResult innerAnalyseResult, object innerTarget, bool innerIsArrayElement, bool innerNullable) { Array array = innerAnalyseResult.GetValue <Array>(innerTarget); if (array == null) { if (!innerAttribute.IsRequire) { return; } throw new PropertyNullValueException(string.Format(ExceptionMessage.EX_PROPERTY_VALUE, innerAttribute.Id, innerAnalyseResult.Property.Name, innerAnalyseResult.Property.PropertyType)); } //id(1) + total length(4) + rank(4) innerProxy.WriteByte((byte)innerAttribute.Id); MemoryPosition startPosition = innerProxy.GetPosition(); innerProxy.Skip(4); innerProxy.WriteInt32(array.Length); for (int i = 0; i < array.Length; i++) { object element = array.GetValue(i); if (element == null) { innerProxy.WriteUInt16(0); } else { MemoryPosition innerStartObjPosition = innerProxy.GetPosition(); innerProxy.Skip(Size.UInt16); processor.Process(innerProxy, innerAttribute, innerAnalyseResult, element, true); MemoryPosition innerEndObjPosition = innerProxy.GetPosition(); innerProxy.WriteBackUInt16(innerStartObjPosition, (ushort)(MemoryPosition.CalcLength(innerProxy.SegmentCount, innerStartObjPosition, innerEndObjPosition) - 2)); } } MemoryPosition endPosition = innerProxy.GetPosition(); innerProxy.WriteBackInt32(startPosition, MemoryPosition.CalcLength(innerProxy.SegmentCount, startPosition, endPosition) - 4); }; } property.CacheProcess(proxy, property.Attribute, property, obj, false, false); property.HasCacheFinished = true; continue; } #endregion throw new NotSupportedException(string.Format(ExceptionMessage.EX_NOT_SUPPORTED_VALUE, property.Attribute.Id, property.Property.Name, property.Property.PropertyType)); } MemoryPosition wrapperEndPosition = proxy.GetPosition(); int length = MemoryPosition.CalcLength(proxy.SegmentCount, wrapperStartPosition, wrapperEndPosition); proxy.WriteBackInt32(wrapperStartPosition, length); return(length); }
/// <summary> /// 将一个元数据转换为特定类型的对象 /// </summary> /// <typeparam name="T">对象类型</typeparam> /// <param name="target">特定的对象</param> /// <param name="data">元数据</param> /// <param name="offset">元数据偏移</param> /// <param name="length">可用元数据长度</param> /// <returns>返回转换后的特定对象</returns> /// <exception cref="Exception">转换失败</exception> public static T GetObject <T>(Type target, byte[] data, int offset, int length) { if (target == null) { throw new ArgumentNullException("target"); } if (data == null) { throw new ArgumentNullException("data"); } Dictionary <int, GetObjectAnalyseResult> result = Analyser.GetObjectAnalyser.Analyse(target); if (result == null) { return(default(T)); } #region 解析数据部分 int id, currentLength, chunkSize; chunkSize = offset + length; int innerOffset = offset + 4; int totalLength = BitConverter.ToInt32(data, offset); if (totalLength != length) { throw new System.Exception("Illegal binary data length! #length: " + totalLength); } //create instance for new obj. Object instance = Activator.CreateInstance(target); IntellectObject intellectObject = instance as IntellectObject; if (intellectObject == null) { throw new System.Exception("Cannot convert target object to Intellect Object! #type: " + target.FullName); } do { //get id. id = data[innerOffset++]; //get analyze result. GetObjectAnalyseResult analyzeResult; if (!result.TryGetValue(id, out analyzeResult)) { if (!MemoryAllotter.AllowCompatibleMode) { throw new System.Exception("Illegal data contract, non-exists id! #id: " + id); } intellectObject.CompatibleMode = true; intellectObject.IsPickup = true; return((T)instance); } //calc data length. if (analyzeResult.VT) { currentLength = analyzeResult.VTStruct.Size; } else { currentLength = BitConverter.ToInt32(data, innerOffset); innerOffset += 4; } //set current property value to the target object. InstanceHelper.SetInstance(intellectObject, analyzeResult, data, innerOffset, currentLength); innerOffset += currentLength; } while (innerOffset < data.Length && innerOffset < chunkSize); #endregion intellectObject.IsPickup = true; return((T)instance); }