#include "StdAfx.h" #include "XMLEngineMI.h" XML_API xi; namespace { class CXMLNodeMI : public IXMLNode, private boost::noncopyable { public: typedef boost::shared_ptr TXMLNodePtr; public: explicit CXMLNodeMI(HXML hXMl,bool bDestroy = false) : m_hXML(hXMl),m_bDestroy(bDestroy) { assert(m_hXML); } virtual ~CXMLNodeMI() { if(m_bDestroy) { xi.destroyNode(m_hXML); } } virtual size_t GetChildCount()const { return xi.getChildCount(m_hXML); } virtual TXMLNodePtr GetChildNode(size_t nIndex)const { HXML h = xi.getChild(m_hXML, (int)nIndex); if(h) { return TXMLNodePtr(new CXMLNodeMI(h)); } else { return TXMLNodePtr(); } } virtual tstring GetText()const { tstring sResult; LPCTSTR psz = xi.getText(m_hXML); if(psz) { sResult = psz; } return sResult; } virtual tstring GetName()const { tstring sResult; LPCTSTR psz = xi.getName(m_hXML); if(psz) { sResult = psz; } return sResult; } virtual bool AddChild(const TXMLNodePtr& pNode) { CXMLNodeMI* pXML = dynamic_cast(pNode.get()); if(pXML) { xi.addChild2(pXML->m_hXML,m_hXML); pXML->m_bDestroy = false; return true; } else { return false; } } virtual bool AddAttribute(const tstring& rsName,const tstring& rsValue) { xi.addAttr(m_hXML,rsName.c_str(),rsValue.c_str()); return true; } virtual tstring GetAttributeValue(const tstring& rsAttrName) { LPCTSTR pszValue = xi.getAttrValue(m_hXML,rsAttrName.c_str()); return ((NULL != pszValue) ? tstring(pszValue) : tstring()); } virtual void Write(tostream& o)const { // struct safe_string // { // safe_string(LPTSTR p):m_p(p){} // ~safe_string(){xi.freeMem(m_p);} // // LPTSTR m_p; // }; // // struct mir_safe_string // { // mir_safe_string(LPSTR p) : m_p(p){} // ~mir_safe_string(){mir_free(m_p);} // // LPSTR m_p; // }; safe_string ss(xi.toString(m_hXML,NULL)); if(ss.m_p) { mir_safe_string mss(mir_utf8encodeT(ss.m_p)); if(mss.m_p) { o << mss.m_p; } } } private: HXML m_hXML; bool m_bDestroy; }; } CXMLEngineMI::CXMLEngineMI() { } CXMLEngineMI::~CXMLEngineMI() { } IXMLNode::TXMLNodePtr CXMLEngineMI::LoadFile(const tstring& rsFileName)const { // struct mir_safe_string // { // mir_safe_string(LPTSTR p) : m_p(p){} // ~mir_safe_string(){mir_free(m_p);} // // LPTSTR m_p; // }; IXMLNode::TXMLNodePtr pResult; FILE* stream; if(0 == ::_tfopen_s(&stream,rsFileName.c_str(),_T("r"))) { struct _stat st; if(-1 != ::_fstat(::_fileno(stream),&st)) { std::vector aBuffer(st.st_size+1); char* pBuffer = &*(aBuffer.begin()); size_t cBytes = ::fread(pBuffer,sizeof(char),st.st_size,stream); if(cBytes > 0 && cBytes <= static_cast(st.st_size)) { pBuffer[cBytes] = '\0'; int nLen = (int)cBytes; mir_safe_string ss(mir_utf8decodeT(pBuffer)); if(ss.m_p) { HXML h = xi.parseString(ss.m_p,&nLen,NULL); if(h) { pResult = IXMLNode::TXMLNodePtr(new CXMLNodeMI(h,true)); } } } } ::fclose(stream); } return pResult; } namespace { IXMLNode::TXMLNodePtr create_node(const tstring& rsName,const tstring& rsText,bool bIsDecl) { IXMLNode::TXMLNodePtr pResult; HXML h = xi.createNode(rsName.c_str(),rsText.c_str(),bIsDecl); if(h) { pResult = IXMLNode::TXMLNodePtr(new CXMLNodeMI(h,true)); } return pResult; } } bool CXMLEngineMI::SaveFile(const tstring& rsFileName,const IXMLNode::TXMLNodePtr& pNode)const { CXMLNodeMI* pXML = dynamic_cast(pNode.get()); if(pXML) { tofstream file(rsFileName.c_str()); if(file.good()) { IXMLNode::TXMLNodePtr pRoot(create_node(_T("xml"),tstring(),true)); if(pRoot) { pRoot->AddAttribute(_T("version"),_T("1.0")); pRoot->AddAttribute(_T("encoding"),_T("UTF-8")); file << *pRoot; } if(file.good()) { file << *pNode; } } return file.good(); } return false; } IXMLNode::TXMLNodePtr CXMLEngineMI::CreateNode(const tstring& rsName,const tstring& rsText)const { return create_node(rsName,rsText,false); }