// 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;
}