/// <summary>
        ///     从元数据转换为第三方客户数据
        /// </summary>
        /// <param name="instance">目标对象</param>
        /// <param name="result">分析结果</param>
        /// <param name="container">网络数据容器</param>
        public override GetObjectResultTypes Process(object instance, GetObjectAnalyseResult result, INetworkDataContainer container)
        {
            byte keyType, valueType;
            int  count;

            if (!container.TryReadByte(out keyType))
            {
                return(GetObjectResultTypes.NotEnoughData);
            }
            if (!container.TryReadByte(out valueType))
            {
                return(GetObjectResultTypes.NotEnoughData);
            }
            if (!container.TryReadInt32(out count))
            {
                return(GetObjectResultTypes.NotEnoughData);
            }
            count = count.ToLittleEndian();
            Dictionary <string, Cell> value = new Dictionary <string, Cell>(count);

            for (int i = 0; i < count; i++)
            {
                int stringCount;
                if (!container.TryReadInt32(out stringCount))
                {
                    return(GetObjectResultTypes.NotEnoughData);
                }
                stringCount = stringCount.ToLittleEndian();
                string keyContent;
                if (!container.TryReadString(Encoding.UTF8, stringCount, out keyContent))
                {
                    return(GetObjectResultTypes.NotEnoughData);
                }

                Cell valueContent;
                GetObjectResultTypes type = ThriftObjectEngine.TryGetObject(typeof(Cell), container, out valueContent, true);
                if (type != GetObjectResultTypes.Succeed)
                {
                    return(type);
                }
                value.Add(keyContent, valueContent);
            }
            result.SetValue(instance, value);
            return(GetObjectResultTypes.Succeed);
        }
Ejemplo n.º 2
0
 /// <summary>
 ///     Serialize current Thrift object into data buffer.
 /// </summary>
 public void Bind()
 {
     try
     {
         Body   = ThriftObjectEngine.ToBytes(this);
         IsBind = true;
     }
     catch (MethodAccessException ex)
     {
         IsBind = false;
         Body   = null;
         _tracing.Error(ex, null);
         //redirect to friendly exception message.
         throw new MethodAccessException(string.Format(ExceptionMessage.EX_METHOD_ACCESS, GetType().FullName));
     }
     catch (Exception ex)
     {
         IsBind = false;
         Body   = null;
         _tracing.Error(ex, null);
     }
 }
 /// <summary>
 ///    追加一个新的数据段
 /// </summary>
 /// <param name="args">数据段接受参数</param>
 public void Append(SegmentReceiveEventArgs args)
 {
     lock (_lockObj)
     {
         _container.AppendNetworkData(args);
         MessageIdentity identity;
         if (!_container.TryReadMessageIdentity(out identity))
         {
             _container.ResetOffset();
             return;
         }
         _container.ResetOffset();
         Type msgType = _protocolStack.GetMessageType(identity.Command, false);
         if (msgType == null)
         {
             _tracing.Error("#Type of Thrift message has no any registered .NET type. #Type: {0}, seqID={1}, data: \r\n{2}", identity.Command, identity.SequenceId, _container.Dump());
         }
         else
         {
             try
             {
                 ThriftMessage msg;
                 if (ThriftObjectEngine.TryGetObject(msgType, _container, out msg) != GetObjectResultTypes.Succeed)
                 {
                     return;
                 }
                 _container.UpdateOffset();
                 OnParseSucceed(new LightSingleArgEventArgs <List <ThriftMessage> >(new List <ThriftMessage> {
                     msg
                 }));
             }
             catch (Exception ex)
             {
                 _tracing.Error(ex, null);
             }
         }
     }
 }
Ejemplo n.º 4
0
        /// <summary>
        ///     设置字段实例
        /// </summary>
        /// <param name="instance">对象实例</param>
        /// <param name="analyseResult">字段临时解析结构</param>
        /// <param name="container">网络数据容器</param>
        public static GetObjectResultTypes SetInstance(object instance, GetObjectAnalyseResult analyseResult, INetworkDataContainer container)
        {
            GetObjectAnalyseResult analyze = analyseResult;

            //热处理判断
            if (analyze.HasCacheFinished)
            {
                return(analyze.CacheProcess(instance, analyseResult, container));
            }

            #region 普通类型判断

            IThriftTypeProcessor intellectTypeProcessor = ThriftTypeProcessorMapping.Instance.GetProcessor(analyze.Property.PropertyType);
            if (intellectTypeProcessor != null)
            {
                //添加热缓存
                IThriftTypeProcessor processor = intellectTypeProcessor;
                analyze.CacheProcess     = processor.Process;
                analyze.HasEnoughData    = processor.HasEnoughData;
                analyze.HasCacheFinished = true;
                return(analyze.CacheProcess(instance, analyseResult, container));
            }

            #endregion

            #region 枚举类型判断

            //枚举类型
            if (analyze.Property.PropertyType.IsEnum)
            {
                Type enumType = Enum.GetUnderlyingType(analyze.Property.PropertyType);
                intellectTypeProcessor = ThriftTypeProcessorMapping.Instance.GetProcessor(enumType);
                if (intellectTypeProcessor == null)
                {
                    throw new Exception("Cannot support this enum type! #type: " + analyze.Property.PropertyType);
                }
                //添加热处理
                IThriftTypeProcessor processor = intellectTypeProcessor;
                analyze.CacheProcess     = processor.Process;
                analyze.HasEnoughData    = processor.HasEnoughData;
                analyze.HasCacheFinished = true;
                return(analyze.CacheProcess(instance, analyseResult, container));
            }

            #endregion

            #region 可空类型判断

            Type innerType;
            if ((innerType = Nullable.GetUnderlyingType(analyze.Property.PropertyType)) != null)
            {
                intellectTypeProcessor = ThriftTypeProcessorMapping.Instance.GetProcessor(innerType);
                if (intellectTypeProcessor != null)
                {
                    //添加热缓存
                    IThriftTypeProcessor processor = intellectTypeProcessor;
                    analyze.CacheProcess     = processor.Process;
                    analyze.HasEnoughData    = processor.HasEnoughData;
                    analyze.HasCacheFinished = true;
                    return(analyze.CacheProcess(instance, analyseResult, container));
                }
                throw new Exception("Cannot find compatible processor, #type: " + analyze.Property.PropertyType);
            }

            #endregion

            #region Thrift类型的判断

            //Thrift对象的判断
            if (analyze.Property.PropertyType.IsClass && analyze.Property.PropertyType.GetInterface(Consts.ThriftObjectFullName) != null)
            {
                //添加热缓存
                analyze.CacheProcess = delegate(object innerInstance, GetObjectAnalyseResult innerAnalyseResult, INetworkDataContainer innerContainer)
                {
                    GetObjectResultTypes r;
                    ThriftObject         tobj;
                    if ((r = ThriftObjectEngine.TryGetObject(innerAnalyseResult.Property.PropertyType, innerContainer, out tobj, true)) != GetObjectResultTypes.Succeed)
                    {
                        return(r);
                    }
                    innerAnalyseResult.SetValue(innerInstance, tobj);
                    return(GetObjectResultTypes.Succeed);
                };
                analyze.HasCacheFinished = true;
                return(analyze.CacheProcess(instance, analyseResult, container));;
            }

            #endregion

            #region 数组的判断

            if (analyze.Property.PropertyType.IsArray)
            {
                Type elementType = analyze.Property.PropertyType.GetElementType();
                intellectTypeProcessor = ArrayTypeProcessorMapping.Instance.GetProcessor(analyze.Property.PropertyType);
                if (intellectTypeProcessor != null)
                {
                    //添加热缓存
                    IThriftTypeProcessor processor = intellectTypeProcessor;
                    analyze.HasEnoughData    = processor.HasEnoughData;
                    analyze.CacheProcess     = processor.Process;
                    analyze.HasCacheFinished = true;
                    return(analyze.CacheProcess(instance, analyseResult, container));
                }
                if (elementType.IsSubclassOf(typeof(ThriftObject)))
                {
                    #region IntellectObject type array processor.

                    //add HOT cache.
                    analyze.CacheProcess = delegate(object innerInstance, GetObjectAnalyseResult innerAnalyseResult, INetworkDataContainer innerContainer)
                    {
                        if (!innerContainer.CheckEnoughSize(5))
                        {
                            return(GetObjectResultTypes.NotEnoughData);
                        }
                        byte tmpData;
                        int  arrLen;
                        if (!innerContainer.TryReadByte(out tmpData))
                        {
                            return(GetObjectResultTypes.NotEnoughData);
                        }
                        PropertyTypes arrElementType = (PropertyTypes)tmpData;
                        if (!innerContainer.TryReadInt32(out arrLen))
                        {
                            return(GetObjectResultTypes.NotEnoughData);
                        }
                        arrLen = arrLen.ToLittleEndian();
                        Func <int, ThriftObject[]> func  = ThriftObjectArrayHelper.GetFunc <ThriftObject>(analyze.Property.PropertyType);
                        ThriftObject[]             array = func(arrLen);
                        for (int i = 0; i < arrLen; i++)
                        {
                            GetObjectResultTypes r;
                            ThriftObject         tobj;
                            if ((r = ThriftObjectEngine.TryGetObject(innerAnalyseResult.Property.PropertyType.GetElementType(), innerContainer, out tobj, true)) != GetObjectResultTypes.Succeed)
                            {
                                return(r);
                            }
                            array[i] = tobj;
                        }
                        innerAnalyseResult.SetValue(innerInstance, array);
                        return(GetObjectResultTypes.Succeed);
                    };

                    #endregion
                }
                else
                {
                    throw new NotSupportedException(string.Format(ExceptionMessage.EX_NOT_SUPPORTED_VALUE, analyseResult.Attribute.Id, analyseResult.Property.Name, analyseResult.Property.PropertyType));
                }
                analyze.HasCacheFinished = true;
                return(analyze.CacheProcess(instance, analyseResult, container));
            }

            #endregion

            throw new Exception("Cannot support this data type: " + analyze.Property.PropertyType);
        }