// 解码Present请求包 public static int Decode_PresentRequest( BerNode root, out PresentRequestInfo info, out string strError) { strError = ""; int nRet = 0; info = new PresentRequestInfo(); Debug.Assert(root != null, ""); if (root.m_uTag != BerTree.z3950_presentRequest) { strError = "root tag is not z3950_presentRequest"; return -1; } for (int i = 0; i < root.ChildrenCollection.Count; i++) { BerNode node = root.ChildrenCollection[i]; switch (node.m_uTag) { case BerTree.z3950_ReferenceId: // 2 info.m_strReferenceId = node.GetCharNodeData(); break; case BerTree.z3950_ResultSetId: // 31 resultSetId (IntenationalString) info.m_strResultSetID = node.GetCharNodeData(); break; case BerTree.z3950_resultSetStartPoint: // 30 resultSetStartPoint (Integer) info.m_lResultSetStartPoint = node.GetIntegerNodeData(); break; case BerTree.z3950_numberOfRecordsRequested: // 29 numberOfRecordsRequested (Integer) info.m_lNumberOfRecordsRequested = node.GetIntegerNodeData(); break; case BerTree.z3950_ElementSetNames: // 19 ElementSetNames (complicates) { List<string> elementset_names = null; nRet = DecodeElementSetNames(node, out elementset_names, out strError); if (nRet == -1) return -1; info.m_elementSetNames = elementset_names; } break; default: break; } } return 0; }
// 解码Initial请求包 public static int Decode_InitRequest( BerNode root, out InitRequestInfo info, out string strDebugInfo, out string strError) { strError = ""; strDebugInfo = ""; info = new InitRequestInfo(); Debug.Assert(root != null, ""); if (root.m_uTag != BerTree.z3950_initRequest) { strError = "root tag is not z3950_initRequest"; return -1; } for (int i = 0; i < root.ChildrenCollection.Count; i++) { BerNode node = root.ChildrenCollection[i]; switch (node.m_uTag) { case BerTree.z3950_ReferenceId: info.m_strReferenceId = node.GetCharNodeData(); strDebugInfo += "ReferenceID='" + node.GetCharNodeData() + "'\r\n"; break; case BerTree.z3950_ProtocolVersion: info.m_strProtocolVersion = node.GetBitstringNodeData(); strDebugInfo += "ProtocolVersion='" + node.GetBitstringNodeData() + "'\r\n"; break; case BerTree.z3950_Options: info.m_strOptions = node.GetBitstringNodeData(); strDebugInfo += "Options='" + node.GetBitstringNodeData() + "'\r\n"; break; case BerTree.z3950_PreferredMessageSize: info.m_lPreferredMessageSize = node.GetIntegerNodeData(); strDebugInfo += "PreferredMessageSize='" + node.GetIntegerNodeData() + "'\r\n"; break; case BerTree.z3950_ExceptionalRecordSize: info.m_lExceptionalRecordSize = node.GetIntegerNodeData(); strDebugInfo += "ExceptionalRecordSize='" + node.GetIntegerNodeData() + "'\r\n"; break; case BerTree.z3950_idAuthentication: { string strGroupId = ""; string strUserId = ""; string strPassword = ""; int nAuthentType = 0; int nRet = DecodeAuthentication( node, out strGroupId, out strUserId, out strPassword, out nAuthentType, out strError); if (nRet == -1) return -1; info.m_nAuthenticationMethod = nAuthentType; // 0: open 1:idPass info.m_strGroupID = strGroupId; info.m_strID = strUserId; info.m_strPassword = strPassword; strDebugInfo += "idAuthentication struct occur\r\n"; } break; case BerTree.z3950_ImplementationId: info.m_strImplementationId = node.GetCharNodeData(); strDebugInfo += "ImplementationId='" + node.GetCharNodeData() + "'\r\n"; break; case BerTree.z3950_ImplementationName: info.m_strImplementationName = node.GetCharNodeData(); strDebugInfo += "ImplementationName='" + node.GetCharNodeData() + "'\r\n"; break; case BerTree.z3950_ImplementationVersion: info.m_strImplementationVersion = node.GetCharNodeData(); strDebugInfo += "ImplementationVersion='" + node.GetCharNodeData() + "'\r\n"; break; case BerTree.z3950_OtherInformationField: info.m_charNego = new CharsetNeogatiation(); info.m_charNego.DecodeProposal(node); break; default: strDebugInfo += "Undefined tag = [" + node.m_uTag.ToString() + "]\r\n"; break; } } return 0; }
// 解码Search请求包 public static int Decode_SearchRequest( BerNode root, out SearchRequestInfo info, out string strError) { strError = ""; int nRet = 0; info = new SearchRequestInfo(); Debug.Assert(root != null, ""); if (root.m_uTag != BerTree.z3950_searchRequest) { strError = "root tag is not z3950_searchRequest"; return -1; } for (int i = 0; i < root.ChildrenCollection.Count; i++) { BerNode node = root.ChildrenCollection[i]; switch (node.m_uTag) { case BerTree.z3950_ReferenceId: // 2 info.m_strReferenceId = node.GetCharNodeData(); break; case BerTree.z3950_smallSetUpperBound: // 13 smallSetUpperBound (Integer) info.m_lSmallSetUpperBound = node.GetIntegerNodeData(); break; case BerTree.z3950_largeSetLowerBound: // 14 largeSetLowerBound (Integer) info.m_lLargeSetLowerBound = node.GetIntegerNodeData(); break; case BerTree.z3950_mediumSetPresentNumber: // 15 mediumSetPresentNumber (Integer) info.m_lMediumSetPresentNumber = node.GetIntegerNodeData(); break; case BerTree.z3950_replaceIndicator: // 16 replaceIndicator, (boolean) info.m_lReplaceIndicator = node.GetIntegerNodeData(); break; case BerTree.z3950_resultSetName: // 17 resultSetName (string) info.m_strResultSetName = node.GetCharNodeData(); break; case BerTree.z3950_databaseNames: // 18 dbNames (sequence) /* // sequence is constructed, // have child with case = 105, (string) m_saDBName.RemoveAll(); DecodeDBName(pNode, m_saDBName, m_bIsCharSetUTF8); * */ { List<string> dbnames = null; nRet = DecodeDbnames(node, out dbnames, out strError); if (nRet == -1) return -1; info.m_dbnames = dbnames; } break; case BerTree.z3950_query: // 21 query (query) // DecodeSearchQuery(pNode, m_strSQLWhere, pRPNStructureRoot); { BerNode rpn_root = GetRPNStructureRoot(node, out strError); if (rpn_root == null) return -1; info.m_rpnRoot = rpn_root; } break; default: break; } } return 0; }
// // 在此结点下增加一棵子树 // parameters: public void AddSubtree(BerNode sub) { this.ChildrenCollection.Add(sub); sub.ParentNode = this; }
public void DumpToFile(Stream stream) { int i; string strIndent = ""; BerNode obj = null; int nMax; obj = this; while (true) { if (obj.ParentNode == null) { break; } strIndent += " "; obj = obj.ParentNode; } string strText = ""; if (this.ParentNode != null) { strText += strIndent + "{\r\n"; strText += strIndent + "tag=[" + this.m_uTag.ToString() + "] " + "class=[" + ((int)this.m_cClass).ToString() + "] " + "form=[" + ((int)this.m_cForm).ToString() + "]\r\n"; if (this.m_baData != null) { strText += strIndent + "datalen=[" + this.m_baData.Length.ToString() + "] " + "content[" + ByteArrayToDispString(this.m_baData) + "]\r\n"; } else { strText += strIndent + "datalen=0\r\n"; } if (this.m_strDebugInfo != "") { strText += "debuginfo[" + this.m_strDebugInfo + "]\r\n"; } } nMax = this.ChildrenCollection.Count; strText += strIndent + "childrencount=[" + nMax.ToString() + "]\r\n"; byte[] baText = Encoding.UTF8.GetBytes(strText); stream.Write(baText, 0, baText.Length); for (i = 0; i < nMax; i++) { obj = this.ChildrenCollection[i]; obj.DumpToFile(stream); } strText = strIndent + "}\r\n"; baText = Encoding.UTF8.GetBytes(strText); stream.Write(baText, 0, baText.Length); }
// 在当前结点下方构造一个存放字符数据的子结点 // parameters: // return: // null // 其他 public BerNode NewChildCharNode(UInt16 uTag, char cClass, byte [] baData) { BerNode node = null; if (this.m_cForm==ASN1_PRIMITIVE) return null; node = new BerNode(); node.ParentNode = this; this.ChildrenCollection.Add(node); node.m_baData = baData; node.m_uTag = uTag; node.m_cClass = cClass; node.m_cForm = ASN1_PRIMITIVE; return node; }
// 在当前结点下方构造一个存放整型数据的子结点 // parameters: // return: // null // 其他 public BerNode NewChildIntegerNode(UInt16 uTag, char cClass, byte[] baData) { if (this.m_cForm == ASN1_PRIMITIVE) return null; BerNode node = null; int nLen; List<byte> charray = new List<byte>(); node = new BerNode(); node.ParentNode = this; this.ChildrenCollection.Add(node); nLen = baData.Length; charray.AddRange(baData); ChangeIntegerOrder(ref charray); if (charray[0] == 0) { while ((charray.Count > 1) && (charray[0] == 0) && (charray[1] < 128)) charray.RemoveAt(0); } else { if (charray[0] == 0xff) while ((charray.Count > 1) && (charray[0] == 0xff) && (charray[1] > 127)) charray.RemoveAt(0); } node.m_baData = new byte[charray.Count]; charray.CopyTo(node.m_baData); node.m_uTag = uTag; node.m_cClass = cClass; node.m_cForm = ASN1_PRIMITIVE; return node; }
// 解析出search请求中的 数据库名列表 static int DecodeDbnames(BerNode root, out List<string> dbnames, out string strError) { dbnames = new List<string>(); strError = ""; for (int i = 0; i < root.ChildrenCollection.Count; i++) { BerNode node = root.ChildrenCollection[i]; if (node.m_uTag == 105) { dbnames.Add(node.GetCharNodeData()); } } return 0; }
// 解析出init请求中的 鉴别信息 // parameters: // nAuthentType 0: open(simple) 1:idPass(group) static int DecodeAuthentication( BerNode root, out string strGroupId, out string strUserId, out string strPassword, out int nAuthentType, out string strError) { strGroupId = ""; strUserId = ""; strPassword = ""; nAuthentType = 0; strError = ""; if (root == null) { strError = "root == null"; return -1; } string strOpen = ""; // open mode authentication for (int i = 0; i < root.ChildrenCollection.Count; i++) { BerNode node = root.ChildrenCollection[i]; switch (node.m_uTag) { case BerNode.ASN1_SEQUENCE: nAuthentType = 1; // "GROUP"; for (int k = 0; k < node.ChildrenCollection.Count; k++) { BerNode nodek = node.ChildrenCollection[k]; switch (nodek.m_uTag) { case 0: // groupId strGroupId = nodek.GetCharNodeData(); break; case 1: // userId strUserId = nodek.GetCharNodeData(); break; case 2: // password strPassword = nodek.GetCharNodeData(); break; } } break; case BerNode.ASN1_VISIBLESTRING: case BerNode.ASN1_GENERALSTRING: nAuthentType = 0; // "SIMPLE"; strOpen = node.GetCharNodeData(); break; } } if (nAuthentType == 0) { int nRet = strOpen.IndexOf("/"); if (nRet != -1) { strUserId = strOpen.Substring(0, nRet); strPassword = strOpen.Substring(nRet + 1); } else { strUserId = strOpen; } } return 0; }
// 解析出search请求中的 数据库名列表 static int DecodeElementSetNames(BerNode root, out List<string> elementset_names, out string strError) { elementset_names = new List<string>(); strError = ""; for (int i = 0; i < root.ChildrenCollection.Count; i++) { BerNode node = root.ChildrenCollection[i]; /* if (node.m_uTag == 105) { dbnames.Add(node.GetCharNodeData()); } * */ // TODO: 这里需要看一下PDU定义,看看是否需要判断m_uTag elementset_names.Add(node.GetCharNodeData()); } return 0; }
// 获得search请求中的RPN根节点 static BerNode GetRPNStructureRoot(BerNode root, out string strError) { strError = ""; if (root == null) { strError = "query root is null"; return null; } if (root.ChildrenCollection.Count < 1) { strError = "no query item"; return null; } BerNode RPNRoot = root.ChildrenCollection[0]; if (1 != RPNRoot.m_uTag) // type-1 query { strError = "not type-1 query. unsupported query type"; return null; } string strAttributeSetId = ""; //attributeSetId OBJECT IDENTIFIER // string strQuery = ""; for (int i = 0; i < RPNRoot.ChildrenCollection.Count; i++) { BerNode node = RPNRoot.ChildrenCollection[i]; switch (node.m_uTag) { case 6: // attributeSetId (OBJECT IDENTIFIER) strAttributeSetId = node.GetOIDsNodeData(); if (strAttributeSetId != "1.2.840.10003.3.1") // bib-1 { strError = "support bib-1 only"; return null; } break; // RPNStructure (CHOICE 0, 1) case 0: case 1: return node; // this is RPN Stucture root } } strError = "not found"; return null; }
/* void FillChildren(TreeNode topnode, IndexInfo info) { TreeNode newnode = new TreeNode(); topnode.Nodes.Add(newnode); FillNodeAndChildren(newnode, info.BerTree.m_RootNode.ChildrenCollection[0]); } * */ void FillNodeAndChildren(TreeNode topnode, BerNode bernode) { topnode.Text = bernode.GetDebugString(); topnode.Tag = bernode; for (int i = 0; i < bernode.ChildrenCollection.Count; i++) { BerNode berchildnode = bernode.ChildrenCollection[i]; TreeNode newtreenode = new TreeNode(); topnode.Nodes.Add(newtreenode); FillNodeAndChildren(newtreenode, berchildnode); } }
// // 在此节点下增加一棵子树 // parameters: public void AddSubtree(BerNode sub) { this.ChildrenCollection.Add(sub); sub.ParentNode = this; }
// 在当前节点下方构造一个存放OIDs数据的节点 // parameters: // return: // NULL // 其他 public BerNode NewChildOIDsNode(UInt16 uTag, char cClass, string strValue) { if (this.m_cForm == ASN1_PRIMITIVE) { return(null); } BerNode node = null; // List<byte> charray; node = new BerNode(); node.ParentNode = this; this.ChildrenCollection.Add(node); byte[] place = new byte[100]; /* seems like enough */ int offset = 0; long value; int nRet = 0; string strTemp = ""; for (int i = 0; i < strValue.Length;) { /* * if (Char.IsDigit(strValue[i]) == false) * break; * */ if (i > 90) { Debug.Assert(false, ""); return(null); } strTemp = GetNumber(strValue, i); value = Convert.ToInt64(strTemp); if (i == 0) /* first 2 numbers get special treatment */ { nRet = strValue.IndexOf('.', i); if (nRet == -1) { Debug.Assert(false, ""); return(null); } i = nRet + 1; strTemp = GetNumber(strValue, i); value = value * 40 + Convert.ToInt64(strTemp); } if (value >= 0x80) { int count = 0; byte[] bits = new byte[12]; /* Save a 84 (12*7) bit number */ while (value != 0) { bits[count++] = (byte)(value & 0x7F); value >>= 7; } /* Now place in the correct order */ while (--count > 0) { place[offset++] = (byte)(bits[count] | 0x80); } place[offset++] = bits[count]; } else { place[offset++] = (byte)value; } nRet = strValue.IndexOf('.', i); if (nRet != -1) { i = nRet + 1; } else { break; } } node.m_baData = new byte[offset]; Array.Copy(place, node.m_baData, offset); node.m_uTag = uTag; node.m_cClass = cClass; node.m_cForm = ASN1_PRIMITIVE; return(node); }
// 在当前结点下方构造一个constructed结构的非叶子结点 // parameters: // return: // null // 其他 public BerNode NewChildConstructedNode(UInt16 uTag, char cClass) { BerNode node = null; if (this.m_cForm == ASN1_PRIMITIVE) return null; node = new BerNode(); node.ParentNode = this; this.ChildrenCollection.Add(node); node.m_uTag = uTag; node.m_cClass = cClass; node.m_cForm = ASN1_CONSTRUCTED; return node; }
// 解码RPN结构中的Attribute + Term结构 static int DecodeAttributeAndTerm( Encoding term_encoding, BerNode pNode, out long lAttributeType, out long lAttributeValue, out string strTerm, out string strError) { lAttributeType = 0; lAttributeValue = 0; strTerm = ""; strError = ""; if (pNode == null) { strError = "node == null"; return -1; } if (pNode.ChildrenCollection.Count < 2) //attriblist + term { strError = "bad RPN query"; return -1; } BerNode pAttrib = pNode.ChildrenCollection[0]; // attriblist BerNode pTerm = pNode.ChildrenCollection[1]; // term if (44 != pAttrib.m_uTag) // Attributes { strError = "only support Attributes"; return -1; } if (45 != pTerm.m_uTag) // Term { strError = "only support general Term"; return -1; } // get attribute type and value if (pAttrib.ChildrenCollection.Count < 1) //attribelement { strError = "bad RPN query"; return -1; } pAttrib = pAttrib.ChildrenCollection[0]; if (16 != pAttrib.m_uTag) //attribelement (SEQUENCE) { strError = "only support Attributes"; return -1; } for (int i = 0; i < pAttrib.ChildrenCollection.Count; i++) { BerNode pTemp = pAttrib.ChildrenCollection[i]; switch (pTemp.m_uTag) { case 120: // attributeType lAttributeType = pTemp.GetIntegerNodeData(); break; case 121: // attributeValue lAttributeValue = pTemp.GetIntegerNodeData(); break; } } // get term strTerm = pTerm.GetCharNodeData(term_encoding); if (-1 == lAttributeType || -1 == lAttributeValue || String.IsNullOrEmpty(strTerm) == true) { strError = "bad RPN query"; return -1; } return 0; }
// 给结点的m_baData赋值 int GetNodeData(byte [] baPackage, ref int nDelta, ref int nFieldlen) { BerNode node = null; int nSublen; if (m_cForm==ASN1_CONSTRUCTED) { int nMax = nFieldlen; while (nMax>0) { node = new BerNode(); //生成此结点的一个子结点 node.ParentNode = this; this.ChildrenCollection.Add(node); node.BuildTreeNode(baPackage, nDelta, nSublen); nMax -= nSublen; // nDelta += nSublen; TRACE("%d",nDelta); } } else { m_baData = new byte[nFieldlen]; Debug.Assert(baPackage.Length >= nFieldlen, ""); Array.Copy(baPackage, nDelta, this.m_baData, 0, nFieldlen); nDelta += nFieldlen; } return 0; }
static int DecodeRPNOperator(BerNode pNode) { if (pNode == null) return -1; if (46 == pNode.m_uTag) { if (pNode.ChildrenCollection.Count > 0) { return pNode.ChildrenCollection[0].m_uTag; } } return -1; }
// 2007/7/16 public BerNode NewChildBooleanNode(UInt16 uTag, char cClass, bool bData) { BerNode node = null; if (this.m_cForm == ASN1_PRIMITIVE) return null; node = new BerNode(); node.ParentNode = this; this.ChildrenCollection.Add(node); node.m_baData = new byte[1]; if (bData == true) node.m_baData[0] = 1; else node.m_baData[0] = 0; node.m_uTag = uTag; node.m_cClass = cClass; node.m_cForm = ASN1_PRIMITIVE; return node; }
// 根据RPN创建XML检索式 // 本函数要递归调用,检索数据库并返回结果集 // parameters: // node RPN 结构的根结点 // strXml[out] 返回局部XML检索式 // return: // -1 error // 0 succeed int BuildQueryXml( List<string> dbnames, BerNode node, out string strQueryXml, out string strError) { strQueryXml = ""; strError = ""; int nRet = 0; if (node == null) { strError = "node == null"; return -1; } if (0 == node.m_uTag) { // operand node // 检索得到 saRecordID if (node.ChildrenCollection.Count < 1) { strError = "bad RPN structure"; return -1; } BerNode pChild = node.ChildrenCollection[0]; if (102 == pChild.m_uTag) { // AttributesPlusTerm long nAttributeType = -1; long nAttributeValue = -1; string strTerm = ""; nRet = DecodeAttributeAndTerm( this._searchTermEncoding, pChild, out nAttributeType, out nAttributeValue, out strTerm, out strError); if (nRet == -1) return -1; nRet = BuildOneXml( dbnames, strTerm, nAttributeValue, out strQueryXml, out strError); if (nRet == -1) return -1; return 0; /* // 真的要去检索数据库啦 SearchDBMulti(pResult, nAttributeValue, strTerm); * */ } else if (31 == pChild.m_uTag) { // 是结果集参预了检索 string strResultSetID = pChild.GetCharNodeData(); strQueryXml = "<item><resultSetName>" + strResultSetID + "</resultSetName></item>"; /* // // 为了避免在递归运算时删除了以前保留的结果集,copy 一份 if (!FindAndCopyExistResultSet(strResultSetID, pResult)) { throw_exception(0, _T("referred resultset not exist")); } // * */ } else { // strError = "Unsurported RPN structure"; } } else if (1 == node.m_uTag) { // rpnRpnOp // if (3 != node.ChildrenCollection.Count) { strError = "bad RPN structure"; return -1; } // string strXmlLeft = ""; string strXmlRight = ""; int nOperator = -1; nRet = BuildQueryXml( dbnames, node.ChildrenCollection[0], out strXmlLeft, out strError); if (nRet == -1) return -1; nRet = BuildQueryXml( dbnames, node.ChildrenCollection[1], out strXmlRight, out strError); if (nRet == -1) return -1; // and [0] // or [1] // and-not [2] nOperator = DecodeRPNOperator(node.ChildrenCollection[2]); if (nOperator == -1) { strError = "DecodeRPNOperator() return -1"; return -1; } switch (nOperator) { case 0: // and strQueryXml = "<group>" + strXmlLeft + "<operator value='AND' />" + strXmlRight + "</group>"; break; case 1: // or strQueryXml = "<group>" + strXmlLeft + "<operator value='OR' />" + strXmlRight + "</group>"; break; case 2: // and-not strQueryXml = "<group>" + strXmlLeft + "<operator value='SUB' />" + strXmlRight + "</group>"; break; default: // 不支持的操作符 strError = "unsurported operator"; return -1; } } else { strError = "bad RPN structure"; } return 0; }
// 在当前结点下方构造一个存放OIDs数据的结点 // parameters: // return: // NULL // 其他 public BerNode NewChildOIDsNode(UInt16 uTag, char cClass, string strValue) { if (this.m_cForm == ASN1_PRIMITIVE) return null; BerNode node = null; // List<byte> charray; node = new BerNode(); node.ParentNode = this; this.ChildrenCollection.Add(node); byte[] place = new byte[100]; /* seems like enough */ int offset = 0; long value; int nRet = 0; string strTemp = ""; for (int i = 0; i < strValue.Length; ) { /* if (Char.IsDigit(strValue[i]) == false) break; * */ if (i > 90) { Debug.Assert(false, ""); return null; } strTemp = GetNumber(strValue,i); value = Convert.ToInt64(strTemp); if (i == 0) /* first 2 numbers get special treatment */ { nRet = strValue.IndexOf('.', i); if (nRet == -1) { Debug.Assert(false, ""); return null; } i = nRet + 1; strTemp = GetNumber(strValue, i); value = value * 40 + Convert.ToInt64(strTemp); } if (value >= 0x80) { int count = 0; byte[] bits = new byte[12]; /* Save a 84 (12*7) bit number */ while (value != 0) { bits[count++] = (byte)(value & 0x7F ); value >>= 7; } /* Now place in the correct order */ while (--count > 0) place[offset++] = (byte)(bits[count] | 0x80); place[offset++] = bits[count]; } else place[offset++] = (byte)value; nRet = strValue.IndexOf('.', i); if (nRet != -1) { i = nRet + 1; } else { break; } } node.m_baData = new byte[offset]; Array.Copy(place, node.m_baData, offset); node.m_uTag = uTag; node.m_cClass = cClass; node.m_cForm = ASN1_PRIMITIVE; return node; }
// 构造NamePlusRecord子树 // parameters: // node NamePlusRecord的容器节点。也就是Present Response的根节点 public void BuildNamePlusRecord(BerNode node) { if (this.m_external == null && this.m_surrogateDiagnostic == null) throw new Exception("m_external 和 m_surrogateDiagnostic 不能同时为空"); if (this.m_external != null && this.m_surrogateDiagnostic != null) throw new Exception("m_external 和 m_surrogateDiagnostic 不能同时为非空。只能有一个为空"); BerNode pSequence = node.NewChildConstructedNode( BerNode.ASN1_SEQUENCE, // 16 BerNode.ASN1_UNIVERSAL); // 数据库名 pSequence.NewChildCharNode(0, BerNode.ASN1_CONTEXT, // ASN1_PRIMITIVE, BUG!!! Encoding.UTF8.GetBytes(this.m_strDatabaseName)); // record(一条记录) BerNode nodeRecord = pSequence.NewChildConstructedNode( 1, BerNode.ASN1_CONTEXT); if (this.m_external != null) { // extenal BerNode nodeRetrievalRecord = nodeRecord.NewChildConstructedNode( 1, BerNode.ASN1_CONTEXT); // real extenal! BerNode nodeExternal = nodeRetrievalRecord.NewChildConstructedNode( 8, // UNI_EXTERNAL BerNode.ASN1_UNIVERSAL); // TODO: 和前一条重复的库名和marc syntax oid可以省略? Debug.Assert(String.IsNullOrEmpty(this.m_external.m_strDirectRefenerce) == false, ""); nodeExternal.NewChildOIDsNode(6, // UNI_OBJECTIDENTIFIER, BerNode.ASN1_UNIVERSAL, this.m_external.m_strDirectRefenerce); // 1 条 MARC 记录 nodeExternal.NewChildCharNode(1, BerNode.ASN1_CONTEXT, this.m_external.m_octectAligned); } // 如果获得MARC记录出错,则这里要创建SurrogateDiagnostic record if (this.m_surrogateDiagnostic != null) { BerNode nodeSurrogateDiag = nodeRecord.NewChildConstructedNode( 2, BerNode.ASN1_CONTEXT); BerNode nodeDiagRoot = nodeSurrogateDiag.NewChildConstructedNode( BerNode.ASN1_SEQUENCE, // sequence BerNode.ASN1_UNIVERSAL); this.m_surrogateDiagnostic.BuildBer(nodeDiagRoot); /* nodeDiagRoot.NewChildOIDsNode(6, BerNode.ASN1_UNIVERSAL, this.m_surrogateDiagnostic.m_strDiagSetID); // "1.2.840.10003.4.1" nodeDiagRoot.NewChildIntegerNode(2, BerNode.ASN1_UNIVERSAL, BitConverter.GetBytes((long)this.m_surrogateDiagnostic.m_nDiagCondition)); if (String.IsNullOrEmpty(this.m_surrogateDiagnostic.m_strAddInfo) == false) { nodeDiagRoot.NewChildCharNode(26, BerNode.ASN1_UNIVERSAL, Encoding.UTF8.GetBytes(this.m_surrogateDiagnostic.m_strAddInfo)); } * */ } }
// return: // false // true public bool BuildPartTree(byte[] baBuffer, int nHead, int nLenParam, out int nUsedLen) { nUsedLen = 0; int tag; int fieldlen, headerlen; int nTempLen; BerNode node; int nLen = nLenParam; if (nLen == 0) return false; int offs = nHead; if (this.ParentNode == null) { node = new BerNode(); node.ParentNode = this; this.ChildrenCollection.Add(node); return node.BuildPartTree(baBuffer, nHead, nLen, out nUsedLen); } // 探测tag占据byte数 int taglen = get_tag(out tag, baBuffer, offs, nLen); if (taglen == 0) { /* no tag yet */ Debug.Assert(false, ""); return false; } if (nLen == taglen) return false; Debug.Assert(nLen != taglen, ""); // 探测长度占据byte数 int lenlen = get_len(out fieldlen, baBuffer, offs + taglen, nLen - taglen); if ((lenlen) == 0) { Debug.Assert(false, ""); return false; /* no len yet */ } Debug.Assert(fieldlen < nLen - taglen, ""); // fieldlen为内容长度 headerlen = taglen + lenlen; nUsedLen += headerlen; Debug.Assert(nUsedLen <= nLenParam, ""); if (lenlen == 1 && fieldlen == -1) /* indefinite 不确定 length */ { int fieldlen1 = 0; int totlen = 0; // 1.给此结点的Tag、Class、Form赋值 SetTagClassForm(baBuffer, offs); /* loop through the subfields and see if they are complete */ for (offs += headerlen, nLen -= headerlen; nLen > 1 && (baBuffer[offs] != 0 || baBuffer[offs + 1] != 0); offs += fieldlen1, nLen -= fieldlen1) { node = new BerNode(); //生成此结点的一个子结点 node.ParentNode = this; this.ChildrenCollection.Add(node); if (node.BuildPartTree(baBuffer, offs, nLen, out nTempLen) == false) return false; totlen += nTempLen; fieldlen1 = nTempLen; nUsedLen += nTempLen; Debug.Assert(nUsedLen <= nLenParam, ""); } if (nLen > 1 && baBuffer[offs] == 0 && baBuffer[offs + 1] == 0) // 当发现某个部分开头两个字符为0 { //*remainder=headerlen+totlen+2; /* + 2 nulls at end */ nUsedLen += 2; Debug.Assert(nUsedLen <= nLenParam, ""); return true; } //*remainder = -1; /* special flag to indicate indefinite length */ /* items */ return false; } if (fieldlen + headerlen <= nLen) { // 4.给结点的数据赋值 node = null; int nMax, nSubLen; // 1.给此结点的Tag、Class、Form赋值 SetTagClassForm(baBuffer, nHead); //!!!!!!!!!!!!! if (this.m_cForm == ASN1_CONSTRUCTED) { int nStart = 0; nMax = fieldlen; while (nMax > 0) { node = new BerNode(); //生成此结点的一个子结点 node.ParentNode = this; this.ChildrenCollection.Add(node); bool bRet = node.BuildPartTree(baBuffer, nHead + headerlen + nStart, fieldlen, out nSubLen); Debug.Assert(nSubLen <= fieldlen, ""); // 如果nSubLen永远为0怎么办 nMax -= nSubLen; nStart += nSubLen; nUsedLen += nSubLen; Debug.Assert(nUsedLen <= nLenParam, ""); Debug.Assert(nMax >= 0, ""); } } else { this.m_baData = new byte[fieldlen]; Array.Copy(baBuffer, nHead + headerlen, this.m_baData, 0, fieldlen); nUsedLen += fieldlen; Debug.Assert(nUsedLen <= nLenParam, ""); } //*remainder=fieldlen+headerlen; return true; } nUsedLen = fieldlen + headerlen; Debug.Assert(nUsedLen <= nLenParam, ""); if (nUsedLen >= nLenParam) return false; // //*remainder=fieldlen+headerlen-len; return true; }
// 接收响应包 public async Task <RecvResult> SimpleRecvTcpPackage() { string strError = ""; RecvResult result = new RecvResult(); int nInLen; int wRet = 0; bool bInitialLen = false; Debug.Assert(_client != null, "client为空"); result.Package = new byte[4096]; nInLen = 0; result.Length = 4096; //COMM_BUFF_LEN; while (nInLen < result.Length) { if (_client == null) { strError = "通讯中断"; goto ERROR1; } try { wRet = await _client.GetStream().ReadAsync(result.Package, nInLen, result.Package.Length - nInLen); } catch (SocketException ex) { if (ex.ErrorCode == 10035) { System.Threading.Thread.Sleep(100); continue; } strError = "recv出错: " + ex.Message; goto ERROR1; } catch (Exception ex) { strError = "recv出错: " + ex.Message; goto ERROR1; } if (wRet == 0) { strError = "Closed by remote peer"; goto ERROR1; } // 得到包的长度 if ((wRet >= 1 || nInLen >= 1) && bInitialLen == false) { bool bRet = BerNode.IsCompleteBER(result.Package, 0, nInLen + wRet, out long remainder); if (bRet == true) { result.Length = nInLen + wRet; break; } } nInLen += wRet; if (nInLen >= result.Package.Length && bInitialLen == false) { // 扩大缓冲区 byte[] temp = new byte[result.Package.Length + 4096]; Array.Copy(result.Package, 0, temp, 0, nInLen); result.Package = temp; result.Length = result.Package.Length; } } // 最后规整缓冲区尺寸,如果必要的话 if (result.Package.Length > result.Length) { byte[] temp = new byte[result.Length]; Array.Copy(result.Package, 0, temp, 0, result.Length); result.Package = temp; } return(result); ERROR1: // this.CloseSocket(); // baPackage = null; return(new RecvResult { Value = -1, ErrorInfo = strError }); }