www.pudn.com > manypeopleallchat.rar > XMLCommand.h
// XMLCommand.h: interface for the CXMLCommand class. // ////////////////////////////////////////////////////////////////////// #if !defined(AFX_XMLCOMMAND_H__468D863E_C56E_435B_9D2D_57CE71FC5037__INCLUDED_) #define AFX_XMLCOMMAND_H__468D863E_C56E_435B_9D2D_57CE71FC5037__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 #importnamed_guids using namespace MSXML; #include "user.h" #include "buffer.h" //element #define USERLOGIN "USERLOGIN" #define USERLOGOUT "USERLOGOUT" #define NEWUSER "NEWUSER" #define USERSPEAK "USERSPEAK" #define USERMESSAGE "USERMESSAGE" #define LOGINSUCCESS "LOGINSUCCESS" #define USERS "USERS" #define USER "USER" #define REQUESTSF "REQUESTSF" #define OK "OK" #define NO "NO" //attribute #define NAME "NAME" #define ID "ID" #define IP "IP" #define PORT "PORT" #define FPORT "FPORT" //net packet #define NET "NET" #define TAGNET1 "<"NET">" #define TAGNET2 ""NET">" template class CXMLCommand { protected: Type* m_pType; protected: //构建XML格式 CString CreateNetPacket(IXMLDOMDocumentPtr docPtr); //根据tag,产生用户信息 IXMLDOMDocumentPtr CreateUserInfoTag(_bstr_t &tag, USERINFO &user, BOOL bIP = FALSE); //从节点中获得用户数据,节点包括userinfo的属性:ID和NAME属性 BOOL GetUserInfoFromNode(IXMLDOMNodePtr nodePtr, USERINFO &user, BOOL bIP = FALSE); public: CXMLCommand(){}; virtual ~CXMLCommand(){}; void SetType(Type* pType){m_pType = pType;}; //从缓冲区中读取,是否存在完整的xml指令,即取出 ... BOOL HasNetPacket(CBuffer &buffer, CString &strXML); //获得输入指令 CString GetCommand(){return CString((char*)m_out);} //处理信息,由子类重写 virtual BOOL DoProcessNetPacket(LONG userID, CString &strXML) = 0; }; //template IXMLDOMDocumentPtr CXMLCommand ::CreateUserInfoTag(_bstr_t &tag, USERINFO &user, BOOL bIP) { IXMLDOMDocumentPtr docPtr; IXMLDOMElementPtr elementPtr; //生成文档 docPtr.CreateInstance(MSXML::CLSID_DOMDocument); //根据tag生成根元素 elementPtr = docPtr->createElement(tag); docPtr->documentElement = elementPtr; //设置用户属性 elementPtr->setAttribute(_bstr_t(ID), _variant_t(user.m_id)); elementPtr->setAttribute(_bstr_t(NAME),_variant_t(user.m_name)); if(bIP) { elementPtr->setAttribute(_bstr_t(IP),_variant_t(user.m_ip)); elementPtr->setAttribute(_bstr_t(PORT),_variant_t(user.m_nPort)); elementPtr->setAttribute(_bstr_t(FPORT),_variant_t(user.m_nFilePort)); } return docPtr; } //在网络上传输时,先打包 template CString CXMLCommand ::CreateNetPacket(IXMLDOMDocumentPtr docPtr) { IXMLDOMElementPtr elementPtr = docPtr->createElement(_bstr_t(NET)); elementPtr->appendChild(docPtr->documentElement); docPtr->documentElement = elementPtr; return (char*)(docPtr->xml); } template BOOL CXMLCommand ::HasNetPacket(CBuffer &buffer, CString &strXML) { int nPos1 = buffer.Scan(TAGNET1, 0); if(nPos1 == -1) return FALSE; //删除无效数据(不再NET包内部) buffer.Delete(nPos1); int nPos2 = buffer.Scan(TAGNET2, 0); if(nPos2 == -1) return FALSE; //分配足够的空间,多分配一个结尾符 int nSize = nPos2 + strlen(TAGNET2)+1; PCHAR pBuf = new CHAR[nSize]; memset(pBuf, 0, nSize); //从缓冲区中读入数据,并删除缓冲区内容 buffer.Read(pBuf, nSize-1); strXML = pBuf; //释放空间 free(pBuf); return TRUE; } //FALSE:指令格式不对 template BOOL CXMLCommand ::GetUserInfoFromNode(IXMLDOMNodePtr nodePtr, USERINFO &user, BOOL bIP) { IXMLDOMNamedNodeMapPtr nodeMapPtr = nodePtr->Getattributes(); IXMLDOMNodePtr nodePtr1 = nodeMapPtr->getNamedItem(_bstr_t(ID)); if(nodePtr1 == NULL) return FALSE; IXMLDOMNodePtr nodePtr2 = nodeMapPtr->getNamedItem(_bstr_t(NAME)); if(nodePtr2 == NULL) return FALSE; user.m_id = atol((char*)nodePtr1->text); sprintf(user.m_name, (char *)nodePtr2->text); if(bIP) { IXMLDOMNodePtr nodePtr3 = nodeMapPtr->getNamedItem(_bstr_t(IP)); if(nodePtr3 == NULL) return FALSE; sprintf(user.m_ip, (char *)nodePtr3->text); IXMLDOMNodePtr nodePtr4 = nodeMapPtr->getNamedItem(_bstr_t(PORT)); if(nodePtr4 == NULL) return FALSE; user.m_nPort = atol((char*)nodePtr4->text); IXMLDOMNodePtr nodePtr5 = nodeMapPtr->getNamedItem(_bstr_t(FPORT)); if(nodePtr5 == NULL) return FALSE; user.m_nFilePort = atol((char*)nodePtr5->text); } return TRUE; } #endif // !defined(AFX_XMLCOMMAND_H__468D863E_C56E_435B_9D2D_57CE71FC5037__INCLUDED_)