Пример #1
0
        /// <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());
        }
Пример #2
0
 /// <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);
 }
Пример #3
0
        /// <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);
        }