Ejemplo n.º 1
0
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);
			}
		}
			
	}
}
Ejemplo n.º 2
0
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;
}