Click here to Skip to main content
15,895,011 members
Articles / Desktop Programming / MFC

CXMLProfile - Easy XML Profiles for applications

Rate me:
Please Sign up or sign in to vote.
4.44/5 (6 votes)
26 Feb 20042 min read 132.5K   1.3K   42  
A MFC class to store an application's profile in an XML file.
// XMLProfile.cpp
// By Emilio Guijarro Cameros


#include "XMLProfile.h"

// CXMLProfile

CXMLProfile::CXMLProfile(LPCTSTR lpszProfileName) : pXMLDoc(NULL)
{		
	if (GetVersion() < 0x80000000) 
	{
		TCHAR szProfilesDir[MAX_PATH];

		SHGetSpecialFolderPath(NULL, szProfilesDir, CSIDL_LOCAL_APPDATA, TRUE);
		sFileName = _bstr_t(szProfilesDir) + _bstr_t("\\") + _bstr_t(lpszProfileName) + _bstr_t(".xml");		
	}
	else
		sFileName = _bstr_t(lpszProfileName);
}

CXMLProfile::~CXMLProfile()
{
	pXMLDoc->Release();
}

// CXMLProfile member functions

bool CXMLProfile::writeProfileInt(LPCTSTR lpszSection, LPCTSTR lpszEntry, int nValue) 
{	
	IXMLDOMNode* nEntry;
	WCHAR szTemp[255];

	_itow(nValue, szTemp, 10);
	
	nEntry = getEntry(lpszSection, lpszEntry);
	nEntry->put_text(_bstr_t(szTemp));
	nEntry->Release();
	
	return true;
}

bool CXMLProfile::writeProfileString(LPCTSTR lpszSection, LPCTSTR lpszEntry, LPCTSTR lpszData) 
{
	IXMLDOMNode* nEntry;

	nEntry = getEntry(lpszSection, lpszEntry);
	nEntry->put_text(_bstr_t(lpszData));
	nEntry->Release();
	
	return true;
}

int CXMLProfile::getProfileInt(LPCTSTR lpszSection, LPCTSTR lpszEntry, int nDefault) 
{
	IXMLDOMNode* nEntry;
	BSTR szContent = NULL;

	nEntry = getEntry(lpszSection, lpszEntry);
	nEntry->get_text(&szContent);
	
	if(szContent == NULL || _bstr_t(szContent) == _bstr_t(""))
	{
		IXMLDOMNode *nParent;
		
		nEntry->get_parentNode(&nParent);
		nParent->removeChild(nEntry, NULL);
		
		nEntry->Release();
		nParent->Release();

		return nDefault;
	}	
	
	nEntry->Release();

	return _wtoi(szContent);
}

LPSTR CXMLProfile::getProfileString(LPCTSTR lpszSection, LPCTSTR lpszEntry, LPCSTR lpszDefault, LPSTR lpBuffer, UINT nBufferSize)
{
	IXMLDOMNode* nEntry;
	BSTR szContent = NULL;

	nEntry = getEntry(lpszSection, lpszEntry);
	
	nEntry->get_text(&szContent);

	if(szContent == NULL || _bstr_t(szContent) == _bstr_t("")) {
		IXMLDOMNode *nParent;
		
		nEntry->get_parentNode(&nParent);
		nParent->removeChild(nEntry, NULL);
		
		nEntry->Release();
		nParent->Release();

		return (LPSTR)lpszDefault;
	}
	
	nEntry->Release();

	if(_bstr_t(szContent).length() < nBufferSize)
	{
		CHAR* szAsciiContent = _com_util::ConvertBSTRToString(szContent);

		strcpy(lpBuffer, szAsciiContent);
	}
	else
		throw CXMLProfileException("Buffer overflow");

	return lpBuffer;
}

IXMLDOMNode * CXMLProfile::getSection(LPCTSTR lpszSection)
{
	IXMLDOMElement* base, *element;
	IXMLDOMNode* nSec, *nResult;
	_bstr_t szName;
	bool bSecFound = false, bEntryFound = false;

	pXMLDoc->get_documentElement(&base);
	
	for(base->get_firstChild(&nSec); nSec != NULL; nSec->get_nextSibling(&nSec)) {
		nSec->get_baseName(szName.GetAddress());

		if(szName == _bstr_t(lpszSection)) {
			nResult = nSec;
			break;
		}
	}

	if(nSec == NULL) {
		pXMLDoc->createElement(_bstr_t(lpszSection), &element);
		base->appendChild(element, &nSec);
		element->Release();
		nResult = nSec;
	}

	base->Release();
	
	return nResult;
}

IXMLDOMNode * CXMLProfile::getEntry(LPCTSTR lpszSection, LPCTSTR lpszEntry)
{
	IXMLDOMElement* base, *element;
	IXMLDOMNode* nSec, *nEntry, *nResult;
	_bstr_t szName;

	pXMLDoc->get_documentElement(&base);
	
	for(base->get_firstChild(&nSec); nSec != NULL; nSec->get_nextSibling(&nSec)) {
		nSec->get_baseName(szName.GetAddress());

		if(szName == _bstr_t(lpszSection)) {
			for(nSec->get_firstChild(&nEntry); nEntry != NULL; nEntry->get_nextSibling(&nEntry)) {
				nEntry->get_baseName(szName.GetAddress());

				if(szName == _bstr_t(lpszEntry)) {
					nResult = nEntry;				
					break;
				}
			}

			if(nEntry == NULL) {
				pXMLDoc->createElement(_bstr_t(lpszEntry), &element);
				nSec->appendChild(element, &nEntry);
				element->Release();
				nResult = nEntry;
			}
			nSec->Release();
			break;
		}
	}

	if(nSec == NULL) {
		pXMLDoc->createElement(_bstr_t(lpszSection), &element);
		base->appendChild(element, &nSec);
		element->Release();
		pXMLDoc->createElement(_bstr_t(lpszEntry), &element);
		nSec->appendChild(element, &nEntry);
		element->Release();
		nResult = nEntry;
	}
	
	base->Release();

	return nResult;
}

bool CXMLProfile::saveProfile()
{
	if(pXMLDoc != NULL && SUCCEEDED(pXMLDoc->save(_variant_t(sFileName))))
		return true;
	else
		return false;
}

bool CXMLProfile::loadProfile()
{
	if(pXMLDoc != NULL)
		return false;

	if(SUCCEEDED(CoInitialize(NULL)) && SUCCEEDED(CoCreateInstance(CLSID_DOMDocument, 
		NULL, CLSCTX_INPROC_SERVER, IID_IXMLDOMDocument, (void**)&pXMLDoc)))
	{
		VARIANT_BOOL bResult;

		if(FAILED(pXMLDoc->load(_variant_t(sFileName), &bResult)))
			return false;
	}	

	IXMLDOMElement* base;
	
	pXMLDoc->get_documentElement(&base);

	if(base == NULL) {
		pXMLDoc->createElement(_bstr_t("profile"), &base);
		pXMLDoc->appendChild(base, NULL);
	}

	return true;
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Instructor/Trainer
Netherlands Netherlands
Emilio is a Computer Engineer currently working as software engineer in embedded systems.

Main interests are C/C++ programming, algorithmics, compilers, embedded systems, cryptography, and operating systems.

Comments and Discussions