in src/codegen/tool/GenerateCppLibrary.cpp [868:1037]
void CGenerateCppLibrary::emitMethodHandler(
std::wostream& osMethodHandler,
std::wostream& osAbstractMethods,
const schema::CMethodInfo*pMethodInfo,
bool isPublic)
{
bool hasResult = pMethodInfo->getResultType() && pMethodInfo->getResultType()->getPropertyType() != foundation::PropertyType_Empty;
osMethodHandler << "\t\t\tcase " << toTypeInfoName(pMethodInfo->getParent().getName()) << "::Method_" << pMethodInfo->getName() << ":" << std::endl;
osMethodHandler << "\t\t\t{" << std::endl;
// Emit macro parameters check
osMethodHandler << "\t\t\t\t";
if (pMethodInfo->getParameters().size() == 0)
{
osMethodHandler << "IFCEXPECT(parameters==nullptr || size==0);";
}
else
{
osMethodHandler << "IFCEXPECT(size==" << pMethodInfo->getParameters().size() << ");";
}
osMethodHandler << std::endl;
// Emit result holder
if (hasResult && !pMethodInfo->getIsAsync())
{
osMethodHandler << "\t\t\t\t";
emitModelTypeVarDeclare(osMethodHandler, pMethodInfo->getResultType(), L"result");
}
std::wstring invokeInstance;
std::wstring methodNameCallback = this->getMethodCallback(pMethodInfo, invokeInstance);
osAbstractMethods << "\tvirtual HRESULT " << methodNameCallback << "(";
std::wostringstream osClassMethodInvoke;
osClassMethodInvoke << "\t\t\t\t";
osClassMethodInvoke << "hr = " << invokeInstance << "->" << methodNameCallback << "(";
int parameterIndex = 1;
for (schema::_MethodParamIteratorType::const_iterator iterParam = pMethodInfo->getParameters().begin();
iterParam != pMethodInfo->getParameters().end();
++iterParam)
{
bool isParameterArray = ((*iterParam)->getPropertyType() & 0x400) != 0;
// Emit Virtual abstract params
if (iterParam != pMethodInfo->getParameters().begin())
{
osAbstractMethods << ",";
osClassMethodInvoke << ",";
}
emitModelPropertyTypeInfo(osAbstractMethods, (*iterParam), false, parameterIndex);
osAbstractMethods << " " << (*iterParam)->getParameterName();
// Emit Var declares
osMethodHandler << "\t\t\t\t";
std::wstring varName = L"_" + (*iterParam)->getParameterName();
emitModelTypeVarDeclare(osMethodHandler, (*iterParam), varName.data());
osMethodHandler << std::endl;
osMethodHandler << "\t\t\t\t";
osMethodHandler << "IFHR(" << getFoundationNamespace() << "::pv_util::GetValue(parameters[";
osMethodHandler << (int)(iterParam - pMethodInfo->getParameters().begin());
osMethodHandler << "],";
emitDelegateTypeVarAddress(osMethodHandler, *iterParam, varName.data());
osMethodHandler << "));" << std::endl;
// Add to Class Invoke method
if (isParameterArray)
{
osClassMethodInvoke << varName << ".GetSize(),";
// use Cast to avoid (const) prefix on GetBuffer
osClassMethodInvoke << "(";
emitPropertyTypeInfo(osClassMethodInvoke, (*iterParam));
osClassMethodInvoke << ")";
}
osClassMethodInvoke << varName;
if (isParameterArray)
{
osClassMethodInvoke << ".GetBuffer()";
}
++parameterIndex;
}
if ((hasResult || pMethodInfo->getIsAsync()) && pMethodInfo->getParameters().size())
{
osAbstractMethods << ",";
osClassMethodInvoke << ",";
}
bool isResultArray = (pMethodInfo->getResultType()->getPropertyType() & 0x400) != 0;
if (pMethodInfo->getIsAsync())
{
if (isPublic)
{
auto asyncResultType = toPropertyTypeInfoAsync(pMethodInfo->getResultType(), true);
osAbstractMethods << asyncResultType << "**ppResult";
osClassMethodInvoke << "reinterpret_cast<" << asyncResultType << "**>(*ppResult)";
}
else
{
emitAsyncOperationClassDeclare(osAbstractMethods);
osClassMethodInvoke << "reinterpret_cast<" << getFoundationNamespace() << "::library::IAsyncOperationClass *>(*ppResult)";
}
}
else if (hasResult)
{
emitModelPropertyTypeInfo(osAbstractMethods, pMethodInfo->getResultType(), true);
osAbstractMethods << " pResult";
emitDelegateTypeVarAddress(osClassMethodInvoke, pMethodInfo->getResultType(), L"result");
}
osAbstractMethods << ")\n"
<< "\t{\n"
<< "\t\tfoundation_assert(false);\n"
<< "\t\treturn E_NOTIMPL;\n"
<< "\t}\n" << std::endl;
osClassMethodInvoke << ");" << std::endl;
osMethodHandler << osClassMethodInvoke.str().data();
if (hasResult && !pMethodInfo->getIsAsync())
{
osMethodHandler << "\t\t\t\t";
osMethodHandler << "if(SUCCEEDED(hr))" << std::endl;
osMethodHandler << "\t\t\t\t";
osMethodHandler << "{" << std::endl;
osMethodHandler << "\t\t\t\t\t";
if (isUseWrapperDelegatePropertyTypeInfo(pMethodInfo->getResultType()))
{
if (isResultArray)
{
osMethodHandler << "*ppResult = foundation::CreateValue(result).Detach();" << std::endl;
}
else
{
osMethodHandler << "*ppResult = result.Detach();" << std::endl;
}
}
else
{
osMethodHandler << "*ppResult = " << getFoundationNamespace() << "::CreateValue(";
if (isResultArray)
{
osMethodHandler << "result.GetSize(),";
// use Cast to avoid (const) prefix on GetBuffer
osMethodHandler << "(";
emitPropertyTypeInfo(osMethodHandler, (pMethodInfo->getResultType()));
osMethodHandler << ")";
osMethodHandler << "result.GetBuffer()";
}
else
{
osMethodHandler << "result";
}
osMethodHandler << ").Detach();" << std::endl;
}
osMethodHandler << "\t\t\t\t";
osMethodHandler << "}" << std::endl;
}
osMethodHandler << "\t\t\t}" << std::endl;
osMethodHandler << "\t\t\tbreak;" << std::endl;
}