void XSDGenerator::deepCopyMembers(const Poco::CppParser::Struct* pIn, Poco::CppParser::Struct* pOut) { // deep copy all variables and functions, exluding constructor/destructor Poco::CppParser::Struct::BaseIterator itB = pIn->baseBegin(); Poco::CppParser::Struct::BaseIterator itBEnd = pIn->baseEnd(); for (; itB!= itBEnd; ++itB) { if (itB->pClass) deepCopyMembers(itB->pClass, pOut); } // handle members Poco::CppParser::NameSpace::SymbolTable members; pIn->variables(members); Poco::CppParser::NameSpace::SymbolTable::const_iterator it = members.begin(); Poco::CppParser::NameSpace::SymbolTable::const_iterator itEnd = members.end(); for (; it != itEnd; ++it) { Poco::CppParser::Variable* pVar = static_cast<Poco::CppParser::Variable*>(it->second); Poco::CppParser::Variable* pCpyVar = new Poco::CppParser::Variable(pVar->declaration(), pOut); pCpyVar->setAccess(pVar->getAccess()); pCpyVar->setAttributes(pVar->getAttributes()); } // handle methods members.clear(); Poco::CppParser::Struct::Functions fcts; pIn->methods(Poco::CppParser::Symbol::ACC_PUBLIC, fcts); Poco::CppParser::Struct::Functions::const_iterator itt = fcts.begin(); Poco::CppParser::Struct::Functions::const_iterator ittEnd = fcts.end(); for (; itt != ittEnd; ++itt) { Poco::CppParser::Function* pFct = static_cast<Poco::CppParser::Function*>(*itt); if (!pFct->isConstructor() && ! pFct->isDestructor()) { Poco::CppParser::Function* pCpyFct = new Poco::CppParser::Function(pFct->declaration(), pOut); pCpyFct->setAccess (pFct->getAccess()); addDocumentation(pFct, pCpyFct); pCpyFct->setAttributes(pFct->getAttributes()); if (pFct->isConst()) pCpyFct->makeConst(); Poco::CppParser::Function::Iterator itF = pFct->begin(); Poco::CppParser::Function::Iterator itFEnd = pFct->end(); for (; itF != itFEnd; ++itF) { std::string decl = Poco::CodeGeneration::Utility::resolveParamDecl(pIn, *itF); if ((*itF)->hasDefaultValue()) { decl.append(" = "); decl.append(Poco::CodeGeneration::Utility::resolveType(_pStructIn, (*itF)->declType())); decl.append("("); decl.append((*itF)->defaultValue()); decl.append(")"); } Poco::CppParser::Parameter* pParam = new Poco::CppParser::Parameter(decl, pCpyFct); pCpyFct->addParameter(pParam); } } } }
Poco::CppParser::Struct* XSDGenerator::convertToStruct(const Poco::CppParser::Function* pFunc, bool isResponse) { /// a type created by function parameters can never extend any other type std::string inputDataType; if (isResponse) inputDataType = GenUtility::getReplyMethodName(pFunc); else inputDataType = GenUtility::getRequestMethodName(pFunc); std::string decl(Poco::CodeGeneration::Utility::CLASS); decl.append(" "); decl.append(inputDataType); Poco::CppParser::Struct* pStruct = new Poco::CppParser::Struct(decl, true, &_ns); // now add for each param a set and get method, // also add a variable for each param (set the docu!!!!) // don't forget the return value! // return parameter std::string rdecl = pFunc->getReturnParameter(); if (!rdecl.empty() && rdecl != "void" && isResponse) { // if we have an inline type we must fetch the struct for that type // and add all children of that type as direct members of pStruct // or simply inherit from it :-) bool isInline = GenUtility::getInlineReturnParam(pFunc); if (isInline) { std::string fullResType = GenUtility::getResolvedReturnParameterType(pFunc->nameSpace(), pFunc); std::string resType(fullResType); //restype can either be a native type or a complex type which we serialize, or it can be hidden inside a template like vector, set,... SharedPtr bool isPtrType = GenUtility::isPtrType(resType); if (isPtrType) { std::vector<std::string> inn = GenUtility::getInnerTemplateTypes(resType); poco_assert (inn.size() == 1); resType = inn[0]; } bool isVectorOrNullable = GenUtility::isVectorType(resType) || GenUtility::isNullableType(resType) || GenUtility::isOptionalType(resType); if (isVectorOrNullable) { throw Poco::LogicException(pFunc->fullName() + ": For an inlined data type maxOccurs must be 1! No vector/set/multiset allowed"); } if (AbstractGenerator::BUILTIN_TYPES.find(resType) != AbstractGenerator::BUILTIN_TYPES.end()) { throw Poco::LogicException(pFunc->fullName() + ": Only complex data types can be inlined!"); } // now get the class definition for that file Poco::CppParser::Symbol* pSym = pFunc->nameSpace()->lookup(resType); if (pSym && pSym->kind() == Poco::CppParser::Symbol::SYM_STRUCT) { Poco::CppParser::Struct* pRetStruct = static_cast<Poco::CppParser::Struct*>(pSym); // deep copy members pRetStruct deepCopyMembers(pRetStruct, pStruct); } else throw Poco::LogicException("Failed to find data type for inlined return value in method: " + pFunc->fullName()); } else { std::string retParamName (GenUtility::getReturnParameterName(pFunc)); rdecl.append(" " + retParamName); Poco::CppParser::Parameter p(rdecl, 0); Poco::CppParser::Variable* pVar = createVariable(&p, pStruct); Poco::CppParser::Attributes attr; attr["order"] = "0"; pVar->setAttributes(attr); //pVar->setDocumentation("///[[order=0]]"); createGetFct(&p, pStruct); createSetFct(&p, pStruct); } } Poco::CppParser::Function::Iterator it = pFunc->begin(); Poco::CppParser::Function::Iterator itEnd = pFunc->end(); Poco::UInt32 unknownOrderOffset = 0xffff0000; CodeGenerator::Properties funcProps; GeneratorEngine::parseProperties(pFunc, funcProps); for (; it != itEnd; ++it) { std::string direction; CodeGenerator::Properties::iterator itProp = funcProps.find("$" + (*it)->name()); if (itProp != funcProps.end()) { CodeGenerator::Properties paramProps; // we need direction GeneratorEngine::parseElementProperties(itProp->second, paramProps); GeneratorEngine::getStringProperty(paramProps, Utility::DIRECTION, direction); } //isOutParam excludes soapheader already, do the same for replies bool inSoapHeader = GenUtility::getIsInHeader(pFunc, *it); if ( (isResponse && isOutParameter(*it) && direction != "in") || (!isResponse && !inSoapHeader && direction != "out")) { Poco::CppParser::Variable* pVar = createVariable(*it, pStruct); addVarDocu(pVar, pFunc, (*it)->name(), unknownOrderOffset++); createGetFct(*it, pStruct); createSetFct(*it, pStruct); } else if (inSoapHeader) { // Note: we must export for each soapHeader an element that has the same name as the parameter! Poco::CppParser::Parameter* pParam = *it; const std::string& declType = pParam->declType(); std::string name = GenUtility::getParameterName(pFunc, pParam); std::string aType = Poco::CodeGeneration::Utility::resolveType(pFunc->nameSpace(), declType); if (aType == declType) { _exportSoapHeaderTypes.insert (std::make_pair(name, aType)); } else { Poco::CppParser::Symbol* pSym = pFunc->nameSpace()->lookup(aType); poco_assert (pSym); _exportSoapHeaderTypes.insert (std::make_pair(name, pSym->name())); } } } return pStruct; }