I got a programm, that works with xml files. And it uses MSXML.dll. But i found i greate memory leak, and i can't understand - what am i doing wrong???
Here is the code:
#pragma once
#include <vector>
#import <msxml.dll> named_guids
using namespace MSXML;
using namespace std;
class CNakladImporter
{
vector <CString> m_vHead;
vector <CString> m_vHeadForAgents;
CFile m_File;
CString m_PathToNomen;
CString m_PathToAgents;
CString m_PathToNaklad;
MSXML::IXMLDOMDocumentPtr m_plDomDocument;
MSXML::IXMLDOMElementPtr m_plDocRoot;
void GetChild(MSXML::IXMLDOMNodePtr pParent,CString FullPath);
void GetChildForAgents(MSXML::IXMLDOMNodePtr pParent);
int CreateHead(MSXML::IXMLDOMNodePtr pParent);
int CreateHeadForAgents(MSXML::IXMLDOMNodePtr pParent);
public:
CNakladImporter(void);
void SetPathToNomen(CString Path);
void SetPathToAgents(CString Path);
void SetPathToNaklad(CString Path);
BOOL ExportAgents(CProgressCtrl* ProgressCtrl);
BOOL ExportNomen(CProgressCtrl* ProgressCtrl);
BOOL ImportNaklad(CProgressCtrl* ProgressCtrl);
void ClearHistory();
~CNakladImporter(void);
bool InitXML(void);
};
and implementation
#include "StdAfx.h"
#include "nakladimporter.h"
char PathToNomenOnPocket[] = "\\Program Files\\Mobile Terminal\\Data\\Nomen.dat";
char PathToAgentsOnPocket[] = "\\Program Files\\Mobile Terminal\\Data\\Agents.dat";
char PathToNaklOnPocket[] = "\\My Documents\\*.xml";
char PathToMyDocyments[] = "\\My Documents\\";
char PathToHistory[] = "\\Program Files\\Mobile Terminal\\Data\\History\\";
char PathToHistoryNakl[] = "\\Program Files\\Mobile Terminal\\Data\\History\\*.xml";
CNakladImporter::CNakladImporter(void)
{
}
CNakladImporter::~CNakladImporter(void)
{
}
void CNakladImporter::SetPathToNomen(CString Path)
{
m_PathToNomen = Path;
}
void CNakladImporter::SetPathToAgents(CString Path)
{
m_PathToAgents = Path;
}
void CNakladImporter::SetPathToNaklad(CString Path)
{
m_PathToNaklad = Path;
}
BOOL CNakladImporter::ExportAgents(CProgressCtrl* ProgressCtrl)
{
_bstr_t bstrFileName;
bstrFileName = m_PathToAgents.AllocSysString();
variant_t vResult;
vResult = m_plDomDocument->load(bstrFileName);
if(((bool)vResult)==TRUE)
{
ProgressCtrl->SetRange(0,30);
ProgressCtrl->SetStep(10);
char Razdelitel = '?';
m_File.Open("Agents.dat",CFile::modeCreate|CFile::modeWrite);
m_plDocRoot = m_plDomDocument->documentElement;
MSXML::IXMLDOMNodePtr pDocRoot = m_plDomDocument->documentElement;
CreateHeadForAgents(pDocRoot);
int Size = m_vHeadForAgents.size();
m_File.Write(&Size,sizeof(int));
Size--;
for(int i = 0;i<m_vHeadForAgents.size();i++)
Size+=m_vHeadForAgents[i].GetLength();
m_File.Write(&Size,sizeof(int));
for(i = 0;i<m_vHeadForAgents.size();i++)
{
m_File.Write(m_vHeadForAgents[i],m_vHeadForAgents[i].GetLength());
if(i<m_vHeadForAgents.size()-1)
m_File.Write(&Razdelitel,1);
}
ProgressCtrl->StepIt();
m_vHead.clear();
Razdelitel = '.';
m_File.Write(&Razdelitel,1);
GetChildForAgents(m_plDocRoot);
ProgressCtrl->StepIt();
m_File.Close();
m_File.Open("Agents.dat",CFile::modeRead);
char* buffer = new char[m_File.GetLength()];
m_File.Read(buffer,m_File.GetLength());
WCHAR wsdata[256];
MultiByteToWideChar(CP_ACP,0,PathToAgentsOnPocket,strlen(PathToAgentsOnPocket)+1,wsdata,sizeof(wsdata)/sizeof(wsdata[0]));
HANDLE hFile = CeCreateFile(wsdata,GENERIC_READ|GENERIC_WRITE,NULL,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
if(hFile==INVALID_HANDLE_VALUE)
{
MessageBox(NULL,"Can't Create File On Mobile Terminal","MT Error",MB_ICONERROR);
return FALSE;
}
DWORD Bytes;
CeWriteFile(hFile,buffer,m_File.GetLength(),&Bytes,NULL);
CeCloseHandle(hFile);
m_File.Close();
DeleteFile("Agents.dat");
ProgressCtrl->StepIt();
return TRUE;
}
return FALSE;
}
void CNakladImporter::GetChildForAgents(MSXML::IXMLDOMNodePtr pParent)
{
MSXML::IXMLDOMNamedNodeMapPtr pNamedNodeMapPtr =NULL;
MSXML::IXMLDOMNodePtr pXMLAttrNode = NULL;
long AttributesNumber = 0;
CString AttrName;
HRESULT hResult = pParent->get_attributes(&pNamedNodeMapPtr);
if(FAILED(hResult))
{
::MessageBox(NULL,"Attribute Getting Error","XML Error",MB_ICONERROR);
return;
}
pNamedNodeMapPtr->get_length(&AttributesNumber);
char Razdelitel = '#';
for(int i = 0;i<AttributesNumber;i++)
{
pNamedNodeMapPtr->get_item(i,&pXMLAttrNode);
COleVariant OleVariant;
pXMLAttrNode->get_nodeValue(OleVariant);
CString str = OleVariant;
if(str=="")
str=" ";
str.Replace('#','-');
m_File.Write(str,str.GetLength());
m_File.Write(&Razdelitel,1);
}
for(MSXML::IXMLDOMNodePtr pChild = pParent->firstChild;NULL!=pChild;pChild=pChild->nextSibling)
{
GetChildForAgents(pChild);
}
}
void CNakladImporter::GetChild(MSXML::IXMLDOMNodePtr pParent,CString FullPath = "")
{
MSXML::IXMLDOMNamedNodeMapPtr pNamedNodeMapPtr =NULL;
MSXML::IXMLDOMNodePtr pXMLAttrNode = NULL;
long AttributesNumber = 0;
CString AttrName;
HRESULT hResult = pParent->get_attributes(&pNamedNodeMapPtr);
if(FAILED(hResult))
{
::MessageBox(NULL,"Attribute Getting Error","XML Error",MB_ICONERROR);
return;
}
pNamedNodeMapPtr->get_length(&AttributesNumber);
char Razdelitel = '#';
for(int i = 0;i<AttributesNumber;i++)
{
pNamedNodeMapPtr->get_item(i,&pXMLAttrNode);
CString str((LPCTSTR)pXMLAttrNode->nodeName);
if(str=="Группа")
{
COleVariant OleVariant;
pXMLAttrNode->get_nodeValue(OleVariant);
CString OleString = OleVariant;
FullPath += OleString+"\\";
}
else
{
if(!i)
{
m_File.Write(FullPath,FullPath.GetLength());
m_File.Write(&Razdelitel,1);
}
COleVariant OleVariant;
pXMLAttrNode->get_nodeValue(OleVariant);
CString str = OleVariant;
if(str=="")
str = " ";
str.Replace('#','-');
m_File.Write(str,str.GetLength());
m_File.Write(&Razdelitel,1);
}
}
for(MSXML::IXMLDOMNodePtr pChild = pParent->firstChild;NULL!=pChild;pChild=pChild->nextSibling)
{
GetChild(pChild,FullPath);
}
}
int CNakladImporter::CreateHeadForAgents(MSXML::IXMLDOMNodePtr pParent)
{
MSXML::IXMLDOMNamedNodeMapPtr pNamedNodeMapPtr =NULL;
MSXML::IXMLDOMNodePtr pXMLAttrNode = NULL;
long AttributesNumber = 0;
HRESULT hResult = pParent->get_attributes(&pNamedNodeMapPtr);
if(FAILED(hResult))
{
::MessageBox(NULL,"Error","Error",MB_ICONERROR);
return 1;
}
pNamedNodeMapPtr->get_length(&AttributesNumber);
for(int i = 0;i<AttributesNumber;i++)
{
pNamedNodeMapPtr->get_item(i,&pXMLAttrNode);
for(int j = 0;j<AttributesNumber;j++)
{
pNamedNodeMapPtr->get_item(j,&pXMLAttrNode);
CString str((LPCTSTR)pXMLAttrNode->nodeName);
m_vHeadForAgents.push_back(str);
}
return 1;
break;
}
for(MSXML::IXMLDOMNodePtr pChild = pParent->firstChild;NULL!=pChild;pChild=pChild->nextSibling)
{
if(CreateHeadForAgents(pChild)==1)
return 1;
}
return 0;
}
int CNakladImporter::CreateHead(MSXML::IXMLDOMNodePtr pParent)
{
MSXML::IXMLDOMNamedNodeMapPtr pNamedNodeMapPtr =NULL;
MSXML::IXMLDOMNodePtr pXMLAttrNode = NULL;
long AttributesNumber = 0;
HRESULT hResult = pParent->get_attributes(&pNamedNodeMapPtr);
if(FAILED(hResult))
{
::MessageBox(NULL,"Error","Error",MB_ICONERROR);
return 1;
}
pNamedNodeMapPtr->get_length(&AttributesNumber);
for(int i = 0;i<AttributesNumber;i++)
{
pNamedNodeMapPtr->get_item(i,&pXMLAttrNode);
CString str((LPCTSTR)pXMLAttrNode->nodeName);
if(str!="Группа")
{
for(int j = 0;j<AttributesNumber;j++)
{
pNamedNodeMapPtr->get_item(j,&pXMLAttrNode);
CString str((LPCTSTR)pXMLAttrNode->nodeName);
m_vHead.push_back(str);
}
return 1;
}
break;
}
for(MSXML::IXMLDOMNodePtr pChild = pParent->firstChild;NULL!=pChild;pChild=pChild->nextSibling)
{
if(CreateHead(pChild)==1)
return 1;
}
return 0;
}
BOOL CNakladImporter::ExportNomen(CProgressCtrl* ProgressCtrl)
{
_bstr_t bstrFileName;
bstrFileName = m_PathToNomen.AllocSysString();
variant_t vResult;
vResult = m_plDomDocument->load(bstrFileName);
if(((bool)vResult)==TRUE)
{
ProgressCtrl->SetRange(0,30);
ProgressCtrl->SetStep(10);
char Razdelitel = '?';
m_File.Open("Nomen.dat",CFile::modeCreate|CFile::modeWrite);
m_plDocRoot = m_plDomDocument->documentElement;
MSXML::IXMLDOMNodePtr pDocRoot = m_plDomDocument->documentElement;
m_vHead.push_back(CString("Путь"));
CreateHead(pDocRoot);
int Size = m_vHead.size();
m_File.Write(&Size,sizeof(int));
Size--;
for(int i = 0;i<m_vHead.size();i++)
Size+=m_vHead[i].GetLength();
m_File.Write(&Size,sizeof(int));
for(i = 0;i<m_vHead.size();i++)
{
m_File.Write(m_vHead[i],m_vHead[i].GetLength());
if(i<m_vHead.size()-1)
m_File.Write(&Razdelitel,1);
}
ProgressCtrl->StepIt();
m_vHead.clear();
Razdelitel = '.';
m_File.Write(&Razdelitel,1);
GetChild(m_plDocRoot);
ProgressCtrl->StepIt();
m_File.Close();
m_File.Open("Nomen.dat",CFile::modeRead);
char* buffer = new char[m_File.GetLength()];
m_File.Read(buffer,m_File.GetLength());
WCHAR wsdata[256];
MultiByteToWideChar(CP_ACP,0,PathToNomenOnPocket,strlen(PathToNomenOnPocket)+1,wsdata,sizeof(wsdata)/sizeof(wsdata[0]));
HANDLE hFile = CeCreateFile(wsdata,GENERIC_READ|GENERIC_WRITE,NULL,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
if(hFile==INVALID_HANDLE_VALUE)
{
MessageBox(NULL,"Can't Create File On Mobile Terminal","MT Error",MB_ICONERROR);
return FALSE;
}
DWORD Bytes;
CeWriteFile(hFile,buffer,m_File.GetLength(),&Bytes,NULL);
CeCloseHandle(hFile);
m_File.Close();
DeleteFile("Nomen.dat");
ProgressCtrl->StepIt();
return TRUE;
}
else
{
::MessageBox(NULL,"Can't Load XML File","XML Error",MB_ICONERROR);
return FALSE;
}
}
void CNakladImporter::ClearHistory()
{
WCHAR wsdata[512];
WCHAR tempwsdata[512];
MultiByteToWideChar(CP_ACP,0,PathToHistoryNakl,strlen(PathToHistoryNakl)+1,wsdata,sizeof(wsdata)/sizeof(wsdata[0]));
LPCE_FIND_DATA FindData = NULL;
DWORD Count;
CeFindAllFiles(wsdata,FAF_ATTRIB_NO_HIDDEN|FAF_NAME,&Count,&FindData);
MultiByteToWideChar(CP_ACP,0,PathToHistory,strlen(PathToHistory)+1,wsdata,sizeof(wsdata)/sizeof(wsdata[0]));
StrCpyW(tempwsdata,wsdata);
for(int i = 0;i<Count;i++)
{
StrCatW(wsdata,FindData[i].cFileName);
if(!CeDeleteFile(wsdata))
MessageBox(NULL,"Can't Delete File From Mobile Terminal","File Error",MB_ICONERROR);
StrCpyW(wsdata,tempwsdata);
}
if(CeRapiFreeBuffer(FindData)==E_FAIL)
{
MessageBox(NULL,"Memory Free Error","Memory Error",MB_ICONINFORMATION);
};
}
BOOL CNakladImporter::ImportNaklad(CProgressCtrl* ProgressCtrl)
{
CFile file;
char* XMLHEAD = "<?xml version=\"1.0\" encoding=\"windows-1251\"?><НАКЛАДНАЯ>";
char* XMLEND = "</НАКЛАДНАЯ>";
WCHAR wsdata[256];
WCHAR tempwsdata[256];
MultiByteToWideChar(CP_ACP,0,PathToNaklOnPocket,strlen(PathToNaklOnPocket)+1,wsdata,sizeof(wsdata)/sizeof(wsdata[0]));
LPCE_FIND_DATA FindData = NULL;
DWORD Count;
CeFindAllFiles(wsdata,FAF_ATTRIB_NO_HIDDEN|FAF_NAME,&Count,&FindData);
MultiByteToWideChar(CP_ACP,0,PathToMyDocyments,strlen(PathToMyDocyments)+1,wsdata,sizeof(wsdata)/sizeof(wsdata[0]));
StrCpyW(tempwsdata,wsdata);
ProgressCtrl->SetRange(0,Count*10);
ProgressCtrl->SetStep(10);
if(Count==0)
{
MessageBox(NULL,"Mobile Terminal Is Empty","Information",MB_ICONINFORMATION);
return TRUE;
}
CFileException fe;
file.Open(m_PathToNaklad,CFile::modeCreate|CFile::modeWrite,&fe);
file.Write(XMLHEAD,strlen(XMLHEAD));
for(int i = 0;i<Count;i++)
{
StrCatW(wsdata,FindData[i].cFileName);
HANDLE hFileTemp = CeCreateFile(wsdata,GENERIC_READ,NULL,NULL,OPEN_ALWAYS,FILE_ATTRIBUTE_READONLY,NULL);
if(hFileTemp==INVALID_HANDLE_VALUE)
{
MessageBox(NULL,"Can't Open File","Error",MB_ICONINFORMATION);
}
DWORD HIGH;
int Size = CeGetFileSize(hFileTemp,&HIGH);
if(Size>45)
{
char* data = new char[Size-45];
LARGE_INTEGER li;
li.QuadPart = 45;
li.LowPart = CeSetFilePointer(hFileTemp,li.LowPart,&li.HighPart,FILE_BEGIN);
CeReadFile(hFileTemp,data,Size-45,&HIGH,NULL);
file.Write(data,Size-45);
CeCloseHandle(hFileTemp);
delete [] data;
}
WCHAR HistoryPath[512];
MultiByteToWideChar(CP_ACP,0,PathToHistory,strlen(PathToHistory)+1,HistoryPath,sizeof(HistoryPath)/sizeof(HistoryPath[0]));
CeCopyFile(wsdata,StrCatW(HistoryPath,FindData[i].cFileName),FALSE);
if(!CeDeleteFile(wsdata))
MessageBox(NULL,"Can't Delete File From Mobile Terminal","File Error",MB_ICONERROR);
StrCpyW(wsdata,tempwsdata);
ProgressCtrl->StepIt();
}
file.Write(XMLEND,strlen(XMLEND));
file.Close();
if(CeRapiFreeBuffer(FindData)==E_FAIL)
{
MessageBox(NULL,"Memory Free Error","Memory Error",MB_ICONINFORMATION);
};
return TRUE;
}
bool CNakladImporter::InitXML(void)
{
::CoInitialize(NULL);
HRESULT hr = m_plDomDocument.CreateInstance(MSXML::CLSID_DOMDocument);
if(FAILED(hr))
{
_com_error er(hr);
AfxMessageBox(er.ErrorMessage());
return false;
}
return true;
}
Please help, anybody...
Maybe problem in smart pointers???
If i don't call CreateInstance of smart pointer object, do i have to call Release??? Or can i send it in function parameter Somenting(SMartPtr pPtr)???
|