示例#1
0
        /// <summary>
        ///     将一个对象字段转换为二进制元数据
        /// </summary>
        /// <param name="metadata">需要转换成元数据的Value字典</param>
        /// <param name="proxy">内存段代理器</param>
        internal unsafe static void ToBytes(ResourceBlock metadata, IMemorySegmentProxy proxy)
        {
            Dictionary <byte, BaseValueStored> valueStoreds = metadata.GetMetaDataDictionary();
            uint           markRangeLength      = (uint)(valueStoreds.Count * 5);
            MemoryPosition wrapperStartPosition = proxy.GetPosition();

            proxy.Skip(4U);
            proxy.WriteUInt16((ushort)(valueStoreds.Count));
            MemoryPosition wrapperMarkRangeStartPosition = proxy.GetPosition();

            proxy.Skip(markRangeLength);
            MemoryPosition wrapperOffsetStartPosition = proxy.GetPosition();
            MarkRange *    markRange = stackalloc MarkRange[valueStoreds.Count];
            int            i         = 0;

            foreach (KeyValuePair <byte, BaseValueStored> valueStored in valueStoreds)
            {
                //转化成二进制数组的形式
                MemoryPosition wrapperCurrentPosition = proxy.GetPosition();
                uint           currentOffset          = (uint)MemoryPosition.CalcLength(proxy.SegmentCount, wrapperOffsetStartPosition, wrapperCurrentPosition);
                (markRange + i)->Id     = valueStored.Key;
                (markRange + i++)->Flag = (uint)((currentOffset << 8) | (int)valueStored.Value.TypeId);
                if (valueStored.Value.IsNull)
                {
                    continue;
                }
                valueStored.Value.ToBytes(proxy);
            }
            MemoryPosition wrapperEndPosition = proxy.GetPosition();

            //回写mark Range
            proxy.WriteBackMemory(wrapperMarkRangeStartPosition, markRange, markRangeLength);
            //回写4bytes总长
            proxy.WriteBackInt32(wrapperStartPosition, MemoryPosition.CalcLength(proxy.SegmentCount, wrapperStartPosition, wrapperEndPosition));
        }
        /// <summary>
        ///     从第三方客户数据转换为元数据
        /// </summary>
        /// <param name="proxy">内存片段代理器</param>
        /// <param name="attribute">字段属性</param>
        /// <param name="analyseResult">分析结果</param>
        /// <param name="target">目标对象实例</param>
        /// <param name="isArrayElement">当前写入的值是否为数组元素标示</param>
        public override void Process(IMemorySegmentProxy proxy, IntellectPropertyAttribute attribute, ToBytesAnalyseResult analyseResult, object target, bool isArrayElement = false, bool isNullable = false)
        {
            string[] value = analyseResult.GetValue <string[]>(target);
            if (value == null)
            {
                if (!attribute.IsRequire)
                {
                    return;
                }
                throw new PropertyNullValueException(string.Format(ExceptionMessage.EX_PROPERTY_VALUE, attribute.Id, analyseResult.Property.Name, analyseResult.Property.PropertyType));
            }
            //id(1) + total length(4) + rank(4)
            proxy.WriteByte((byte)attribute.Id);
            MemoryPosition position = proxy.GetPosition();

            proxy.Skip(4U);
            proxy.WriteInt32(value.Length);
            if (value.Length == 0)
            {
                proxy.WriteBackInt32(position, 4);
                return;
            }
            for (int i = 0; i < value.Length; i++)
            {
                string elementValue = value[i];
                if (string.IsNullOrEmpty(elementValue))
                {
                    proxy.WriteUInt16(0);
                }
                else
                {
                    byte[] elementData = Encoding.UTF8.GetBytes(elementValue);
                    proxy.WriteUInt16((ushort)elementData.Length);
                    proxy.WriteMemory(elementData, 0U, (uint)elementData.Length);
                }
            }
            MemoryPosition endPosition = proxy.GetPosition();

            proxy.WriteBackInt32(position, MemoryPosition.CalcLength(proxy.SegmentCount, position, endPosition) - 4);
        }
示例#3
0
        /// <summary>
        ///     将一个智能对象转换为二进制元数据
        /// </summary>
        /// <param name="obj">智能对象</param>
        /// <param name="proxy">内存段代理器</param>
        /// <returns>返回当前已经被序列化对象的总体长度</returns>
        internal static void ToBytes(IThriftObject obj, IMemorySegmentProxy proxy)
        {
            //获取智能对象中的智能属性,并按照Id来排序
            ToBytesAnalyseResult[] properties = Analyser.ToBytesAnalyser.Analyse(obj);
            if (properties.Length == 0)
            {
                return;
            }
            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 普通类型判断

                IThriftTypeProcessor intellectTypeProcessor = ThriftTypeProcessorMapping.Instance.GetProcessor(property.Property.PropertyType);
                if (intellectTypeProcessor != null)
                {
                    //添加热缓存
                    IThriftTypeProcessor 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.IsEnum)
                {
                    //获取枚举类型
                    Type enumType = Enum.GetUnderlyingType(property.Property.PropertyType);
                    intellectTypeProcessor = ThriftTypeProcessorMapping.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));
                    }
                    //添加热缓存
                    IThriftTypeProcessor 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 = ThriftTypeProcessorMapping.Instance.GetProcessor(innerType);
                    if (intellectTypeProcessor != null)
                    {
                        //添加热缓存
                        IThriftTypeProcessor processor = intellectTypeProcessor;
                        property.CacheProcess = delegate(IMemorySegmentProxy innerProxy, ThriftPropertyAttribute 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 Thrift Object类型判断

                if (property.Property.PropertyType.GetInterface(Consts.ThriftObjectFullName) != null)
                {
                    //添加热缓存
                    property.CacheProcess = delegate(IMemorySegmentProxy innerProxy, ThriftPropertyAttribute innerAttribute, ToBytesAnalyseResult innerAnalyseResult, object innerTarget, bool innerIsArrayElement, bool innerNullable)
                    {
                        IThriftObject innerIntellectObj = innerAnalyseResult.GetValue <IThriftObject>(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.
                    IThriftTypeProcessor 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.IsSubclassOf(typeof(ThriftObject)))
                    {
                        //Add hot cache.
                        property.CacheProcess = delegate(IMemorySegmentProxy innerProxy, ThriftPropertyAttribute innerAttribute, ToBytesAnalyseResult innerAnalyseResult, object innerTarget, bool innerIsArrayElement, bool innerNullable)
                        {
                            IThriftObject[] array = innerAnalyseResult.GetValue <IThriftObject[]>(innerTarget);
                            if (array == null)
                            {
                                if (innerAttribute.Optional)
                                {
                                    return;
                                }
                                throw new PropertyNullValueException(string.Format(ExceptionMessage.EX_PROPERTY_VALUE, innerAttribute.Id, innerAnalyseResult.Property.Name, innerAnalyseResult.Property.PropertyType));
                            }
                            //property type
                            innerProxy.WriteSByte((sbyte)innerAttribute.PropertyType);
                            innerProxy.WriteInt16(((short)innerAttribute.Id).ToBigEndian());
                            //element type(1) + array length(4)
                            innerProxy.WriteSByte((sbyte)PropertyTypes.Struct);
                            innerProxy.WriteInt32(array.Length.ToBigEndian());
                            for (int i = 0; i < array.Length; i++)
                            {
                                IThriftObject element = array[i];
                                ToBytes(element, innerProxy);
                                //end flag of Thrift protocol object.
                                innerProxy.WriteSByte(0x00);
                            }
                        };
                    }
                    else
                    {
                        intellectTypeProcessor = ThriftTypeProcessorMapping.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.
                        IThriftTypeProcessor processor = intellectTypeProcessor;
                        property.CacheProcess = delegate(IMemorySegmentProxy innerProxy, ThriftPropertyAttribute innerAttribute, ToBytesAnalyseResult innerAnalyseResult, object innerTarget, bool innerIsArrayElement, bool innerNullable)
                        {
                            Array array = innerAnalyseResult.GetValue <Array>(innerTarget);
                            if (array == null)
                            {
                                if (innerAttribute.Optional)
                                {
                                    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));
            }
        }
示例#4
0
        /// <summary>
        ///     将指定类型的实例序列化为二进制数据
        /// </summary>
        /// <param name="type">类型</param>
        /// <param name="instance">实例对象</param>
        /// <param name="proxy">内存段代理器</param>
        /// <returns>返回序列化后的二进制数据, 如果instance为null, 则返回null</returns>
        /// <exception cref="NotSupportedException">不被支持的类型</exception>
        private static void ToBytes(Type type, object instance, IMemorySegmentProxy proxy)
        {
            Type innerType;
            Action <IMemorySegmentProxy, object> cache;

            lock (_serLockObj)
            {
                if (_serializers.TryGetValue(type.FullName, out cache))
                {
                    cache(proxy, instance);
                    return;
                }
                IIntellectTypeProcessor intellectTypeProcessor;

                #region 普通类型判断

                intellectTypeProcessor = IntellectTypeProcessorMapping.Instance.GetProcessor(type);
                if (intellectTypeProcessor != null)
                {
                    //添加热缓存
                    IIntellectTypeProcessor processor = intellectTypeProcessor;
                    _serializers.Add(type.FullName, (cache = (innerProxy, innerObj) => processor.Process(innerProxy, innerObj)));
                }

                #endregion

                #region 枚举类型判断

                //枚举类型
                else if (type.GetTypeInfo().IsEnum)
                {
                    //获取枚举类型
                    Type enumType = Enum.GetUnderlyingType(type);
                    intellectTypeProcessor = IntellectTypeProcessorMapping.Instance.GetProcessor(enumType);
                    if (intellectTypeProcessor == null)
                    {
                        throw new NotSupportedException(string.Format(ExceptionMessage.EX_NOT_SUPPORTED_VALUE_TEMPORARY, type));
                    }
                    IIntellectTypeProcessor processor = intellectTypeProcessor;
                    _serializers.Add(type.FullName, (cache = (innerProxy, innerObj) => processor.Process(innerProxy, innerObj)));
                }

                #endregion

                #region 可空类型判断

                else if ((innerType = Nullable.GetUnderlyingType(type)) != null)
                {
                    intellectTypeProcessor = IntellectTypeProcessorMapping.Instance.GetProcessor(innerType);
                    if (intellectTypeProcessor == null)
                    {
                        throw new NotSupportedException(string.Format(ExceptionMessage.EX_NOT_SUPPORTED_VALUE_TEMPORARY, innerType));
                    }
                    IIntellectTypeProcessor processor = intellectTypeProcessor;
                    _serializers.Add(type.FullName, (cache = (innerProxy, innerObj) => processor.Process(innerProxy, innerObj)));
                }

                #endregion

                #region 智能对象类型判断

                else if (type.GetTypeInfo().IsSubclassOf(typeof(IntellectObject)))
                {
                    _serializers.Add(type.FullName, (cache = (innerProxy, innerObj) => { IntellectObjectEngine.ToBytes((IIntellectObject)innerObj, innerProxy); }));
                }

                #endregion

                #region 数组的判断

                else if (type.IsArray)
                {
                    if (!type.HasElementType)
                    {
                        throw new NotSupportedException(string.Format(ExceptionMessage.EX_NOT_SUPPORTED_VALUE_TEMPORARY, type));
                    }
                    Type elementType = type.GetElementType();
                    VT   vt          = FixedTypeManager.IsVT(elementType);
                    IIntellectTypeProcessor arrayProcessor = ArrayTypeProcessorMapping.Instance.GetProcessor(type);
                    if (arrayProcessor != null)
                    {
                        _serializers.Add(type.FullName, (cache = (innerProxy, innerObj) => arrayProcessor.Process(innerProxy, innerObj)));
                    }
                    else if (vt != null)
                    {
                        throw new NotSupportedException(string.Format(ExceptionMessage.EX_NOT_SUPPORTED_VALUE_TEMPORARY, type));
                    }
                    else if (elementType.GetTypeInfo().IsSubclassOf(typeof(IntellectObject)))
                    {
                        //Add hot cache.
                        _serializers.Add(type.FullName, (cache = (innerProxy, innerObj) =>
                        {
                            IIntellectObject[] array = (IIntellectObject[])innerObj;
                            if (array == null || array.Length == 0)
                            {
                                return;
                            }
                            //write array length.
                            innerProxy.WriteUInt32((uint)array.Length);
                            for (int i = 0; i < array.Length; i++)
                            {
                                if (array[i] == null)
                                {
                                    innerProxy.WriteUInt16(0);
                                }
                                else
                                {
                                    MemoryPosition innerStartObjPosition = innerProxy.GetPosition();
                                    innerProxy.Skip(Size.UInt16);
                                    IntellectObjectEngine.ToBytes(array[i], innerProxy);
                                    MemoryPosition innerEndObjPosition = innerProxy.GetPosition();
                                    innerProxy.WriteBackUInt16(innerStartObjPosition, (ushort)(MemoryPosition.CalcLength(innerProxy.SegmentCount, innerStartObjPosition, innerEndObjPosition) - 2));
                                }
                            }
                        }));
                    }
                    else
                    {
                        throw new NotSupportedException(string.Format(ExceptionMessage.EX_NOT_SUPPORTED_VALUE_TEMPORARY, type));
                    }
                }

                #endregion

                cache(proxy, instance);
            }
        }