/// <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);
             }
         }
     }
 }
示例#2
0
        /// <summary>
        ///     将一个元数据转换为特定类型的对象
        /// </summary>
        /// <typeparam name="T">对象类型</typeparam>
        /// <param name="target">特定的对象</param>
        /// <param name="container">网络数据容器</param>
        /// <param name="value">如果解析成功, 则此字段为解析成功后的值</param>
        /// <param name="isInnerObject">
        ///     是否为内部对象
        ///     <para>* 如果此值被设置为false(默认值), 则会对当前类型尝试解析MessageIdentity字段</para>
        /// </param>
        /// <returns>返回一个解析后的状态</returns>
        /// <exception cref="ArgumentNullException">参数不能为空</exception>
        /// <exception cref="Exception">转换失败</exception>
        public static GetObjectResultTypes TryGetObject <T>(Type target, INetworkDataContainer container, out T value, bool isInnerObject = false)
        {
            value = default(T);
            if (target == null)
            {
                throw new ArgumentNullException("target");
            }
            if (container == null)
            {
                throw new ArgumentNullException("container");
            }
            Dictionary <short, GetObjectAnalyseResult> result = Analyser.GetObjectAnalyser.Analyse(target);

            if (result == null)
            {
                return(GetObjectResultTypes.UnknownObjectType);
            }
            GetObjectResultTypes tmpFieldParsingResult;
            //create instance for new obj.
            Object       instance     = Activator.CreateInstance(target);
            ThriftObject thriftObject = instance as ThriftObject;

            if (thriftObject == null)
            {
                throw new Exception("Cannot convert target object to Intellect Object! #type: " + target.FullName);
            }

            #region Data Parsing.

            GetObjectAnalyseResult analyzeResult;
            if (!isInnerObject)
            {
                #region Message Identity.

                if (!result.TryGetValue(-1, out analyzeResult))
                {
                    throw new Exception("#Lost Thrift protocol object processor which it can handles type of MessageIdentity");
                }
                if (analyzeResult.HasCacheFinished)
                {
                    if ((tmpFieldParsingResult = analyzeResult.CacheProcess(instance, analyzeResult, container)) != GetObjectResultTypes.Succeed)
                    {
                        container.ResetOffset();
                        return(tmpFieldParsingResult);
                    }
                }
                else
                {
                    IThriftTypeProcessor processor = ThriftTypeProcessorMapping.Instance.GetProcessor(analyzeResult.Property.PropertyType);
                    if (processor == null)
                    {
                        throw new Exception("#Lost Thrift protocol object processor which it can handles type of MessageIdentity");
                    }
                    analyzeResult.CacheProcess     = processor.Process;
                    analyzeResult.HasEnoughData    = processor.HasEnoughData;
                    analyzeResult.HasCacheFinished = true;
                    if ((tmpFieldParsingResult = analyzeResult.CacheProcess(instance, analyzeResult, container)) != GetObjectResultTypes.Succeed)
                    {
                        container.ResetOffset();
                        return(tmpFieldParsingResult);
                    }
                }

                #endregion
            }

            while (true)
            {
                byte pType;
                //get property type.
                if (!container.TryReadByte(out pType))
                {
                    container.ResetOffset();
                    return(GetObjectResultTypes.NotEnoughData);
                }
                PropertyTypes propertyType = (PropertyTypes)pType;
                //succeed parsing binary data to a Thrift protocol object by finding Thrift protocol's STOP flag.
                if (propertyType == PropertyTypes.Stop)
                {
                    value = (T)instance;
                    return(GetObjectResultTypes.Succeed);
                }
                //get id.
                short id;
                if (!container.TryReadInt16(out id))
                {
                    container.ResetOffset();
                    return(GetObjectResultTypes.NotEnoughData);
                }
                id = id.ToLittleEndian();
                //get analyze result.
                if (!result.TryGetValue(id, out analyzeResult))
                {
                    throw new Exception(string.Format("Illegal data contract, non-exists id! #id: {0} \r\n#Formatted MSG info: {1}, data: \r\n{2}", id, instance, container.Dump()));
                }
                //set current property value to the target object.
                if ((tmpFieldParsingResult = InstanceHelper.SetInstance(thriftObject, analyzeResult, container)) != GetObjectResultTypes.Succeed)
                {
                    container.ResetOffset();
                    return(tmpFieldParsingResult);
                }
            }

            #endregion
        }