private Object ParseTlv(Type propType, TlvConfig cfg, String tagName, int lengthBytes, Type tlvType, byte[] bytesValue, String locMsg, bool isAlwaysOneTag, ref int tlvLength) { int tagLength = (cfg != null && cfg.TagsCount > 0) ? cfg.GetTag(0).Name.Length : (tagName.Length > 0 ? tagName.Length : 2); if (cfg != null && cfg.LengthBytes > 0) { lengthBytes = cfg.LengthBytes; } if (cfg != null && cfg.ClassType != null) { tlvType = cfg.ClassType; } IDictionary <String, Object> tagValMap = new Dictionary <String, Object>(); int i = 0; byte[] bytes; while (i < bytesValue.Length) { CheckTlvToken(i, tagLength, bytesValue, locMsg); bytes = new byte[tagLength]; Array.Copy(bytesValue, i, bytes, 0, tagLength); i += tagLength; String tag = MessageUtility.AsciiArrayToString(bytes); if (tag == null) { throw new MessageParserException("Invalid tag value for a tlv field. Check configuration " + locMsg); } CheckTlvToken(i, lengthBytes, bytesValue, locMsg); bytes = new byte[lengthBytes]; Array.Copy(bytesValue, i, bytes, 0, lengthBytes); i += lengthBytes; int len = MessageUtility.AsciiArrayToInt(bytes); if (len < 0) { throw new MessageParserException("Invalid length value for a tlv field. Check configuration " + locMsg); } if (len > 0) { CheckTlvToken(i, len, bytesValue, locMsg); bytes = new byte[len]; Array.Copy(bytesValue, i, bytes, 0, len); i += len; TlvTagConfig tagCfg = cfg != null?cfg.GetTag(tag) : null; if (tagCfg != null && tagCfg.BitContent != null) { tagValMap[tag] = ParseBitContent(tagCfg.BitContent, bytes); } else { String value = System.Text.Encoding.ASCII.GetString(bytes); if (tagCfg != null && tagCfg.Splitter != null) { tagValMap[tag] = value.Split(new String[] { tagCfg.Splitter }, StringSplitOptions.None); } else { tagValMap[tag] = value; } } } if (isAlwaysOneTag) { break; } } tlvLength = i; if (tagValMap.Count <= 0) { return(null); } String convertFailedMsg = "Cannot convert a tlv field into the mapped property. Check " + locMsg; if (tlvType != null && propType.IsAssignableFrom(tlvType)) { Object propValue = Activator.CreateInstance(tlvType); foreach (KeyValuePair <String, Object> kvp in tagValMap) { PropertyInfo property = tlvType.GetProperty(kvp.Key); if (property == null) { throw new MessageParserException(convertFailedMsg); } Object propValue2 = kvp.Value; if (propValue2 != null) { propValue2 = Util.GetAssignableValue(property.PropertyType, kvp.Value); if (propValue2 == null) { throw new MessageParserException(convertFailedMsg); } } property.SetValue(propValue, propValue2, null); } return(propValue); } else { if (tagValMap.Count == 1) { foreach (Object value in tagValMap.Values) { if (value == null) { return(null); } Object val = Util.GetAssignableValue(propType, value); if (val != null) { return(val); } } } if (!propType.IsAssignableFrom(tagValMap.GetType())) { Object propValue = Activator.CreateInstance(propType); foreach (KeyValuePair <String, Object> kvp in tagValMap) { PropertyInfo property = propType.GetProperty(kvp.Key); if (property == null) { throw new MessageParserException(convertFailedMsg); } Object propValue2 = kvp.Value; if (propValue2 != null) { propValue2 = Util.GetAssignableValue(property.PropertyType, kvp.Value); if (propValue2 == null) { throw new MessageParserException(convertFailedMsg); } } property.SetValue(propValue, propValue2, null); } return(propValue); } } return(tagValMap); }
private byte[] CompileTlv(TlvConfig cfg, String tagName, int lengthBytes, Object obj, String locMsg) { int tagLength = (cfg != null && cfg.TagsCount > 0) ? cfg.GetTag(0).Name.Length : (tagName.Length > 0 ? tagName.Length : 2); if (cfg != null && cfg.LengthBytes > 0) { lengthBytes = cfg.LengthBytes; } if (String.IsNullOrEmpty(tagName) && (cfg == null || cfg.TagsCount <= 0)) { throw new MessageCompilerException( "Cannot compile a tlv field. It cannot determine the tag ID. Check configuration " + locMsg); } IList <TlvTagConfig> tagCfgs = null; if (cfg != null) { tagCfgs = cfg.Tags; } if (tagCfgs == null) { tagCfgs = new List <TlvTagConfig>(); } if (tagCfgs.Count <= 0) { TlvTagConfig tagCfg = new TlvTagConfig(); tagCfg.Name = tagName; tagCfgs.Add(tagCfg); } IDictionary <String, Object> tagMapVal = new Dictionary <String, Object>(); if (obj is IDictionary <String, Object> ) { IDictionary <String, Object> map = (IDictionary <String, Object>)obj; foreach (TlvTagConfig tagCfg in tagCfgs) { if (map.ContainsKey(tagCfg.Name)) { tagMapVal[tagCfg.Name] = map[tagCfg.Name]; } } } else if (obj != null) { foreach (TlvTagConfig tagCfg in tagCfgs) { PropertyInfo property = obj.GetType().GetProperty(tagCfg.Name); if (property != null) { tagMapVal[tagCfg.Name] = property.GetValue(obj, null); } } } if (tagMapVal.Count <= 0 && tagCfgs.Count == 1) { tagMapVal[tagCfgs[0].Name] = obj; } StringBuilder sb = new StringBuilder(); foreach (TlvTagConfig tagCfg in tagCfgs) { sb.Append(tagCfg.Name); String len = "0"; String strVal = ""; if (tagMapVal.ContainsKey(tagCfg.Name) && tagMapVal[tagCfg.Name] != null) { Object value = tagMapVal[tagCfg.Name]; if (tagCfg.Splitter != null) { if (value is IEnumerable <Object> ) { strVal = Util.Join((IEnumerable <Object>)value, tagCfg.Splitter); } else { throw new MessageCompilerException( "Cannot compile a tlv field. The passed value is not an array. Check configuration " + locMsg + " for tag " + tagCfg.Name); } } else if (tagCfg.BitContent != null) { byte[] val = CompileBitContent(tagCfg.BitContent, value); strVal = System.Text.Encoding.ASCII.GetString(val); } else { strVal = value.ToString(); } } len = strVal.Length.ToString(); if (len.Length > lengthBytes) { throw new MessageCompilerException( "Cannot compile a tlv field. The length's value is too big more than " + lengthBytes + " digits. Check configuration " + locMsg + " for tag " + tagCfg.Name); } else if (len.Length < lengthBytes) { len = len.PadLeft(lengthBytes, '0'); } sb.Append(len); sb.Append(strVal); } return(MessageUtility.StringToAsciiArray(sb.ToString())); }