/// <summary> /// 校验URI中的字符是否合法,此处仅编写了整数方法部分,其余省略 /// </summary> /// <param name="c">字符</param> /// <param name="method">方法,从编码表或分区表中获取</param> /// <returns>合法返回true,不合法返回false</returns> private bool VerifyChar(char c, string method) { if (method == "Integer" || method == "Integer_max" | method == "NumericString" || method == "FixedWidthInteger") { if (Char.IsDigit(c)) { return(true); } } else if (method == "Set82" || method == "Set82_max") { if (Symbols.GetSet82HexValue(c) != 0) { return(true); } } else if (method == "Set39_max") { if (Symbols.GetSet39HexValue(c) != 0) { return(true); } } else if (method == "CAGEorDoDAAC") { if (c == '#' || c == '-' || c == '/') { return(false); } if (Symbols.GetSet39HexValue(c) != 0) { return(true); } } return(false); }
/// <summary> /// 获取Pure Identity URI的Tag URI以及二进制编码。在调用此方法前,必须首先 /// 调用SetURI方法以设置Pure Identity URI,并确保SetURI方法调用成功。 /// </summary> /// <param name="filter">将使用的过滤值</param> /// <param name="tagScheme">将使用的二进制编码方案</param> /// <param name="tagURI">得到的Tag URI</param> /// <param name="binEncoding">得到的二进制编码</param> /// <returns>成功返回null,错误则返回出错信息</returns> public string GetTagURIAndBinEncoding(byte filter, string tagScheme, ref string tagURI, ref string binEncoding) { bool lenVariable = false; //查找编码表的所有段 var queryTagScheme = xDocCodingTable.Descendants("TagScheme") .Where(item => item.Attribute("name").Value == tagScheme) .FirstOrDefault(); var segmentList = queryTagScheme.Elements(); //包含每个段结点信息的列表 int totalBit = int.Parse(queryTagScheme.Attribute("len").Value); BitArr result = new BitArr(totalBit); //按总长度创建字节数组 //遍历每一个段,将其转化为二进制编码 index = schemeIndex; foreach (var segment in segmentList) { //首部、过滤值和分区表单独处理 if (segment.Name == "Header")//处理首部 { result.Append(byte.Parse(segment.Value), int.Parse(segment.Attributes("len").FirstOrDefault().Value)); } else if (segment.Name == "Filter") //处理过滤值 { result.Append(filter, int.Parse(segment.Attributes("len").FirstOrDefault().Value)); } else if (segment.Name == "Partition")//处理分区表 { //首先确定分区表名称 string partitionName = segment.Attributes("tableName") .FirstOrDefault().Value; //找到相应分区表 var queryPartition = xDocPartitionTable.Descendants("Partition") .Where(item => item.Attribute("name").Value == partitionName); string part1Name = queryPartition.Attributes("part1Name") .FirstOrDefault().Value; string part1Method = queryPartition.Attributes("col2Method") .FirstOrDefault().Value; //获取URI中的属性分区表Part1的部分 string part1 = GetNextSegmentInUri(part1Method); if (part1 == null) { return(part1Name + "使用了不合法的字符"); } int part1Len = part1.Length; //根据Part1的编码字符个数查找分区表中的相应行 var row = queryPartition.Elements("Row") .Where(item => item.Attribute("col2").Value == part1Len.ToString()) .Select(item => new { val = item.Attribute("value").Value, part1BitLen = item.Attribute("col1").Value, part2BitLen = item.Attribute("col3").Value, part2Len = item.Attribute("col4").Value }).FirstOrDefault(); if (row == null) { return(part1Name + "使用的字符个数不在分区表指定范围内"); } //加入分区值 result.Append(byte.Parse(row.val), 3); //加入分区表第一部分编码 int part1BitLen = int.Parse(row.part1BitLen); byte[] part1Raw = Encode(part1, part1BitLen, part1Method); if (part1Raw == null) { return("Part1编码失败"); } result.AppendTrimLeft(part1Raw, part1BitLen); //获取分区表第二部分指定字符个数 int part2Len = int.Parse(row.part2Len); //查找分区表的Part2信息 string part2Name = queryPartition.Attributes("part2Name") .FirstOrDefault().Value; string part2Method = queryPartition.Attributes("col4Method") .FirstOrDefault().Value; //获取URI中的属性分区表Part2的部分 string part2 = GetNextSegmentInUri(part2Method); if (part2 == null) { return(part2Name + "使用了不合法的字符"); } //固定长度分区表列(列名不带“Max”)的合法性判断 if (!VerifyLength(part2, part2Len, part2Method)) { return(part2Name + "使用的字符个数不在分区表指定范围内"); } //加入分区表第二部分编码 int part2BitLen = int.Parse(row.part2BitLen); byte[] part2Raw = Encode(part2, part2BitLen, part2Method); if (part2Raw == null) { return("Part2编码失败"); } if (part2Method == "Set82_max") { result.AppendTrimRight(part2Raw, part2BitLen); } else if (part2Method == "Set39_max") { lenVariable = true; result.AppendTrimRight(part2Raw, Symbols.CalcActualLength(part2) * 6 + 6); } else { result.AppendTrimLeft(part2Raw, part2BitLen); } } else //其他段共用以下处理方法 { int len = int.Parse(segment.Attributes("len") .FirstOrDefault().Value); string method = segment.Attributes("method").FirstOrDefault().Value; string name = segment.Attributes("name").FirstOrDefault().Value; string segmentInUri = GetNextSegmentInUri(method); if (segmentInUri == null) { return(name + "使用了不合法的字符"); } else { byte[] raw = Encode(segmentInUri, len, method); if (method == "Integer" || method == "NumericString" || method == "FixedWidthInteger") { result.AppendTrimLeft(raw, len); } else if (method == "Set82" || method == "CAGEorDoDAAC") { result.AppendTrimRight(raw, len); } else if (method == "Set39_max") { lenVariable = true; result.AppendTrimRight(raw, Symbols.CalcActualLength(segmentInUri) * 6 + 6); } } } } if (lenVariable) { result.Trim(); } binEncoding = result.ToString(); return(null); }
public string Decode(ref string pureURI) { if (code == null) { return(null); } long header = code.SubBitToInteger(0, 8); var queryTagScheme = xDocCodingTable.Descendants("TagScheme") .Where(item => item.Element("Header").Value == header.ToString()) .FirstOrDefault(); if (queryTagScheme == null) { return("首部值不存在"); } StringBuilder result = new StringBuilder(); int index = 8; foreach (var segment in queryTagScheme.Elements()) { if (segment.Name.ToString() == "Header")//首部 { result.Append(queryTagScheme.Parent.Attribute("uri").Value); TagScheme = queryTagScheme.Attribute("name").Value; } else if (segment.Name.ToString() == "Filter")//过滤值 { int len = int.Parse(queryTagScheme.Element("Filter") .Attribute("len").Value); long filter = code.SubBitToInteger(index, len); if (filter == -1) { return("过滤值解码错误"); } index += len; Filter = (int)filter; } else if (segment.Name.ToString() == "Partition") { //首先查找分区表名称 string partitionName = segment.Attribute("tableName").Value; //找到相应的分区表 var queryPartition = xDocPartitionTable.Descendants("Partition") .Where(item => item.Attribute("name").Value == partitionName); //首先获取分区值 long partVal = code.SubBitToInteger(index, 3); if (partVal == -1) { return("分区值解码错误"); } index += 3; //查找匹配分区表行 var row = queryPartition.Descendants("Row") .Where(item => item.Attribute("value").Value == partVal.ToString()) .Select(item => new { part1BitLen = item.Attribute("col1").Value, part1Len = item.Attribute("col2").Value, part2BitLen = item.Attribute("col3").Value, part2Len = item.Attribute("col4").Value }).FirstOrDefault(); //解码分区表第一部分 string part1Name = queryPartition.Attributes("part1Name").FirstOrDefault().Value; string part1Method = queryPartition.Attributes("col2Method").FirstOrDefault().Value; int len = int.Parse(row.part1BitLen); int part1Len = int.Parse(row.part1Len); string part1 = DecodeSegment(index, len, part1Len, part1Method); if (part1 == null) { return(part1Name + "段解码失败"); } index += len; result.Append(part1); //解码分区表第二部分 string part2Name = queryPartition.Attributes("part2Name").FirstOrDefault().Value; string part2Method = queryPartition.Attributes("col4Method").FirstOrDefault().Value; len = int.Parse(row.part2BitLen); int part2Len = int.Parse(row.part2Len); string part2 = DecodeSegment(index, len, part2Len, part2Method); if (part2 == null) { return(part2Name + "段解码失败"); } if (part2Method == "Set39_max") { index += Symbols.CalcActualLength(part2) * 6 + 6; } else { index += len; } result.Append('.'); result.Append(part2); } else //其它逻辑段的解码 { int len = int.Parse(segment.Attribute("len").Value); string method = segment.Attribute("method").Value; string name = segment.Attribute("name").Value; string other = DecodeSegment(index, len, -1, method); if (other == null) { return("逻辑段:" + name + "解码错误"); } if (method == "Set39_max") { index += Symbols.CalcActualLength(other) * 6 + 6; } else { index += len; } if (other == "") { continue; } result.Append('.'); result.Append(other); } } pureURI = result.ToString(); return(null); }
/// <summary> /// 解码逻辑段 /// </summary> /// <param name="begin">逻辑段在位流中的开始位置</param> /// <param name="bitLen">逻辑段位长度</param> /// <param name="strLen">结果长度</param> /// <param name="method">解码方法</param> /// <returns>成功返回解码后的字符串,失败返回null</returns> private string DecodeSegment(int begin, int bitLen, int strLen, string method) { if (method == "Integer") { string result = code.SubBitToInteger(begin, bitLen).ToString(); if (result.Length < strLen) { result = result.PadLeft(strLen, '0'); } return(result); } else if (method == "Set82" || method == "Set82_max") { StringBuilder sb = new StringBuilder(20); int end = begin + bitLen; while (begin < end) { byte hexValue = code.SubBitToByte(begin, 7); if (hexValue != 0) { sb.Append(Symbols.GetSet82URIForm(hexValue)); } begin += 7; } return(sb.ToString()); } else if (method == "Set39_max") { StringBuilder sb = new StringBuilder(20); int end = begin + bitLen; while (begin < end) { byte hexValue = code.SubBitToByte(begin, 6); if (hexValue == 0) { break; } sb.Append(Symbols.GetSet39URIForm(hexValue)); begin += 6; } return(sb.ToString()); } else if (method == "FillZero") { return(""); } else if (method == "Integer_max") { string result = code.SubBitToInteger(begin, bitLen).ToString(); if (result.Length > strLen) { return(null); } return(result); } else if (method == "NumericString") { string result = code.SubBitToInteger(begin, bitLen).ToString(); if (result[0] != '1') { return(null); } return(result.Remove(0, 1)); } else if (method == "CAGEorDoDAAC") { StringBuilder sb = new StringBuilder(6); int end = begin + bitLen; while (begin < end) { byte hexValue = code.SubBitToByte(begin, 6); if (hexValue == 0) { break; } if (hexValue != 32) { sb.Append(Symbols.GetSet39URIForm(hexValue)); } begin += 6; } return(sb.ToString()); } else if (method == "FixedWidthInteger") { //首先计算字符串长度 int D = (int)(bitLen * Math.Log(2) / Math.Log(10)); //数字位数 string result = code.SubBitToInteger(begin, bitLen).ToString(); if (result.Length < D) { result = result.PadLeft(D, '0'); } return(result); } return(null); }