void CGenerateCppLibrary::emitMethodHandler()

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