Click here to Skip to main content
15,885,309 members
Articles / Desktop Programming / ATL

CM_ConfigBuilder 1.2g: Visual Studio 6/Visual Studio 2005/Visual Studio 2008 Code Generator for Application Settings Graphic Management

Rate me:
Please Sign up or sign in to vote.
4.94/5 (126 votes)
12 Feb 2008CPOL17 min read 696.4K   9.8K   262  
CM_ConfigBuilder generates and compiles the required files to manage your application's settings/preferences and to store/retrieve them in XML format.
// CAtlClassMapGenerator.cpp
//
#include "stdafx.h"
#include "AtlClassMapGenerator.h"
#include "XmlProjectSettings.h"
#include "XmlClassInfo.h"
#include "XmlMemberInfo.h"
#include "XmlProject.h"

CAtlClassMapGenerator::CAtlClassMapGenerator()
{}

CAtlClassMapGenerator::~CAtlClassMapGenerator()
{}


void CAtlClassMapGenerator::Generate()
{
	// generate header file
	//
	GenerateHeader();
	
	// generate implementation file
	//
	GenerateImplementation();
}
	
void CAtlClassMapGenerator::GenerateHeader()
{
	string fileName;
	string pathName;

	Head_generateHeader();
	Head_generateIfDefBegin();
	Head_generateIncludeSection();
	Head_generateForwardDecl();
	Head_generateClassBegin();
	Head_generateConstructor();
	Head_generateDestructor();
	Head_generateMethods();
	Head_generateSerialization();
	Head_generateMembers();
	Head_generateClassEnd();
	Head_generateIfDefEnd();

	pathName = BuildGeneratedSourcePath() + "include\\";
	fileName = GetClassName() + GetCardinalityPostfix(classInfo_) + ".h";
	SaveFile(pathName + fileName, headCode_);

	hGeneratedFiles_[fileName] = pathName + fileName;
}

void CAtlClassMapGenerator::Head_generateHeader()
{
	headCode_ += "// " + GetClassName() + GetCardinalityPostfix(classInfo_) + ".h" + xCrLf;
	headCode_ += "// " + xCrLf; 
	headCode_ += GetGenerationTimeStamp();
}

void CAtlClassMapGenerator::Head_generateIfDefBegin()
{
	headCode_ += "#if !defined(" + DefineOf(GetClassName()) + GetCardinalityPostfix(classInfo_) + ")" + xCrLf;
	headCode_ += "#define " + DefineOf(GetClassName()) + GetCardinalityPostfix(classInfo_) + xCrLf;
	headCode_ += xCrLf;
}

void CAtlClassMapGenerator::Head_generateIncludeSection()
{
	headCode_ += "#include <string>" + xCrLf;
	headCode_ += "#include <map>" + xCrLf;
	headCode_ += "#include \"XmlSerializable.h\"" + xCrLf;
	headCode_ += "#include \"ProjectConfigAtl.h\"" + xCrLf;

	// include contained class header
	//
	headCode_ += "#include \"" + GetClassName(classInfo_->GetName()) + ".h\"" + xCrLf;
	headCode_ += xCrLf;

	headCode_ += xCrLf;
	headCode_ += "using namespace std;" + xCrLf;
	headCode_ += xCrLf;
}

void CAtlClassMapGenerator::Head_generateForwardDecl()
{
}

void CAtlClassMapGenerator::Head_generateClassBegin()
{
	//headCode_ += "class " + GetClassName() + GetCardinalityPostfix(classInfo_) + ": public CXmlSerializable" + xCrLf;
	//headCode_ += "{" + xCrLf;

	string prefix;
	string name;
	string p;

	p =  GetCardinalityPostfix(classInfo_);
	prefix = project_->GetProjectSettings()->GetAtlSettings()->GetClassPrefix();
	name = GetClassName() + p;
	
	headCode_ += "/////////////////////////////////////////////////////////////////////////////" + xCrLf;
	headCode_ += "// " + name + xCrLf;
	headCode_ += "class ATL_NO_VTABLE " + name + ":" + xCrLf; 
	headCode_ += "public CComObjectRootEx<CComSingleThreadModel>," + xCrLf;
	headCode_ += "public CComCoClass<" + name + ", &CLSID_" + classInfo_->GetName() + p + ">," + xCrLf;
	headCode_ += "public IDispatchImpl<I" + name + ", &IID_I" + name + ", &LIBID_" + ToUpperCase(prefix) + "Lib>," + xCrLf;
	headCode_ += "public CXmlSerializable" + xCrLf;
	headCode_ += "{" + xCrLf;
	headCode_ += xCrLf;
	headCode_ += "public:" + xCrLf;
	headCode_ += xTab + "DECLARE_REGISTRY_RESOURCEID(IDR_" + ToUpperCase(classInfo_->GetName() + p) + ")" + xCrLf;
	headCode_ += xTab + "DECLARE_NOT_AGGREGATABLE(" + name + ")" + xCrLf;
	headCode_ += xCrLf;
	headCode_ += xTab + "DECLARE_PROTECT_FINAL_CONSTRUCT()" + xCrLf;
	headCode_ += xCrLf;
	headCode_ += xTab + "BEGIN_COM_MAP(" + name + ")" + xCrLf;
	headCode_ += xTab + xTab + "COM_INTERFACE_ENTRY(I" + name + ")" + xCrLf;
	headCode_ += xTab + xTab + "COM_INTERFACE_ENTRY(IDispatch)" + xCrLf;
	headCode_ += xTab + "END_COM_MAP()" + xCrLf;
	headCode_ += xCrLf;
}

void CAtlClassMapGenerator::Head_generateConstructor()
{
	headCode_ += "public:" + xCrLf;
	headCode_ += xTab + GetClassName() + GetCardinalityPostfix(classInfo_) + "();" + xCrLf;
}

void CAtlClassMapGenerator::Head_generateDestructor()
{
	headCode_ += xTab + "virtual ~" + GetClassName() + GetCardinalityPostfix(classInfo_) + "();" + xCrLf + xCrLf;
}

void CAtlClassMapGenerator::Head_generateMethods()
{
	CXmlBaseElement* sortKeyMember;
	string keyParam;

	sortKeyMember = classInfo_->GetMember(classInfo_->GetCardinalityInfo()->GetMapSortKey());
	if (sortKeyMember == NULL)
		return;

	if (sortKeyMember->GetDataType() == enDataType_String)
		keyParam = "const " + TypeOf(sortKeyMember->GetDataType()) + "& key";
	else
		keyParam = TypeOf(sortKeyMember->GetDataType()) + " key";

	headCode_ += xTab + "// utils" + xCrLf;
	headCode_ += xTab + "//" + xCrLf;
	headCode_ += "public:" + xCrLf;
	//headCode_ += xTab + "void operator=(const " + GetClassName() + GetCardinalityPostfix(classInfo_) + "& copy);" + xCrLf + xCrLf;
	headCode_ += xTab + "void SetDefaults();"  + xCrLf;
	headCode_ += xTab + "void Clear();"  + xCrLf;
	headCode_ += xCrLf;
	headCode_ += xTab + "// I" + GetClassName() + GetCardinalityPostfix(classInfo_) + xCrLf;
	headCode_ += xTab + "//" + xCrLf;
	headCode_ += "public:" + xCrLf;
	headCode_ += xTab + "STDMETHOD(MoveFirst)(/*[out, retval]*/ VARIANT_BOOL* retval);"  + xCrLf;
	headCode_ += xTab + "STDMETHOD(MoveNext)(/*[out, retval]*/ VARIANT_BOOL* retval);"  + xCrLf;
	headCode_ += xTab + "STDMETHOD(GetPair)(/*[out]*/" + OleTypeOf(sortKeyMember->GetDataType()) + "* key, /*[out]*/ I" + GetClassName() + "** " + GetCamelCase(classInfo_->GetName()) + ", /*[out, retval]*/ VARIANT_BOOL* retval);"  + xCrLf;
	headCode_ += xTab + "STDMETHOD(FindItem)(/*[in]*/" + OleTypeOf(sortKeyMember->GetDataType()) + " key, /*[out]*/ I" + GetClassName() + "** " + GetCamelCase(classInfo_->GetName()) + ");"  + xCrLf;
	headCode_ += xTab + "STDMETHOD(Insert)(/*[in]*/ I" + GetClassName() + "* " + GetCamelCase(classInfo_->GetName()) + ");" + xCrLf;
	headCode_ += xTab + "STDMETHOD(Delete)(/*[in]*/" + OleTypeOf(sortKeyMember->GetDataType()) + " key);" + xCrLf;
	headCode_ += xTab + "STDMETHOD(GetSize)(/*[out, retval]*/ long* retval);" + xCrLf;
	headCode_ += xTab + "STDMETHOD(CleanUp)();" + xCrLf;
	headCode_ += xTab + "STDMETHOD(RestoreDefaults)();" + xCrLf;
	headCode_ += xTab + "STDMETHOD(Copy)(/*[in]*/ I" + GetClassName() + GetCardinalityPostfix(classInfo_) + "* source);" + xCrLf;
	headCode_ += xTab + "STDMETHOD(Load)(/*[in]*/ BSTR fileName, /*[out, retval]*/ VARIANT_BOOL* retval);" + xCrLf;
	headCode_ += xTab + "STDMETHOD(Save)(/*[in]*/ BSTR fileName, /*[out, retval]*/ VARIANT_BOOL* retval);" + xCrLf;
	headCode_ += xTab + "STDMETHOD(ReplaceKey)(/*[in]*/ BSTR currentKey, /*[in]*/ BSTR newKey);" + xCrLf;
	headCode_ += xCrLf;

	headCode_ += xTab + "virtual string GetXmlNodeName(){return xmlNodeName_;}" + xCrLf;
	headCode_ += xTab + "static string xmlNodeName_;" + xCrLf;
		
	
	//headCode_ += xTab + "const " + GetClassName() + "& operator[] (" + keyParam + ") const;" + xCrLf;
	//headCode_ += xTab + GetClassName() + "& operator[] (" + keyParam + ");" + xCrLf;
		
	headCode_ += xCrLf;

	//headCode_ += "protected:" + xCrLf;
	//headCode_ += xTab + "void Copy(I" + GetClassName() + GetCardinalityPostfix(classInfo_) + "* source);"  + xCrLf;
	//headCode_ += xCrLf;
}

void CAtlClassMapGenerator::Head_generateSerialization()
{
	headCode_ += xTab + "// serialization" + xCrLf;
	headCode_ += xTab + "//" + xCrLf;
	headCode_ += xTab + "public:" + xCrLf;
	headCode_ += xTab + "virtual bool BuildFromXml(CXMLDOMNode& node);" + xCrLf;
	headCode_ += xTab + "virtual bool AppendToDOMDocument(CXMLDOMDocument2& xmlDoc, CXMLDOMElement& parentElement, bool parentIsValid = true);" + xCrLf;
	headCode_ += xCrLf;
}

void CAtlClassMapGenerator::Head_generateMembers()
{
	CXmlBaseElement* sortKeyMember;
	
	sortKeyMember = classInfo_->GetMember(classInfo_->GetCardinalityInfo()->GetMapSortKey());
	if (sortKeyMember == NULL)
		return;

	headCode_ += xTab + "// inner members" + xCrLf;
	headCode_ += xTab + "//" + xCrLf;
	headCode_ += "protected:" + xCrLf;

	headCode_ += xTab + "map<" + TypeOf(sortKeyMember->GetDataType()) + ", CComObject<"  + GetClassName() + ">* > " + GetCamelCase(classInfo_->GetName()+ GetCardinalityPostfix(classInfo_))  + "_;" + xCrLf;
	headCode_ += xTab + "map<" + TypeOf(sortKeyMember->GetDataType()) + ", CComObject<"  + GetClassName() + ">* >::iterator it_;" + xCrLf;
}

void CAtlClassMapGenerator::Head_generateClassEnd()
{
	headCode_ += xCrLf;
	headCode_ += "};" + xCrLf;
	headCode_ += xCrLf;
}

void CAtlClassMapGenerator::Head_generateIfDefEnd()
{
	headCode_ += "#endif //!defined(" + DefineOf(GetClassName() + GetCardinalityPostfix(classInfo_)) + ")" + xCrLf + xCrLf;
}

void CAtlClassMapGenerator::GenerateImplementation()
{
	string fileName;
	string pathName;

	Impl_generateHeader();
	Impl_generateIncludeSection();
	
	Impl_generateConstructor();
	Impl_generateDestructor();
	Impl_generateMethods();
	Impl_generateSerialization();

	pathName = BuildGeneratedSourcePath() + "src\\";
	fileName = GetClassName() + GetCardinalityPostfix(classInfo_) +  ".cpp";
	SaveFile(pathName + fileName, implCode_);

	cppGeneratedFiles_[fileName] = pathName + fileName;
}

void CAtlClassMapGenerator::Impl_generateHeader()
{
	implCode_ += "// " + GetClassName() + GetCardinalityPostfix(classInfo_) + ".cpp" + xCrLf;
	implCode_ += "// " + xCrLf; 
	implCode_ += GetGenerationTimeStamp();
	implCode_ += "#pragma warning(disable:4786)" + xCrLf;
	implCode_ += xCrLf;
}

void CAtlClassMapGenerator::Impl_generateIncludeSection()
{
	implCode_ += "#include \"stdafx.h\"" + xCrLf;
	implCode_ += "#include \"" + GetClassName() + GetCardinalityPostfix(classInfo_) + ".h\"" + xCrLf;

	ClassMemberMap::iterator it;
	ClassMemberMap* members;
	CXmlBaseElement* member;
	string name;

	members = classInfo_->GetMembers();
	for(it = members->begin(); it != members->end(); it++) {
		member = it->second;
		if (member->GetDataType() == enDataType_Class) {
			CXmlClassInfo* classInfo;

			classInfo = dynamic_cast<CXmlClassInfo*>(member);
			if (classInfo->GetDefinitionInheritance())
				classInfo = dynamic_cast<CXmlClassInfo*>(rootClassInfo_->GetMemberById(classInfo->GetInherithClassId()));

			name = classInfo->GetName();
			implCode_ += "#include \"" + GetClassName(name) + ".h\"" + xCrLf;
		}
	}

	implCode_ +=  xCrLf;
}

void CAtlClassMapGenerator::Impl_generateConstructor()
{
	string p;

	p = GetCardinalityPostfix(classInfo_);

	implCode_ += "string " + GetClassName() + p + "::xmlNodeName_ = \"" + classInfo_->GetName() + p + "\";" + xCrLf;	
	implCode_ += xCrLf;

	// default constructor
	//
	implCode_ += GetClassName() + p + "::" + GetClassName() + p + "()" + xCrLf;
	implCode_ += "{" + xCrLf;
	//implCode_ += xTab + "SetDefaults();" + xCrLf;
	implCode_ += "}" + xCrLf;
	implCode_ += xCrLf;

}

void CAtlClassMapGenerator::Impl_generateDestructor()
{
	string p;

	p = GetCardinalityPostfix(classInfo_);

	implCode_ += GetClassName() + p + "::~" + GetClassName() + p + "()" + xCrLf;
	implCode_ += "{" + xCrLf;
	implCode_ += xTab + "CleanUp();" + xCrLf;
	implCode_ += "}" + xCrLf;
	implCode_ += xCrLf;
}

void CAtlClassMapGenerator::Impl_generateMethods()
{
	CXmlBaseElement* sortKeyMember;
	string p;
	string keyParam;

	sortKeyMember = classInfo_->GetMember(classInfo_->GetCardinalityInfo()->GetMapSortKey());
	if (sortKeyMember == NULL)
		return;

	if (sortKeyMember->GetDataType() == enDataType_String)
		keyParam = "const " + TypeOf(sortKeyMember->GetDataType()) + "& key";
	else
		keyParam = TypeOf(sortKeyMember->GetDataType()) + " key";

	p = GetCardinalityPostfix(classInfo_);

	// Copy
	//
	string mapName;
	string paramName;

	mapName = GetCamelCase(classInfo_->GetName()) + p;
	paramName = GetCamelCase(classInfo_->GetName()) + p;
	implCode_ += "STDMETHODIMP " + GetClassName() + p + "::Copy(I" + GetClassName() + p + "* source)"  + xCrLf;
	implCode_ += "{" + xCrLf;
	implCode_ += xTab + "USES_CONVERSION;" + xCrLf;
	implCode_ += xCrLf;
	implCode_ += xTab + "CleanUp();" + xCrLf;
	implCode_ += xCrLf;
	implCode_ += xTab + "VARIANT_BOOL ret;" + xCrLf;
	if (sortKeyMember->GetDataType() == enDataType_String)
		implCode_ += xTab + "CComBSTR key;" + xCrLf;
	else
		implCode_ += xTab + OleTypeOf(sortKeyMember->GetDataType()) + " key;" + xCrLf;
	implCode_ += xTab + "I" + GetClassName() + "* mapItem;" + xCrLf;
	//implCode_ += xTab + "I" + GetClassName() + "* newItem;" + xCrLf;
	implCode_ += xTab + "CComObject<" + GetClassName() + ">* tmp;" + xCrLf;
	implCode_ += xTab + "HRESULT hRes = 0;" + xCrLf;
	implCode_ += xCrLf;
	implCode_ += xTab + "source->MoveFirst(&ret);" + xCrLf;
	implCode_ += xTab + "while (ret == VARIANT_TRUE) {" + xCrLf;
	implCode_ += xTab + xTab + "source->GetPair(&key, &mapItem, &ret);" + xCrLf;
	implCode_ += xCrLf;
	//implCode_ += xTab + xTab + "tmp = new CComObject<" + GetClassName() + ">;" + xCrLf;
	implCode_ += xTab + xTab + "hRes = CComObject<" + GetClassName() + ">::CreateInstance(&tmp);" + xCrLf;
	implCode_ += xTab + xTab + "tmp->AddRef();" + xCrLf;
	//implCode_ += xTab + xTab + "tmp->QueryInterface(IID_I" + GetClassName() + ", (void**) &newItem);" + xCrLf;
	//implCode_ += xTab + xTab + "newItem->Copy(mapItem);" + xCrLf;
	implCode_ += xTab + xTab + "tmp->Copy(mapItem);" + xCrLf;
	implCode_ += xTab + xTab + "mapItem->Release();" + xCrLf;
	implCode_ += xCrLf;
	implCode_ += xTab + xTab + GetCamelCase(classInfo_->GetName()) + p + "_[W2A(key)] = tmp;" + xCrLf;
	//if (sortKeyMember->GetDataType() == enDataType_String) {
	//	implCode_ += xTab + xTab + "SysFreeString(key);" + xCrLf;
	//}
	implCode_ += xTab + xTab + "source->MoveNext(&ret);" + xCrLf;
	implCode_ += xTab + "}" + xCrLf;
	implCode_ += xTab + "return S_OK;" + xCrLf;
	implCode_ += "}" + xCrLf;
	implCode_ += xCrLf;

	// SetDefaults
	//
	implCode_ += "void " + GetClassName() + p + "::SetDefaults()"  + xCrLf;
	implCode_ += "{" + xCrLf;
	implCode_ += xTab + "RestoreDefaults();" + xCrLf;
	implCode_ += "}" + xCrLf;
	implCode_ += xCrLf;

	// Clear
	//
	implCode_ += "void " + GetClassName() + p +"::Clear()"  + xCrLf;
	implCode_ += "{" + xCrLf;
	implCode_ += xTab + "CleanUp();" + xCrLf;
	implCode_ += "}" + xCrLf;
	implCode_ += xCrLf;

	// RestoreDefaults
	//
	implCode_ += "STDMETHODIMP " + GetClassName() + p + "::RestoreDefaults()"  + xCrLf;
	implCode_ += "{" + xCrLf;
	implCode_ += xTab + "return S_OK;" + xCrLf;
	implCode_ += "}" + xCrLf;
	implCode_ += xCrLf;

	// CleanUp
	//
	implCode_ += "STDMETHODIMP " + GetClassName() + p +"::CleanUp()"  + xCrLf;
	implCode_ += "{" + xCrLf;
	implCode_ += xTab + "map<" + TypeOf(sortKeyMember->GetDataType()) + ", CComObject<" + GetClassName() + ">* >::iterator it;" + xCrLf;
	implCode_ += xCrLf;
	implCode_ += xTab + "for(it = " + mapName + "_.begin(); it != " + mapName + "_.end(); it++) {" + xCrLf;
	implCode_ += xTab + xTab + "it->second->CleanUp();" + xCrLf;
	implCode_ += xTab + xTab + "it->second->Release();" + xCrLf;
	implCode_ += xTab + "}" + xCrLf;
	implCode_ += xTab + mapName + "_.clear();" + xCrLf;
	implCode_ += xCrLf;
	implCode_ += xTab + "return S_OK;" + xCrLf;
	implCode_ += "}" + xCrLf;
	implCode_ += xCrLf;

	// GetSize
	//
	implCode_ += "STDMETHODIMP " + GetClassName() + p +"::GetSize(long* retval)"  + xCrLf;
	implCode_ += "{" + xCrLf;
	implCode_ += xTab + "*retval = " + GetCamelCase(classInfo_->GetName()) + p + "_.size();" + xCrLf;
	implCode_ += xTab + "return S_OK;" + xCrLf;
	implCode_ += "}" + xCrLf;
	implCode_ += xCrLf;

	// ReplaceKey
	//
	implCode_ += "STDMETHODIMP " + GetClassName() + p +"::ReplaceKey(BSTR currentKey, BSTR newKey)"  + xCrLf;
	implCode_ += "{" + xCrLf;
	implCode_ += xTab + "USES_CONVERSION;" + xCrLf;
	implCode_ += xCrLf;
	implCode_ += xTab + "map<" + TypeOf(sortKeyMember->GetDataType()) + ", CComObject<" + GetClassName() + ">* >::iterator it;" + xCrLf;
	implCode_ += xTab + "CComObject<" + GetClassName() + ">* tmp;" + xCrLf;
	implCode_ += xCrLf;
	implCode_ += xTab + "// check if new key is already used by another element" + xCrLf;
	implCode_ += xTab + "//" + xCrLf;
	implCode_ += xTab + "it = " + mapName + "_.find(W2A(newKey));" + xCrLf;
	implCode_ += xTab + "if (it != " + mapName + "_.end())" + xCrLf;
	implCode_ += xTab + xTab + "return S_OK;" + xCrLf;
	implCode_ += xCrLf;
	implCode_ += xTab + "// check if current key exists" + xCrLf;
	implCode_ += xTab + "//" + xCrLf;
	implCode_ += xTab + "it = " + mapName + "_.find(W2A(currentKey));" + xCrLf;
	implCode_ += xTab + "if (it == " + mapName + "_.end())" + xCrLf;
	implCode_ += xTab + xTab + "return S_OK;" + xCrLf;
	implCode_ += xCrLf;
	implCode_ += xTab + "tmp = it->second;" + xCrLf;
	implCode_ += xTab + mapName + "_.erase(W2A(currentKey));" + xCrLf;
	implCode_ += xTab + mapName + "_[W2A(newKey)] = tmp;" + xCrLf;
	implCode_ += xTab + "tmp->put_" + sortKeyMember->GetName() + "(newKey);" + xCrLf;
	implCode_ += xCrLf;
	implCode_ += xTab + "return S_OK;" + xCrLf;
	implCode_ += "}" + xCrLf;
	implCode_ += xCrLf;

	// Insert
	//
	paramName = GetCamelCase(classInfo_->GetName());
	implCode_ += "STDMETHODIMP " + GetClassName() + p +"::Insert(I" + GetClassName() + "* item)" + xCrLf;
	implCode_ += "{" + xCrLf;
	implCode_ += xTab + "USES_CONVERSION;" + xCrLf;
	implCode_ += xCrLf;
	implCode_ += xTab + "CComObject<" + GetClassName() + ">* newItem;" + xCrLf;
	if (sortKeyMember->GetDataType() == enDataType_String)
		implCode_ += xTab + "CComBSTR key;" + xCrLf;
	else
		implCode_ += xTab + OleTypeOf(sortKeyMember->GetDataType()) + " key;" + xCrLf;

	implCode_ += xTab + "HRESULT hRes = 0;" + xCrLf;
	implCode_ += xCrLf;
	//implCode_ += xTab + "newItem = new CComObject<" + GetClassName() + ">;" + xCrLf;
	implCode_ += xTab + "hRes = CComObject<" + GetClassName() + ">::CreateInstance(&newItem);" + xCrLf;
	implCode_ += xTab + "newItem->AddRef();" + xCrLf;
	implCode_ += xTab + "newItem->Copy(item);" + xCrLf;
	implCode_ += xTab + "newItem->get_" + sortKeyMember->GetName() + "(&key);" + xCrLf;
	implCode_ += xTab + mapName + "_[W2A(key)] = newItem;" + xCrLf;
	//if (sortKeyMember->GetDataType() == enDataType_String)
	//	implCode_ += xTab + "SysFreeString(key);" + xCrLf;
	implCode_ += xTab + "return S_OK;" + xCrLf;
	implCode_ += "}" + xCrLf;
	implCode_ += xCrLf;

	// Delete
	//
	implCode_ += "STDMETHODIMP " + GetClassName() + p +"::Delete(" + OleTypeOf(sortKeyMember->GetDataType()) + " key)" + xCrLf;
	implCode_ += "{" + xCrLf;
	implCode_ += xTab + "USES_CONVERSION;" + xCrLf;
	implCode_ += xCrLf;
	implCode_ += xTab + "map<" + TypeOf(sortKeyMember->GetDataType()) + ", CComObject<" + GetClassName() + ">* >::iterator it;" + xCrLf;
	implCode_ += xCrLf;
	implCode_ += xTab + "it = " + mapName + "_.find(W2A(key));" + xCrLf;
	implCode_ += xTab + "if (it != " + mapName + "_.end()) {" + xCrLf;
	implCode_ += xTab + xTab + "it->second->Release();" + xCrLf;
	implCode_ += xTab + xTab + mapName + "_.erase(W2A(key));" + xCrLf;
	implCode_ += xTab + "}" + xCrLf;
	implCode_ += xTab + "return S_OK;" + xCrLf;
	implCode_ += "}" + xCrLf;
	implCode_ += xCrLf;

	// MoveFirst
	//
	implCode_ += "STDMETHODIMP " + GetClassName() + p +"::MoveFirst(VARIANT_BOOL* retval)"  + xCrLf;
	implCode_ += "{" + xCrLf;
	implCode_ += xTab + "it_ = " + mapName + "_.begin();" + xCrLf;
	implCode_ += xCrLf;
	implCode_ += xTab + "*retval = (" + mapName + "_.size() != 0) ? VARIANT_TRUE : VARIANT_FALSE;" + xCrLf;
	implCode_ += xCrLf;
	implCode_ += xTab + "return S_OK;" + xCrLf;
	implCode_ += "}" + xCrLf;
	implCode_ += xCrLf;

	// MoveNext
	//
	implCode_ += "STDMETHODIMP " + GetClassName() + p +"::MoveNext(VARIANT_BOOL* retval)"  + xCrLf;
	implCode_ += "{" + xCrLf;
	implCode_ += xTab + "it_++;" + xCrLf;
	implCode_ += xCrLf;
	implCode_ += xTab + "*retval = (it_ != " + mapName + "_.end()) ? VARIANT_TRUE : VARIANT_FALSE;" + xCrLf;
	implCode_ += xCrLf;
	implCode_ += xTab + "return S_OK;" + xCrLf;
	implCode_ += "}" + xCrLf;
	implCode_ += xCrLf;
	
	// GetPair
	//
	implCode_ += "STDMETHODIMP " + GetClassName() + p +"::GetPair(" + OleTypeOf(sortKeyMember->GetDataType()) + "* key, I" + GetClassName() + "** item, VARIANT_BOOL* retval)"  + xCrLf;
	implCode_ += "{" + xCrLf;
	implCode_ += xTab + "USES_CONVERSION;" + xCrLf;
	implCode_ += xCrLf;
	implCode_ += xTab + "if (it_ != " + mapName + "_.end()) {" + xCrLf;
	implCode_ += xTab + xTab + "CComObject<" + GetClassName() + ">* tmp;" + xCrLf;
	if (sortKeyMember->GetDataType() == enDataType_String) {
		implCode_ += xTab + xTab + "string tmpKey;" + xCrLf;
		implCode_ += xCrLf;
		implCode_ += xTab + xTab + "tmpKey = it_->first;" + xCrLf;
		implCode_ += xTab + xTab + "*key = ::SysAllocString(A2W(tmpKey.c_str()));" + xCrLf;
	} else {
		implCode_ += xCrLf;
		implCode_ += xTab + xTab + "*key = it_->first" + xCrLf; 
	}
	implCode_ += xTab + xTab + "tmp = it_->second;" + xCrLf;
	implCode_ += xTab + xTab + "tmp->QueryInterface(IID_I" + GetClassName(classInfo_->GetName()) + ", (void**) item);" + xCrLf;
	implCode_ += xTab + xTab + "*retval = VARIANT_TRUE;" + xCrLf;
	implCode_ += xTab + "} else {" + xCrLf;
	implCode_ += xTab + xTab + "*retval = VARIANT_FALSE;" + xCrLf;
	implCode_ += xTab + "}" + xCrLf;
	implCode_ += xCrLf;
	implCode_ += xTab + "return S_OK;" + xCrLf;
	implCode_ += "}" + xCrLf;
	implCode_ += xCrLf;

	// FindItem
	//
	implCode_ += "STDMETHODIMP " + GetClassName() + p +"::FindItem(" + OleTypeOf(sortKeyMember->GetDataType()) + " key, I" + GetClassName() + "** item)"  + xCrLf;
	implCode_ += "{" + xCrLf;
	implCode_ += xTab + "USES_CONVERSION;" + xCrLf;
	implCode_ += xCrLf;
	implCode_ += xTab + "map<" + TypeOf(sortKeyMember->GetDataType()) + ", CComObject<" + GetClassName() + ">* >::iterator it;" + xCrLf;
	implCode_ += xCrLf;
	implCode_ += xTab + "it = " + mapName + "_.find(W2A(key));" + xCrLf;
	implCode_ += xTab + "if (it != " + mapName + "_.end()) {" + xCrLf;
	implCode_ += xTab + xTab + "CComObject<" + GetClassName() + ">* tmp;" + xCrLf;
	implCode_ += xCrLf;
	implCode_ += xTab + xTab + "tmp = it->second;" + xCrLf;
	implCode_ += xTab + xTab + "tmp->QueryInterface(IID_I" + GetClassName(classInfo_->GetName()) + ", (void**) item);" + xCrLf;
	implCode_ += xTab + "} else {" + xCrLf;
	implCode_ += xTab + xTab + "*item = NULL;" + xCrLf;
	implCode_ += xTab + "}" + xCrLf;
	implCode_ += xCrLf;
	implCode_ += xTab + "return S_OK;" + xCrLf;
	implCode_ += "}" + xCrLf;
	implCode_ += xCrLf;

	//////////////////////////////////////////////////////////////////////
	// loadFromFile
	//
	implCode_ += "STDMETHODIMP " + GetClassName() + p + "::Load(BSTR fileName, VARIANT_BOOL* retval)" + xCrLf;
	implCode_ += "{" + xCrLf;
	implCode_ += xTab + "USES_CONVERSION;" + xCrLf;
	implCode_ += xCrLf;
	implCode_ += xTab + "bool ret;" + xCrLf;
	implCode_ += xCrLf;
	implCode_ += xTab + "ret = LoadFromXmlFile(W2A(fileName));" + xCrLf;
	implCode_ += xTab + "*retval = ret ? VARIANT_TRUE : VARIANT_FALSE;" + xCrLf;
	implCode_ += xCrLf;
	implCode_ += xTab + "return S_OK;" + xCrLf;
	implCode_ += "}" + xCrLf;
	implCode_ += xCrLf;

	//////////////////////////////////////////////////////////////////////
	// saveToFile
	//
	implCode_ += "STDMETHODIMP " + GetClassName() + p + "::Save(BSTR fileName, VARIANT_BOOL* retval)" + xCrLf;
	implCode_ += "{" + xCrLf;
	implCode_ += xTab + "USES_CONVERSION;" + xCrLf;
	implCode_ += xCrLf;
	implCode_ += xTab + "bool ret;" + xCrLf;
	implCode_ += xCrLf;
	implCode_ += xTab + "ret = SaveToXmlFile(W2A(fileName));" + xCrLf;
	implCode_ += xTab + "*retval = ret ? VARIANT_TRUE : VARIANT_FALSE;" + xCrLf;
	implCode_ += xCrLf;
	implCode_ += xTab + "return S_OK;" + xCrLf;
	implCode_ += "}" + xCrLf;
	implCode_ += xCrLf;
}

void CAtlClassMapGenerator::Impl_generateSerialization()
{
	ClassMemberMap::iterator it;
	CXmlBaseElement* member;
	string mapName;
	string sortKey;
	string p;

	p = GetCardinalityPostfix(classInfo_);
	mapName = GetCamelCase(classInfo_->GetName()) + p;
	sortKey = "newChildElement.Get" + classInfo_->GetCardinalityInfo()->GetMapSortKey() + "()";
	member = classInfo_->GetMember(classInfo_->GetCardinalityInfo()->GetMapSortKey());

	//////////////////////////////////////////////////////////////////////
	// BuildFromXml
	//
	implCode_ += "bool " + GetClassName() + p +"::BuildFromXml(CXMLDOMNode& node)" + xCrLf;
	implCode_ += "{" + xCrLf;
	implCode_ += xTab + "USES_CONVERSION;" + xCrLf + xCrLf;

	implCode_ += xTab + "CXMLDOMNode childNode;" + xCrLf;
    implCode_ += xTab + "CXMLDOMNodeList children;" + xCrLf;
	implCode_ += xTab + "string nodeName;" + xCrLf;
	if (member->GetDataType() == enDataType_String)
		implCode_ += xTab + "CComBSTR key;" + xCrLf;
	else
		implCode_ += xTab + OleTypeOf(member->GetDataType()) + " key;" + xCrLf;
	implCode_ += xTab + "CComObject<" + GetClassName() + ">* newItem;" + xCrLf;
	implCode_ += xTab + "HRESULT hRes = 0;" + xCrLf;
	implCode_ += xCrLf;
	implCode_ += xTab + "RestoreDefaults();" + xCrLf;
	implCode_ += xTab + xCrLf;

	implCode_ += xTab + "children = node.GetChildNodes();" + xCrLf;
	
	implCode_ += xTab + "for (long i = 0; i < children.GetLength(); i++) {" + xCrLf;
	implCode_ += xTab + xTab + "childNode = children.GetItem(i);" + xCrLf;
	
	implCode_ += xTab + xTab + "nodeName = childNode.GetNodeName();" + xCrLf;

	implCode_ += xTab + xTab + "if (nodeName == " + GetClassName() + "::xmlNodeName_) {" + xCrLf;
	//implCode_ += xTab + xTab + xTab + "newItem = new CComObject<" + GetClassName() + ">;" + xCrLf;
	implCode_ += xTab + xTab + xTab + "hRes = CComObject<" + GetClassName() + ">::CreateInstance(&newItem);" + xCrLf;
	implCode_ += xTab + xTab + xTab + "newItem->AddRef();" + xCrLf;
	implCode_ += xTab + xTab + xTab + "newItem->BuildFromXml(childNode);" + xCrLf;
	implCode_ += xTab + xTab + xTab + "newItem->get_" + member->GetName() + "(&key);" + xCrLf;
	implCode_ += xTab + xTab + xTab + mapName + "_[W2A(key)] = newItem;" + xCrLf;
	implCode_ += xTab + xTab + "}" + xCrLf;
	implCode_ += xCrLf;
	implCode_ += xTab + "}" + xCrLf + xCrLf;

	implCode_ += xTab + "return true;" + xCrLf;

	implCode_ += "}" + xCrLf + xCrLf;

	//////////////////////////////////////////////////////////////////////
	// AppendToDOMDocument
	//
	implCode_ += "bool " + GetClassName() + p + "::AppendToDOMDocument(CXMLDOMDocument2& xmlDoc, CXMLDOMElement& parentElement, bool parentIsValid)" + xCrLf;
	implCode_ += "{" + xCrLf;
	implCode_ += xTab + "CXMLDOMElement newElement;" + xCrLf;
    implCode_ += xTab + "CXMLDOMElement rectElement;" + xCrLf;
	implCode_ += xTab + "CXMLDOMElement member;" + xCrLf;
   	implCode_ += xTab + "map<" + TypeOf(member->GetDataType()) + ", CComObject<"  + GetClassName() + ">* >::iterator it;" + xCrLf;
    implCode_ += xCrLf;
	implCode_ += xTab + "newElement = xmlDoc.CreateElement(GetXmlNodeName().c_str());" + xCrLf;
		
	implCode_ += xTab + "for (it = " + mapName + "_.begin(); it != " + mapName + "_.end(); it++) {" + xCrLf;
	implCode_ += xTab + xTab + "it->second->AppendToDOMDocument(xmlDoc, newElement);" + xCrLf;
	implCode_ += xTab + "}" + xCrLf;
	implCode_ += xCrLf;
	
	implCode_ += xTab + "if (!parentIsValid)" + xCrLf;
    implCode_ += xTab + xTab + "xmlDoc.AppendChild(newElement);" + xCrLf;
	implCode_ += xTab + "else" + xCrLf;
    implCode_ += xTab + xTab + "parentElement.AppendChild(newElement);" + xCrLf + xCrLf;
	implCode_ += xTab + "return true;" + xCrLf;
	implCode_ += "}" + xCrLf + xCrLf;

	
}

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, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Web Developer
Italy Italy
For all Stefano's latest code, binaries and tutorials visit www.codemachines.com

Comments and Discussions