/// <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); }
/// <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); } } } }
/// <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); }