diff options
Diffstat (limited to 'cpp/src/slice2cpp/Gen.cpp')
-rw-r--r-- | cpp/src/slice2cpp/Gen.cpp | 1073 |
1 files changed, 849 insertions, 224 deletions
diff --git a/cpp/src/slice2cpp/Gen.cpp b/cpp/src/slice2cpp/Gen.cpp index 18369db167e..83198bcdd8e 100644 --- a/cpp/src/slice2cpp/Gen.cpp +++ b/cpp/src/slice2cpp/Gen.cpp @@ -223,10 +223,7 @@ Slice::Gen::generate(const UnitPtr& p) { H << "\n#include <Ice/Object.h>"; H << "\n#include <Ice/Outgoing.h>"; - if(p->hasContentsWithMetaData("ami")) - { - H << "\n#include <Ice/OutgoingAsync.h>"; - } + H << "\n#include <Ice/OutgoingAsync.h>"; H << "\n#include <Ice/Incoming.h>"; if(p->hasContentsWithMetaData("amd")) { @@ -247,6 +244,7 @@ Slice::Gen::generate(const UnitPtr& p) { H << "\n#include <Ice/FactoryTableInit.h>"; } + H << "\n#include <IceUtil/ScopedArray.h>"; if(p->usesNonLocals()) { @@ -277,7 +275,6 @@ Slice::Gen::generate(const UnitPtr& p) } C << "\n#include <IceUtil/Iterator.h>"; - C << "\n#include <IceUtil/ScopedArray.h>"; StringList includes = p->includeFiles(); @@ -347,6 +344,15 @@ Slice::Gen::generate(const UnitPtr& p) AsyncImplVisitor asyncImplVisitor(H, C, _dllExport); p->visit(&asyncImplVisitor, false); + // + // The templates are emitted before the proxy definition + // so the derivation hierarchy is known to the proxy: + // the proxy relies on knowing the hierarchy to make the begin_ + // methods type-safe. + // + AsyncCallbackVisitor asyncCallbackVisitor(H, C, _dllExport); + p->visit(&asyncCallbackVisitor, false); + ProxyVisitor proxyVisitor(H, C, _dllExport); p->visit(&proxyVisitor, false); @@ -367,6 +373,15 @@ Slice::Gen::generate(const UnitPtr& p) StreamVisitor streamVistor(H, C); p->visit(&streamVistor, false); } + + // + // We need to delay generating the template after the proxy + // definition, because __completed calls the begin_ method in the + // proxy. + // + AsyncCallbackTemplateVisitor asyncCallbackTemplateVisitor(H, C, _dllExport); + p->visit(&asyncCallbackTemplateVisitor, false); + if(_impl) { implH << "\n#include <"; @@ -514,7 +529,7 @@ Slice::Gen::TypesVisitor::visitExceptionStart(const ExceptionPtr& p) for(q = allDataMembers.begin(); q != allDataMembers.end(); ++q) { - string typeName = inputTypeToString((*q)->type(), _useWstring, (*q)->getMetaData()); + string typeName = inputTypeToString((*q)->type(), (*q)->getMetaData(), _useWstring); allTypes.push_back(typeName); allParamDecls.push_back(typeName + " __ice_" + fixKwd((*q)->name())); } @@ -765,8 +780,8 @@ Slice::Gen::TypesVisitor::visitExceptionEnd(const ExceptionPtr& p) C << nl << "__outS->startSlice();"; for(q = dataMembers.begin(); q != dataMembers.end(); ++q) { - writeStreamMarshalUnmarshalCode(C, (*q)->type(), (*q)->name(), true, "", _useWstring, - (*q)->getMetaData()); + writeStreamMarshalUnmarshalCode(C, (*q)->type(), (*q)->name(), true, "", (*q)->getMetaData(), + _useWstring); } C << nl << "__outS->endSlice();"; if(base) @@ -785,8 +800,8 @@ Slice::Gen::TypesVisitor::visitExceptionEnd(const ExceptionPtr& p) C << nl << "__inS->startSlice();"; for(q = dataMembers.begin(); q != dataMembers.end(); ++q) { - writeStreamMarshalUnmarshalCode(C, (*q)->type(), (*q)->name(), false, "", _useWstring, - (*q)->getMetaData()); + writeStreamMarshalUnmarshalCode(C, (*q)->type(), (*q)->name(), false, "", (*q)->getMetaData(), + _useWstring); } C << nl << "__inS->endSlice();"; if(base) @@ -911,7 +926,7 @@ Slice::Gen::TypesVisitor::visitStructStart(const StructPtr& p) string name = fixKwd(p->name()); - if(findMetaData(p->getMetaData(), false) == "class") + if(findMetaData(p->getMetaData()) == "class") { H << sp << nl << "class " << _dllExport << name << " : public IceUtil::Shared"; H << sb; @@ -929,7 +944,7 @@ Slice::Gen::TypesVisitor::visitStructStart(const StructPtr& p) vector<string> types; for(q = dataMembers.begin(); q != dataMembers.end(); ++q) { - string typeName = inputTypeToString((*q)->type(), _useWstring, (*q)->getMetaData()); + string typeName = inputTypeToString((*q)->type(), (*q)->getMetaData(), _useWstring); types.push_back(typeName); paramDecls.push_back(typeName + " __ice_" + (*q)->name()); } @@ -988,7 +1003,7 @@ Slice::Gen::TypesVisitor::visitStructEnd(const StructPtr& p) } string dllExport; - if(findMetaData(p->getMetaData(), false) != "class") + if(findMetaData(p->getMetaData()) != "class") { dllExport = _dllExport; } @@ -1099,8 +1114,8 @@ Slice::Gen::TypesVisitor::visitStructEnd(const StructPtr& p) C << sb; for(q = dataMembers.begin(); q != dataMembers.end(); ++q) { - writeStreamMarshalUnmarshalCode(C, (*q)->type(), (*q)->name(), true, "", _useWstring, - (*q)->getMetaData()); + writeStreamMarshalUnmarshalCode(C, (*q)->type(), (*q)->name(), true, "", (*q)->getMetaData(), + _useWstring); } C << eb; @@ -1108,8 +1123,8 @@ Slice::Gen::TypesVisitor::visitStructEnd(const StructPtr& p) C << sb; for(q = dataMembers.begin(); q != dataMembers.end(); ++q) { - writeStreamMarshalUnmarshalCode(C, (*q)->type(), (*q)->name(), false, "", _useWstring, - (*q)->getMetaData()); + writeStreamMarshalUnmarshalCode(C, (*q)->type(), (*q)->name(), false, "", (*q)->getMetaData(), + _useWstring); } C << eb; C.zeroIndent(); @@ -1119,7 +1134,7 @@ Slice::Gen::TypesVisitor::visitStructEnd(const StructPtr& p) } H << eb << ';'; - if(findMetaData(p->getMetaData(), false) == "class") + if(findMetaData(p->getMetaData()) == "class") { H << sp << nl << "typedef ::IceUtil::Handle< " << scoped << "> " << p->name() + "Ptr;"; @@ -1222,7 +1237,7 @@ Slice::Gen::TypesVisitor::visitDataMember(const DataMemberPtr& p) { StringList metaData = s->getMetaData(); bool protobuf; - findMetaData(s, metaData, false, protobuf); + findMetaData(s, metaData, protobuf); if(protobuf) { emitWarning(p->file(), p->line(), string("protobuf cannot be used as a ") + @@ -1232,7 +1247,7 @@ Slice::Gen::TypesVisitor::visitDataMember(const DataMemberPtr& p) } } - string s = typeToString(p->type(), _useWstring, p->getMetaData()); + string s = typeToString(p->type(), p->getMetaData(), _useWstring); H << nl << s << ' ' << name << ';'; } @@ -1241,11 +1256,11 @@ Slice::Gen::TypesVisitor::visitSequence(const SequencePtr& p) { string name = fixKwd(p->name()); TypePtr type = p->type(); - string s = typeToString(type, _useWstring, p->typeMetaData()); + string s = typeToString(type, p->typeMetaData(), _useWstring); StringList metaData = p->getMetaData(); bool protobuf; - string seqType = findMetaData(p, metaData, false, protobuf); + string seqType = findMetaData(p, metaData, protobuf); H << sp; if(!protobuf) { @@ -1412,7 +1427,7 @@ Slice::Gen::TypesVisitor::visitSequence(const SequencePtr& p) C << nl << scopedName << "::const_iterator p;"; C << nl << "for(p = v.begin(); p != v.end(); ++p)"; C << sb; - writeStreamMarshalUnmarshalCode(C, type, "(*p)", true, "", _useWstring); + writeStreamMarshalUnmarshalCode(C, type, "(*p)", true, "", StringList(), _useWstring); C << eb; } C << eb; @@ -1436,7 +1451,7 @@ Slice::Gen::TypesVisitor::visitSequence(const SequencePtr& p) C << nl << scopedName << "::iterator p;"; C << nl << "for(p = v.begin(); p != v.end(); ++p)"; C << sb; - writeStreamMarshalUnmarshalCode(C, type, "(*p)", false, "", _useWstring); + writeStreamMarshalUnmarshalCode(C, type, "(*p)", false, "", StringList(), _useWstring); C << eb; } C << eb; @@ -1543,7 +1558,7 @@ Slice::Gen::TypesVisitor::visitSequence(const SequencePtr& p) C << nl << scoped << "::const_iterator p;"; C << nl << "for(p = v.begin(); p != v.end(); ++p)"; C << sb; - writeStreamMarshalUnmarshalCode(C, type, "(*p)", true, "", _useWstring); + writeStreamMarshalUnmarshalCode(C, type, "(*p)", true, "", StringList(), _useWstring); C << eb; C << eb; @@ -1554,7 +1569,7 @@ Slice::Gen::TypesVisitor::visitSequence(const SequencePtr& p) C << nl << "v.resize(sz);"; C << nl << "for(int i = 0; i < sz; ++i)"; C << sb; - writeStreamMarshalUnmarshalCode(C, type, "v[i]", false, "", _useWstring); + writeStreamMarshalUnmarshalCode(C, type, "v[i]", false, "", StringList(), _useWstring); C << eb; C << eb; C.zeroIndent(); @@ -1578,7 +1593,7 @@ Slice::Gen::TypesVisitor::visitDictionary(const DictionaryPtr& p) { StringList metaData = s->getMetaData(); bool protobuf; - findMetaData(s, metaData, false, protobuf); + findMetaData(s, metaData, protobuf); if(protobuf) { emitWarning(p->file(), p->line(), "protobuf cannot be used as a dictionary key in C++"); @@ -1587,12 +1602,12 @@ Slice::Gen::TypesVisitor::visitDictionary(const DictionaryPtr& p) } TypePtr valueType = p->valueType(); - string ks = typeToString(keyType, _useWstring, p->keyMetaData()); + string ks = typeToString(keyType, p->keyMetaData(), _useWstring); if(ks[0] == ':') { ks.insert(0, " "); } - string vs = typeToString(valueType, _useWstring, p->valueMetaData()); + string vs = typeToString(valueType, p->valueMetaData(), _useWstring); H << sp << nl << "typedef ::std::map<" << ks << ", " << vs << "> " << name << ';'; if(!p->isLocal()) @@ -1663,8 +1678,8 @@ Slice::Gen::TypesVisitor::visitDictionary(const DictionaryPtr& p) C << nl << scoped << "::const_iterator p;"; C << nl << "for(p = v.begin(); p != v.end(); ++p)"; C << sb; - writeStreamMarshalUnmarshalCode(C, keyType, "p->first", true, "", _useWstring, p->keyMetaData()); - writeStreamMarshalUnmarshalCode(C, valueType, "p->second", true, "", _useWstring, p->valueMetaData()); + writeStreamMarshalUnmarshalCode(C, keyType, "p->first", true, "", p->keyMetaData(), _useWstring); + writeStreamMarshalUnmarshalCode(C, valueType, "p->second", true, "", p->valueMetaData(), _useWstring); C << eb; C << eb; @@ -1675,9 +1690,9 @@ Slice::Gen::TypesVisitor::visitDictionary(const DictionaryPtr& p) C << nl << "while(sz--)"; C << sb; C << nl << "::std::pair<const " << ks << ", " << vs << "> pair;"; - writeStreamMarshalUnmarshalCode(C, keyType, pf, false, "", _useWstring, p->keyMetaData()); + writeStreamMarshalUnmarshalCode(C, keyType, pf, false, "", p->keyMetaData(), _useWstring); C << nl << scoped << "::iterator __i = v.insert(v.end(), pair);"; - writeStreamMarshalUnmarshalCode(C, valueType, "__i->second", false, "", _useWstring, p->valueMetaData()); + writeStreamMarshalUnmarshalCode(C, valueType, "__i->second", false, "", p->valueMetaData(), _useWstring); C << eb; C << eb; C.zeroIndent(); @@ -1841,7 +1856,7 @@ void Slice::Gen::TypesVisitor::visitConst(const ConstPtr& p) { H << sp; - H << nl << "const " << typeToString(p->type(), _useWstring, p->typeMetaData()) << " " << fixKwd(p->name()) + H << nl << "const " << typeToString(p->type(), p->typeMetaData(), _useWstring) << " " << fixKwd(p->name()) << " = "; BuiltinPtr bp = BuiltinPtr::dynamicCast(p->type()); @@ -1857,7 +1872,7 @@ Slice::Gen::TypesVisitor::visitConst(const ConstPtr& p) "_{}[]#()<>%:;.?*+-/^&|~!=,\\\"' "; static const set<char> charSet(basicSourceChars.begin(), basicSourceChars.end()); - if(_useWstring || findMetaData(p->typeMetaData(), true) == "wstring") + if(_useWstring || findMetaData(p->typeMetaData()) == "wstring") { H << 'L'; } @@ -2441,10 +2456,14 @@ Slice::Gen::ProxyVisitor::visitOperation(const OperationPtr& p) string scope = fixKwd(p->scope()); TypePtr ret = p->returnType(); - string retS = returnTypeToString(ret, _useWstring, p->getMetaData()); + string retS = returnTypeToString(ret, p->getMetaData(), _useWstring | TypeContextAMIEnd); + string retSEndAMI = returnTypeToString(ret, p->getMetaData(), _useWstring | TypeContextAMIPrivateEnd); ContainerPtr container = p->container(); ClassDefPtr cl = ClassDefPtr::dynamicCast(container); + string clScope = fixKwd(cl->scope()); + string delName = "Callback_" + cl->name() + "_" + name; + string delNameScoped = clScope + delName; vector<string> params; vector<string> paramsDecl; @@ -2453,30 +2472,29 @@ Slice::Gen::ProxyVisitor::visitOperation(const OperationPtr& p) vector<string> paramsAMI; vector<string> paramsDeclAMI; vector<string> argsAMI; + vector<string> outParamsAMI; + vector<string> outParamsDeclAMI; + vector<string> outParamsDeclEndAMI; ParamDeclList paramList = p->parameters(); + ParamDeclList inParams; + ParamDeclList outParams; for(ParamDeclList::const_iterator q = paramList.begin(); q != paramList.end(); ++q) { string paramName = fixKwd((*q)->name()); StringList metaData = (*q)->getMetaData(); -#if defined(__SUNPRO_CC) && (__SUNPRO_CC==0x550) - // - // Work around for Sun CC 5.5 bug #4853566 - // string typeString; + string typeStringEndAMI; if((*q)->isOutParam()) { - typeString = outputTypeToString((*q)->type(), _useWstring, metaData); + typeString = outputTypeToString((*q)->type(), metaData, _useWstring | TypeContextAMIEnd); + typeStringEndAMI = outputTypeToString((*q)->type(), metaData, _useWstring | TypeContextAMIPrivateEnd); } else { - typeString = inputTypeToString((*q)->type(), _useWstring, metaData); + typeString = inputTypeToString((*q)->type(), metaData, _useWstring); } -#else - string typeString = (*q)->isOutParam() ? outputTypeToString((*q)->type(), _useWstring, metaData) - : inputTypeToString((*q)->type(), _useWstring, metaData); -#endif params.push_back(typeString); paramsDecl.push_back(typeString + ' ' + paramName); @@ -2484,12 +2502,35 @@ Slice::Gen::ProxyVisitor::visitOperation(const OperationPtr& p) if(!(*q)->isOutParam()) { - string inputTypeString = inputTypeToString((*q)->type(), _useWstring, metaData); - - paramsAMI.push_back(inputTypeString); - paramsDeclAMI.push_back(inputTypeString + ' ' + paramName); + paramsAMI.push_back(typeString); + paramsDeclAMI.push_back(typeString + ' ' + paramName); argsAMI.push_back(paramName); + inParams.push_back(*q); } + else + { + outParamsAMI.push_back(typeString); + outParamsDeclAMI.push_back(typeString + ' ' + paramName); + outParamsDeclEndAMI.push_back(typeStringEndAMI + ' ' + paramName); + outParams.push_back(*q); + } + } + + // + // Check if we need to generate a private ___end_ method. This is the case if the + // when using certain mapping features such as cpp:array or cpp:range:array. While + // the regular end_ method can't return pair<const TYPE*, const TYPE*> because the + // pointers would be invalid once end_ returns, we still want to allow using this + // alternate mapping with AMI response callbacks (to allow zero-copy for instance). + // For this purpose, we generate a special ___end method which is used by the + // __completed implementation of the generated Callback_Inft_opName operation + // delegate. + // + bool generatePrivateEnd = retS != retSEndAMI || outParamsDeclAMI != outParamsDeclEndAMI; + if(generatePrivateEnd) + { + string typeStringEndAMI = outputTypeToString(ret, p->getMetaData(), _useWstring | TypeContextAMIPrivateEnd); + outParamsDeclEndAMI.push_back(typeStringEndAMI + ' ' + "__ret"); } string thisPointer = fixKwd(scope.substr(0, scope.size() - 2)) + "*"; @@ -2515,12 +2556,67 @@ Slice::Gen::ProxyVisitor::visitOperation(const OperationPtr& p) H << fixKwd(name) << spar << args << "&__ctx" << epar << ';'; H << eb; + H << sp << nl << "::Ice::AsyncResultPtr begin_" << name << spar << paramsDeclAMI << epar; + H << sb; + H << nl << "return begin_" << name << spar << argsAMI << "0" << "::IceInternal::__dummyCallback" << "0" + << epar << ';'; + H << eb; + + H << sp << nl << "::Ice::AsyncResultPtr begin_" << name << spar << paramsDeclAMI + << "const ::Ice::Context& __ctx" + << "const ::Ice::LocalObjectPtr& __cookie = 0" << epar; + H << sb; + H << nl << "return begin_" << name << spar << argsAMI << "&__ctx" << "::IceInternal::__dummyCallback" << "__cookie" + << epar << ';'; + H << eb; + + H << sp << nl << "::Ice::AsyncResultPtr begin_" << name << spar << paramsDeclAMI + << "const ::Ice::CallbackPtr& __del" + << "const ::Ice::LocalObjectPtr& __cookie = 0" << epar; + H << sb; + H << nl << "return begin_" << name << spar << argsAMI << "0" << "__del" << "__cookie" << epar << ';'; + H << eb; + + H << sp << nl << "::Ice::AsyncResultPtr begin_" << name << spar << paramsDeclAMI + << "const ::Ice::Context& __ctx" + << "const ::Ice::CallbackPtr& __del" + << "const ::Ice::LocalObjectPtr& __cookie = 0" << epar; + H << sb; + H << nl << "return begin_" << name << spar << argsAMI << "&__ctx" << "__del" << "__cookie" << epar << ';'; + H << eb; + + H << sp << nl << "::Ice::AsyncResultPtr begin_" << name << spar << paramsDeclAMI + << "const " + delNameScoped + "Ptr& __del" + << "const ::Ice::LocalObjectPtr& __cookie = 0" << epar; + H << sb; + H << nl << "return begin_" << name << spar << argsAMI << "0" << "__del" << "__cookie" << epar << ';'; + H << eb; + + H << sp << nl << "::Ice::AsyncResultPtr begin_" << name << spar << paramsDeclAMI + << "const ::Ice::Context& __ctx" + << "const " + delNameScoped + "Ptr& __del" + << "const ::Ice::LocalObjectPtr& __cookie = 0" << epar; + H << sb; + H << nl << "return begin_" << name << spar << argsAMI << "&__ctx" << "__del" << "__cookie" << epar << ';'; + H << eb; + + H << sp << nl << retS << " end_" << name << spar << outParamsDeclAMI + << "const ::Ice::AsyncResultPtr&" << epar << ';'; + if(generatePrivateEnd) + { + H << sp << nl << "void ___end_" << name << spar << outParamsDeclEndAMI; + H << "const ::Ice::AsyncResultPtr&" << epar << ';'; + } + H << nl; H.dec(); H << nl << "private:"; H.inc(); H << sp << nl << _dllExport << retS << ' ' << fixKwd(name) << spar << params << "const ::Ice::Context*" << epar << ';'; + H << nl << _dllExport << "::Ice::AsyncResultPtr begin_" << name << spar << paramsAMI << "const ::Ice::Context*" + << "const ::IceInternal::CallbackBasePtr&" + << "const ::Ice::LocalObjectPtr& __cookie = 0" << epar << ';'; H << nl; H.dec(); H << nl << "public:"; @@ -2557,50 +2653,267 @@ Slice::Gen::ProxyVisitor::visitOperation(const OperationPtr& p) C << sb; if(p->mode() == Operation::Idempotent || p->mode() == Operation::Nonmutating) { - C << nl << "__handleExceptionWrapperRelaxed(__delBase, __ex, 0, __cnt);"; + C << nl << "__handleExceptionWrapperRelaxed(__delBase, __ex, true, __cnt);"; } else { - C << nl << "__handleExceptionWrapper(__delBase, __ex, 0);"; + C << nl << "__handleExceptionWrapper(__delBase, __ex);"; } C << eb; C << nl << "catch(const ::Ice::LocalException& __ex)"; C << sb; - C << nl << "__handleException(__delBase, __ex, 0, __cnt);"; + C << nl << "__handleException(__delBase, __ex, true, __cnt);"; + C << eb; C << eb; C << eb; + + C << sp << nl << "::Ice::AsyncResultPtr" << nl << "IceProxy" << scope << "begin_" << name << spar << paramsDeclAMI + << "const ::Ice::Context* __ctx" << "const ::IceInternal::CallbackBasePtr& __del" + << "const ::Ice::LocalObjectPtr& __cookie" << epar; + C << sb; + string flatName = p->flattenedScope() + name + "_name"; + C << nl << "::IceInternal::OutgoingAsyncPtr __result = new ::IceInternal::OutgoingAsync(this, "; + C << flatName << ", __del, __cookie);"; + C << nl << "try"; + C << sb; + if(p->returnsData()) + { + C << nl << "__checkTwowayOnly(" << flatName << ");"; + } + C << nl << "__result->__prepare(" << flatName << ", " << operationModeToString(p->sendMode()) << ", __ctx);"; + C << nl << "::IceInternal::BasicStream* __os = __result->__getOs();"; + writeMarshalCode(C, inParams, 0, StringList(), true); + if(p->sendsClasses()) + { + C << nl << "__os->writePendingObjects();"; + } + C << nl << "__os->endWriteEncaps();"; + C << nl << "__result->__send(true);"; + C << eb; + C << nl << "catch(const ::Ice::LocalException& __ex)"; + C << sb; + C << nl << "__result->__exceptionAsync(__ex);"; + C << eb; + C << nl << "return __result;"; + C << eb; + + C << sp << nl << retS << nl << "IceProxy" << scope << "end_" << name << spar << outParamsDeclAMI + << "const ::Ice::AsyncResultPtr& __result" << epar; + C << sb; + if(p->returnsData()) + { + C << nl << "::Ice::AsyncResult::__check(__result, this, " << flatName << ");"; + C << nl << "if(!__result->__wait())"; + C << sb; + C << nl << "try"; + C << sb; + C << nl << "__result->__throwUserException();"; + C << eb; + // + // Generate a catch block for each legal user exception. + // (See comment in DelegateMVisitor::visitOperation() for details.) + // + ExceptionList throws = p->throws(); + throws.sort(); + throws.unique(); +#if defined(__SUNPRO_CC) + throws.sort(derivedToBaseCompare); +#else + throws.sort(Slice::DerivedToBaseCompare()); +#endif + for(ExceptionList::const_iterator i = throws.begin(); i != throws.end(); ++i) + { + string scoped = (*i)->scoped(); + C << nl << "catch(const " << fixKwd((*i)->scoped()) << "&)"; + C << sb; + C << nl << "throw;"; + C << eb; + } + C << nl << "catch(const ::Ice::UserException& __ex)"; + C << sb; + C << nl << "throw ::Ice::UnknownUserException(__FILE__, __LINE__, __ex.ice_name());"; + C << eb; + C << eb; + writeAllocateCode(C, ParamDeclList(), ret, p->getMetaData(), _useWstring | TypeContextAMIEnd); + C << nl << "::IceInternal::BasicStream* __is = __result->__getIs();"; + if(ret || !outParams.empty()) + { + C << nl << "__is->startReadEncaps();"; + writeUnmarshalCode(C, outParams, ret, p->getMetaData(), _useWstring | TypeContextAMIEnd); + if(p->returnsClasses()) + { + C << nl << "__is->readPendingObjects();"; + } + C << nl << "__is->endReadEncaps();"; + } + else + { + C << nl << "__is->skipEmptyEncaps();"; + } + if(ret) + { + C << nl << "return __ret;"; + } + } + else + { + C << nl << "__end(__result, " << flatName << ");"; + } C << eb; + if(generatePrivateEnd) + { + assert(p->returnsData()); + + C << sp << nl << "void IceProxy" << scope << "___end_" << name << spar << outParamsDeclEndAMI + << "const ::Ice::AsyncResultPtr& __result" << epar; + C << sb; + C << nl << "::Ice::AsyncResult::__check(__result, this, " << flatName << ");"; + C << nl << "if(!__result->__wait())"; + C << sb; + C << nl << "try"; + C << sb; + C << nl << "__result->__throwUserException();"; + C << eb; + // + // Generate a catch block for each legal user exception. + // (See comment in DelegateMVisitor::visitOperation() for details.) + // + ExceptionList throws = p->throws(); + throws.sort(); + throws.unique(); +#if defined(__SUNPRO_CC) + throws.sort(derivedToBaseCompare); +#else + throws.sort(Slice::DerivedToBaseCompare()); +#endif + for(ExceptionList::const_iterator i = throws.begin(); i != throws.end(); ++i) + { + string scoped = (*i)->scoped(); + C << nl << "catch(const " << fixKwd((*i)->scoped()) << "&)"; + C << sb; + C << nl << "throw;"; + C << eb; + } + C << nl << "catch(const ::Ice::UserException& __ex)"; + C << sb; + C << nl << "throw ::Ice::UnknownUserException(__FILE__, __LINE__, __ex.ice_name());"; + C << eb; + C << eb; + C << nl << "::IceInternal::BasicStream* __is = __result->__getIs();"; + if(ret || !outParams.empty()) + { + C << nl << "__is->startReadEncaps();"; + writeUnmarshalCode(C, outParams, ret, p->getMetaData(), _useWstring | TypeContextAMIPrivateEnd); + if(p->returnsClasses()) + { + C << nl << "__is->readPendingObjects();"; + } + C << nl << "__is->endReadEncaps();"; + } + else + { + C << nl << "__is->skipEmptyEncaps();"; + } + C << eb; + } + if(cl->hasMetaData("ami") || p->hasMetaData("ami")) { string classNameAMI = "AMI_" + cl->name(); string classScope = fixKwd(cl->scope()); string classScopedAMI = classScope + classNameAMI; + string opScopedAMI = classScopedAMI + "_" + name; - H << nl << _dllExport << "bool " << name << "_async" << spar - << ("const " + classScopedAMI + '_' + p->name() + "Ptr&") + H << nl << _dllExport << "bool " << name << "_async" << spar << ("const " + opScopedAMI + "Ptr&") << paramsAMI << epar << ';'; - H << nl << _dllExport << "bool " << name << "_async" << spar - << ("const " + classScopedAMI + '_' + p->name() + "Ptr&") + H << nl << _dllExport << "bool " << name << "_async" << spar << ("const " + opScopedAMI + "Ptr&") << paramsAMI << "const ::Ice::Context&" << epar << ';'; C << sp << nl << "bool" << nl << "IceProxy" << scope << name << "_async" << spar - << ("const " + classScopedAMI + '_' + p->name() + "Ptr& __cb") << paramsDeclAMI << epar; + << ("const " + opScopedAMI + "Ptr& __cb") << paramsDeclAMI << epar; C << sb; - C << nl << "return __cb->__invoke" << spar << "this" << argsAMI << "0" << epar << ';'; + if(p->returnsData()) + { + C << nl << delNameScoped << "Ptr __del;"; + C << nl << "if(dynamic_cast< ::Ice::AMISentCallback*>(__cb.get()))"; + C << sb; + C << nl << " __del = " << classScope << "new" << delName << "(__cb, &" << opScopedAMI << "::__response, &" + << opScopedAMI << "::__exception, &" << opScopedAMI << "::__sent);"; + C << eb; + C << nl << "else"; + C << sb; + C << nl << " __del = " << classScope << "new" << delName << "(__cb, &" << opScopedAMI << "::__response, &" + << opScopedAMI << "::__exception);"; + C << eb; + } + else + { + C << nl << "::IceInternal::CallbackBasePtr __del;"; + C << nl << "if(ice_isTwoway())"; + C << sb; + C << nl << "if(dynamic_cast< ::Ice::AMISentCallback*>(__cb.get()))"; + C << sb; + C << nl << " __del = " << classScope << "new" << delName << "(__cb, &" << opScopedAMI << "::__response, &" + << opScopedAMI << "::__exception, &" << opScopedAMI << "::__sent);"; + C << eb; + C << nl << "else"; + C << sb; + C << nl << " __del = " << classScope << "new" << delName << "(__cb, &" << opScopedAMI << "::__response, &" + << opScopedAMI << "::__exception);"; + C << eb; + C << eb; + C << nl << "else"; + C << sb; + C << nl << "__del = ::Ice::newCallback(__cb);"; + C << eb; + } + C << nl << "::Ice::AsyncResultPtr __ar = begin_" << name << spar << argsAMI << "0, __del" << epar << ';'; + C << nl << "return __ar->sentSynchronously();"; C << eb; C << sp << nl << "bool" << nl << "IceProxy" << scope << name << "_async" << spar - << ("const " + classScopedAMI + '_' + p->name() + "Ptr& __cb") - << paramsDeclAMI << "const ::Ice::Context& __ctx" + << ("const " + opScopedAMI + "Ptr& __cb") << paramsDeclAMI << "const ::Ice::Context& __ctx" << epar; C << sb; - C << nl << "return __cb->__invoke" << spar << "this" << argsAMI << "&__ctx" << epar << ';'; + if(p->returnsData()) + { + C << nl << delNameScoped << "Ptr __del;"; + C << nl << "if(dynamic_cast< ::Ice::AMISentCallback*>(__cb.get()))"; + C << sb; + C << nl << " __del = " << classScope << "new" << delName << "(__cb, &" << opScopedAMI << "::__response, &" + << opScopedAMI << "::__exception, &" << opScopedAMI << "::__sent);"; + C << eb; + C << nl << "else"; + C << sb; + C << nl << " __del = " << classScope << "new" << delName << "(__cb, &" << opScopedAMI << "::__response, &" + << opScopedAMI << "::__exception);"; + C << eb; + } + else + { + C << nl << "::IceInternal::CallbackBasePtr __del;"; + C << nl << "if(ice_isTwoway())"; + C << nl << "if(dynamic_cast< ::Ice::AMISentCallback*>(__cb.get()))"; + C << sb; + C << nl << " __del = " << classScope << "new" << delName << "(__cb, &" << opScopedAMI << "::__response, &" + << opScopedAMI << "::__exception, &" << opScopedAMI << "::__sent);"; + C << eb; + C << nl << "else"; + C << sb; + C << nl << " __del = " << classScope << "new" << delName << "(__cb, &" << opScopedAMI << "::__response, &" + << opScopedAMI << "::__exception);"; + C << eb; + C << nl << "else"; + C << sb; + C << nl << "__del = ::Ice::newCallback(__cb);"; + C << eb; + } + C << nl << "::Ice::AsyncResultPtr __ar = begin_" << name << spar << argsAMI << "&__ctx" << "__del" << epar + << ';'; + C << nl << "return __ar->sentSynchronously();"; C << eb; } - - - } Slice::Gen::DelegateVisitor::DelegateVisitor(Output& h, Output& c, const string& dllExport) : @@ -2706,7 +3019,7 @@ Slice::Gen::DelegateVisitor::visitOperation(const OperationPtr& p) string name = fixKwd(p->name()); TypePtr ret = p->returnType(); - string retS = returnTypeToString(ret, _useWstring, p->getMetaData()); + string retS = returnTypeToString(ret, p->getMetaData(), _useWstring); vector<string> params; @@ -2721,15 +3034,15 @@ Slice::Gen::DelegateVisitor::visitOperation(const OperationPtr& p) string typeString; if((*q)->isOutParam()) { - typeString = outputTypeToString((*q)->type(), _useWstring, metaData); + typeString = outputTypeToString((*q)->type(), metaData, _useWstring); } else { - typeString = inputTypeToString((*q)->type(), _useWstring, metaData); + typeString = inputTypeToString((*q)->type(), metaData, _useWstring); } #else - string typeString = (*q)->isOutParam() ? outputTypeToString((*q)->type(), _useWstring, metaData) - : inputTypeToString((*q)->type(), _useWstring, metaData); + string typeString = (*q)->isOutParam() ? outputTypeToString((*q)->type(), metaData, _useWstring) + : inputTypeToString((*q)->type(), metaData, _useWstring); #endif params.push_back(typeString); @@ -2846,7 +3159,7 @@ Slice::Gen::DelegateMVisitor::visitOperation(const OperationPtr& p) string scoped = fixKwd(p->scoped()); TypePtr ret = p->returnType(); - string retS = returnTypeToString(ret, _useWstring, p->getMetaData()); + string retS = returnTypeToString(ret, p->getMetaData(), _useWstring); vector<string> params; vector<string> paramsDecl; @@ -2864,12 +3177,12 @@ Slice::Gen::DelegateMVisitor::visitOperation(const OperationPtr& p) if(isOutParam) { outParams.push_back(*q); - typeString = outputTypeToString(type, _useWstring, metaData); + typeString = outputTypeToString(type, metaData, _useWstring); } else { inParams.push_back(*q); - typeString = inputTypeToString(type, _useWstring, metaData); + typeString = inputTypeToString(type, metaData, _useWstring); } params.push_back(typeString); @@ -2976,7 +3289,7 @@ Slice::Gen::DelegateMVisitor::visitOperation(const OperationPtr& p) for(ParamDeclList::const_iterator opi = outParams.begin(); opi != outParams.end(); ++opi) { StructPtr st = StructPtr::dynamicCast((*opi)->type()); - if(st && findMetaData(st->getMetaData(), false) == "class") + if(st && findMetaData(st->getMetaData()) == "class") { C << nl << fixKwd((*opi)->name()) << " = new " << fixKwd(st->scoped()) << ";"; } @@ -3120,7 +3433,7 @@ Slice::Gen::DelegateDVisitor::visitOperation(const OperationPtr& p) string scoped = fixKwd(p->scoped()); TypePtr ret = p->returnType(); - string retS = returnTypeToString(ret, _useWstring, p->getMetaData()); + string retS = returnTypeToString(ret, p->getMetaData(), _useWstring); vector<string> params; vector<string> paramsDecl; @@ -3140,15 +3453,15 @@ Slice::Gen::DelegateDVisitor::visitOperation(const OperationPtr& p) string typeString; if((*q)->isOutParam()) { - typeString = outputTypeToString((*q)->type(), _useWstring, metaData); + typeString = outputTypeToString((*q)->type(), metaData, _useWstring); } else { - typeString = inputTypeToString((*q)->type(), _useWstring, metaData); + typeString = inputTypeToString((*q)->type(), metaData, _useWstring); } #else - string typeString = (*q)->isOutParam() ? outputTypeToString((*q)->type(), _useWstring, metaData) - : inputTypeToString((*q)->type(), _useWstring, metaData); + string typeString = (*q)->isOutParam() ? outputTypeToString((*q)->type(), metaData, _useWstring) + : inputTypeToString((*q)->type(), metaData, _useWstring); #endif params.push_back(typeString); @@ -3197,7 +3510,7 @@ Slice::Gen::DelegateDVisitor::visitOperation(const OperationPtr& p) C << sp << nl << "_DirectI" << spar; if(ret) { - string resultRef = outputTypeToString(ret, _useWstring, p->getMetaData()); + string resultRef = outputTypeToString(ret, p->getMetaData(), _useWstring); C << resultRef + " __result"; } C << paramsDecl << "const ::Ice::Current& __current" << epar << " : "; @@ -3274,7 +3587,7 @@ Slice::Gen::DelegateDVisitor::visitOperation(const OperationPtr& p) C << nl; if(ret) { - string resultRef= outputTypeToString(ret, _useWstring, p->getMetaData()); + string resultRef= outputTypeToString(ret, p->getMetaData(), _useWstring); C << nl << resultRef << " _result;"; } @@ -3511,7 +3824,7 @@ Slice::Gen::ObjectVisitor::visitClassDefStart(const ClassDefPtr& p) for(q = allDataMembers.begin(); q != allDataMembers.end(); ++q) { - string typeName = inputTypeToString((*q)->type(), _useWstring, (*q)->getMetaData()); + string typeName = inputTypeToString((*q)->type(), (*q)->getMetaData(), _useWstring); allTypes.push_back(typeName); allParamDecls.push_back(typeName + " __ice_" + (*q)->name()); } @@ -3972,8 +4285,8 @@ Slice::Gen::ObjectVisitor::visitClassDefEnd(const ClassDefPtr& p) C << nl << "__outS->startSlice();"; for(q = dataMembers.begin(); q != dataMembers.end(); ++q) { - writeStreamMarshalUnmarshalCode(C, (*q)->type(), (*q)->name(), true, "", _useWstring, - (*q)->getMetaData()); + writeStreamMarshalUnmarshalCode(C, (*q)->type(), (*q)->name(), true, "", (*q)->getMetaData(), + _useWstring); } C << nl << "__outS->endSlice();"; emitUpcall(base, "::__write(__outS);"); @@ -3988,8 +4301,8 @@ Slice::Gen::ObjectVisitor::visitClassDefEnd(const ClassDefPtr& p) C << nl << "__inS->startSlice();"; for(q = dataMembers.begin(); q != dataMembers.end(); ++q) { - writeStreamMarshalUnmarshalCode(C, (*q)->type(), (*q)->name(), false, "", _useWstring, - (*q)->getMetaData()); + writeStreamMarshalUnmarshalCode(C, (*q)->type(), (*q)->name(), false, "", (*q)->getMetaData(), + _useWstring); } C << nl << "__inS->endSlice();"; emitUpcall(base, "::__read(__inS, true);"); @@ -4122,7 +4435,7 @@ Slice::Gen::ObjectVisitor::visitClassDefEnd(const ClassDefPtr& p) { StringList metaData = s->getMetaData(); bool protobuf; - findMetaData(s, metaData, false, protobuf); + findMetaData(s, metaData, protobuf); if(protobuf) { emitWarning((*q)->file(), (*q)->line(), "protobuf cannot be used as a class member in C++"); @@ -4152,7 +4465,7 @@ Slice::Gen::ObjectVisitor::visitClassDefEnd(const ClassDefPtr& p) } string name = fixKwd((*q)->name()); - string s = typeToString((*q)->type(), _useWstring, (*q)->getMetaData()); + string s = typeToString((*q)->type(), (*q)->getMetaData(), _useWstring); H << sp << nl << s << ' ' << name << ';'; } @@ -4242,7 +4555,7 @@ Slice::Gen::ObjectVisitor::visitOperation(const OperationPtr& p) string scope = fixKwd(p->scope()); TypePtr ret = p->returnType(); - string retS = returnTypeToString(ret, _useWstring, p->getMetaData()); + string retS = returnTypeToString(ret, p->getMetaData(), _useWstring); string params = "("; string paramsDecl = "("; @@ -4270,12 +4583,12 @@ Slice::Gen::ObjectVisitor::visitOperation(const OperationPtr& p) if(isOutParam) { outParams.push_back(*q); - typeString = outputTypeToString(type, _useWstring, (*q)->getMetaData()); + typeString = outputTypeToString(type, (*q)->getMetaData(), _useWstring); } else { inParams.push_back(*q); - typeString = inputTypeToString((*q)->type(), _useWstring, (*q)->getMetaData()); + typeString = inputTypeToString((*q)->type(), (*q)->getMetaData(), _useWstring); } if(q != paramList.begin()) @@ -4380,8 +4693,8 @@ Slice::Gen::ObjectVisitor::visitOperation(const OperationPtr& p) { C << nl << "::IceInternal::BasicStream* __is = __inS.is();"; C << nl << "__is->startReadEncaps();"; - writeAllocateCode(C, inParams, 0, StringList(), _useWstring, true); - writeUnmarshalCode(C, inParams, 0, StringList(), true); + writeAllocateCode(C, inParams, 0, StringList(), _useWstring | TypeContextInParam); + writeUnmarshalCode(C, inParams, 0, StringList(), TypeContextInParam); if(p->sendsClasses()) { C << nl << "__is->readPendingObjects();"; @@ -4438,8 +4751,8 @@ Slice::Gen::ObjectVisitor::visitOperation(const OperationPtr& p) { C << nl << "::IceInternal::BasicStream* __is = __inS.is();"; C << nl << "__is->startReadEncaps();"; - writeAllocateCode(C, inParams, 0, StringList(), _useWstring, true); - writeUnmarshalCode(C, inParams, 0, StringList(), true); + writeAllocateCode(C, inParams, 0, StringList(), _useWstring | TypeContextInParam); + writeUnmarshalCode(C, inParams, 0, StringList(), TypeContextInParam); if(p->sendsClasses()) { C << nl << "__is->readPendingObjects();"; @@ -4769,7 +5082,7 @@ Slice::Gen::ObjectVisitor::emitOneShotConstructor(const ClassDefPtr& p) for(q = allDataMembers.begin(); q != allDataMembers.end(); ++q) { - string typeName = inputTypeToString((*q)->type(), _useWstring, (*q)->getMetaData()); + string typeName = inputTypeToString((*q)->type(), (*q)->getMetaData(), _useWstring); allParamDecls.push_back(typeName + " __ice_" + (*q)->name()); } @@ -4830,6 +5143,409 @@ Slice::Gen::ObjectVisitor::emitUpcall(const ClassDefPtr& base, const string& cal C.restoreIndent(); } +Slice::Gen::AsyncCallbackVisitor::AsyncCallbackVisitor(Output& h, Output& c, const string& dllExport) : + H(h), C(c), _dllExport(dllExport), _useWstring(false) +{ +} + +bool +Slice::Gen::AsyncCallbackVisitor::visitUnitStart(const UnitPtr& p) +{ + return p->hasNonLocalClassDefs(); +} + +void +Slice::Gen::AsyncCallbackVisitor::visitUnitEnd(const UnitPtr&) +{ +} + +bool +Slice::Gen::AsyncCallbackVisitor::visitModuleStart(const ModulePtr& p) +{ + if(!p->hasNonLocalClassDefs()) + { + return false; + } + + _useWstring = setUseWstring(p, _useWstringHist, _useWstring); + + H << sp << nl << "namespace " << fixKwd(p->name()) << nl << '{'; + + return true; +} + +void +Slice::Gen::AsyncCallbackVisitor::visitModuleEnd(const ModulePtr& p) +{ + _useWstring = resetUseWstring(_useWstringHist); + + H << sp << nl << '}'; +} + +bool +Slice::Gen::AsyncCallbackVisitor::visitClassDefStart(const ClassDefPtr& p) +{ + _useWstring = setUseWstring(p, _useWstringHist, _useWstring); + return true; +} + +void +Slice::Gen::AsyncCallbackVisitor::visitClassDefEnd(const ClassDefPtr& p) +{ + _useWstring = resetUseWstring(_useWstringHist); +} + +void +Slice::Gen::AsyncCallbackVisitor::visitOperation(const OperationPtr& p) +{ + ClassDefPtr cl = ClassDefPtr::dynamicCast(p->container()); + + if(cl->isLocal() || cl->operations().empty()) + { + return; + } + + // + // Write the callback base class and callback smart pointer. + // + string delName = "Callback_" + cl->name() + "_" + p->name(); + H << sp << nl << "class " << delName << "_Base : virtual public ::IceInternal::CallbackBase { };"; + H << nl << "typedef ::IceUtil::Handle< " << delName << "_Base> " << delName << "Ptr;"; +} + +Slice::Gen::AsyncCallbackTemplateVisitor::AsyncCallbackTemplateVisitor(Output& h, + Output& c, + const string& dllExport) + : H(h), C(c), _dllExport(dllExport), _useWstring(false) +{ +} + +bool +Slice::Gen::AsyncCallbackTemplateVisitor::visitUnitStart(const UnitPtr& p) +{ + return p->hasNonLocalClassDefs(); +} + +void +Slice::Gen::AsyncCallbackTemplateVisitor::visitUnitEnd(const UnitPtr&) +{ +} + +bool +Slice::Gen::AsyncCallbackTemplateVisitor::visitModuleStart(const ModulePtr& p) +{ + if(!p->hasNonLocalClassDefs()) + { + return false; + } + + _useWstring = setUseWstring(p, _useWstringHist, _useWstring); + + H << sp << nl << "namespace " << fixKwd(p->name()) << nl << '{'; + return true; +} + +void +Slice::Gen::AsyncCallbackTemplateVisitor::visitModuleEnd(const ModulePtr& p) +{ + _useWstring = resetUseWstring(_useWstringHist); + + H << sp << nl << '}'; +} + +bool +Slice::Gen::AsyncCallbackTemplateVisitor::visitClassDefStart(const ClassDefPtr& p) +{ + _useWstring = setUseWstring(p, _useWstringHist, _useWstring); + return true; +} + +void +Slice::Gen::AsyncCallbackTemplateVisitor::visitClassDefEnd(const ClassDefPtr& p) +{ + _useWstring = resetUseWstring(_useWstringHist); +} + +namespace +{ + +bool +usePrivateEnd(const OperationPtr& p) +{ + TypePtr ret = p->returnType(); + string retSEnd = returnTypeToString(ret, p->getMetaData(), TypeContextAMIEnd); + string retSPrivateEnd = returnTypeToString(ret, p->getMetaData(), TypeContextAMIPrivateEnd); + + ParamDeclList outParams; + vector<string> outDeclsEnd; + vector<string> outDeclsPrivateEnd; + + ParamDeclList paramList = p->parameters(); + for(ParamDeclList::const_iterator q = paramList.begin(); q != paramList.end(); ++q) + { + if((*q)->isOutParam()) + { + outDeclsEnd.push_back(outputTypeToString((*q)->type(), (*q)->getMetaData(), TypeContextAMIEnd)); + outDeclsPrivateEnd.push_back(outputTypeToString((*q)->type(), (*q)->getMetaData(), TypeContextAMIPrivateEnd)); + } + } + + return retSEnd != retSPrivateEnd || outDeclsEnd != outDeclsPrivateEnd; +} + +} + +void +Slice::Gen::AsyncCallbackTemplateVisitor::visitOperation(const OperationPtr& p) +{ + generateOperation(p, false); + generateOperation(p, true); +} + +void +Slice::Gen::AsyncCallbackTemplateVisitor::generateOperation(const OperationPtr& p, bool withCookie) +{ + ClassDefPtr cl = ClassDefPtr::dynamicCast(p->container()); + if(cl->isLocal() || cl->operations().empty()) + { + return; + } + + string clName = cl->name(); + string clScope = fixKwd(cl->scope()); + string delName = "Callback_" + clName + "_" + p->name(); + string delTmplName = (withCookie ? "Callback_" : "CallbackNC_") + clName + "_" + p->name(); + + TypePtr ret = p->returnType(); + string retS = inputTypeToString(ret, p->getMetaData(), _useWstring); + string retEndArg = getEndArg(ret, p->getMetaData(), "__ret"); + + ParamDeclList outParams; + vector<string> outArgs; + vector<string> outDecls; + vector<string> outDeclsEnd; + vector<string> outEndArgs; + + ParamDeclList paramList = p->parameters(); + for(ParamDeclList::const_iterator q = paramList.begin(); q != paramList.end(); ++q) + { + if((*q)->isOutParam()) + { + outParams.push_back(*q); + outArgs.push_back(fixKwd((*q)->name())); + outEndArgs.push_back(getEndArg((*q)->type(), (*q)->getMetaData(), outArgs.back())); + outDecls.push_back(inputTypeToString((*q)->type(), (*q)->getMetaData(), _useWstring)); + } + } + + string baseD; + string inheritD; + if(withCookie) + { + baseD = "::IceInternal::Callback<T, CT>"; + H << sp << nl << "template<class T, typename CT>"; + inheritD = p->returnsData() ? "::IceInternal::TwowayCallback<T, CT>" : "::IceInternal::OnewayCallback<T, CT>"; + } + else + { + baseD = "::IceInternal::CallbackNC<T>"; + H << sp << nl << "template<class T>"; + inheritD = p->returnsData() ? "::IceInternal::TwowayCallbackNC<T>" : "::IceInternal::OnewayCallbackNC<T>"; + } + + H << nl << "class " << delTmplName << " : public " << delName << "_Base, public " << inheritD; + H << sb; + H.dec(); + H << nl << "public:"; + H.inc(); + + H << sp << nl << "typedef IceUtil::Handle<T> TPtr;"; + if(withCookie) + { + H << nl << "typedef IceUtil::Handle<CT> CTPtr;"; + } + + string cookieT; + string comCookieT; + if(withCookie) + { + cookieT = "const CTPtr&"; + comCookieT = " , const CTPtr&"; + } + + H << sp << nl << "typedef void (T::*Exception)(const ::Ice::Exception&" << comCookieT << ");"; + H << nl << "typedef void (T::*Sent)(" << cookieT << ");"; + if(p->returnsData()) + { + // + // typedefs for callbacks. + // + H << nl << "typedef void (T::*Response)" << spar; + if(ret) + { + H << retS; + } + H << outDecls; + if(withCookie) + { + H << cookieT; + } + H << epar << ';'; + } + else + { + H << nl << "typedef void (T::*Response)(" << cookieT << ");"; + } + + // + // constructor. + // + H << sp; + H << nl << delTmplName << spar << "const TPtr& obj"; + H << "Response cb"; + H << "Exception excb"; + H << "Sent sentcb" << epar; + H.inc(); + if(p->returnsData()) + { + H << nl << ": " << inheritD + "(obj, cb != 0, excb, sentcb), response(cb)"; + } + else + { + H << nl << ": " << inheritD + "(obj, cb, excb, sentcb)"; + } + H.dec(); + H << sb; + H << eb; + + if(p->returnsData()) + { + // + // completed. + // + H << sp << nl << "virtual void __completed(const ::Ice::AsyncResultPtr& __result) const"; + H << sb; + H << nl << clScope << clName << "Prx __proxy = " << clScope << clName + << "Prx::uncheckedCast(__result->getProxy());"; + writeAllocateCode(H, outParams, ret, p->getMetaData(), + _useWstring | TypeContextInParam | TypeContextAMICallPrivateEnd); + H << nl << "try"; + H << sb; + H << nl; + if(!usePrivateEnd(p)) + { + if(ret) + { + H << retEndArg << " = "; + } + H << "__proxy->end_" << p->name() << spar << outEndArgs << "__result" << epar << ';'; + } + else + { + H << "__proxy->___end_" << p->name() << spar << outEndArgs << retEndArg << "__result" << epar << ';'; + } + writeEndCode(H, outParams, ret, p->getMetaData()); + H << eb; + H << nl << "catch(::Ice::Exception& ex)"; + H << sb; + H.zeroIndent(); + H << nl << "#if defined(_MSC_VER) && (_MSC_VER < 1300) // VC++ 6 compiler bug"; // COMPILERBUG + H.restoreIndent(); + H << nl << "__exception(__result, ex);"; + H.zeroIndent(); + H << nl << "#else"; + H.restoreIndent(); + H << nl << "" << baseD << "::__exception(__result, ex);"; + H.zeroIndent(); + H << nl << "#endif"; + H.restoreIndent(); + H << nl << "return;"; + H << eb; + H << nl << "if(response)"; + H << sb; + H.zeroIndent(); + H << nl << "#if defined(_MSC_VER) && (_MSC_VER < 1300) // VC++ 6 compiler bug"; // COMPILERBUG + H.restoreIndent(); + H << nl << "(callback.get()->*response)" << spar; + if(ret) + { + H << "__ret"; + } + H << outArgs; + if(withCookie) + { + H << "CTPtr::dynamicCast(__result->getCookie())"; + } + H << epar << ';'; + H.zeroIndent(); + H << nl << "#else"; + H.restoreIndent(); + H << nl << "(" << baseD << "::callback.get()->*response)" << spar; + if(ret) + { + H << "__ret"; + } + H << outArgs; + if(withCookie) + { + H << "CTPtr::dynamicCast(__result->getCookie())"; + } + H << epar << ';'; + H.zeroIndent(); + H << nl << "#endif"; + H.restoreIndent(); + H << eb; + H << eb; + + H << sp << nl << "Response response;"; + } + H << eb << ';'; + + // Factory method + if(withCookie) + { + cookieT = "const ::IceUtil::Handle<CT>&"; + comCookieT = " , const ::IceUtil::Handle<CT>&"; + H << sp << nl << "template<class T, typename CT> " << delName << "Ptr"; + } + else + { + H << sp << nl << "template<class T> " << delName << "Ptr"; + } + + H << nl << "new" << delName << "(const ::IceUtil::Handle<T>& instance, "; + if(p->returnsData()) + { + H << "void (T::*cb)" << spar; + if(ret) + { + H << retS; + } + H << outDecls; + if(withCookie) + { + H << cookieT; + } + H << epar << ", "; + } + else + { + H << "void (T::*cb)(" << cookieT << "),"; + } + H << "void (T::*excb)(" << "const ::Ice::Exception&" << comCookieT << ") = 0,"; + H << "void (T::*sentcb)(" << cookieT << ") = 0)"; + H << sb; + if(withCookie) + { + H << nl << "return new " << delTmplName << "<T, CT>(instance, cb, excb, sentcb);"; + } + else + { + H << nl << "return new " << delTmplName << "<T>(instance, cb, excb, sentcb);"; + } + H << eb; +} + Slice::Gen::IceInternalVisitor::IceInternalVisitor(Output& h, Output& c, const string& dllExport) : H(h), C(c), _dllExport(dllExport) { @@ -5073,7 +5789,7 @@ Slice::Gen::ImplVisitor::ImplVisitor(Output& h, Output& c, void Slice::Gen::ImplVisitor::writeDecl(Output& out, const string& name, const TypePtr& type, const StringList& metaData) { - out << nl << typeToString(type, _useWstring, metaData) << ' ' << name; + out << nl << typeToString(type, metaData, _useWstring) << ' ' << name; BuiltinPtr builtin = BuiltinPtr::dynamicCast(type); if(builtin) @@ -5194,7 +5910,7 @@ Slice::Gen::ImplVisitor::writeReturn(Output& out, const TypePtr& type, const Str SequencePtr seq = SequencePtr::dynamicCast(type); if(seq) { - out << nl << "return " << typeToString(seq, _useWstring, metaData) << "();"; + out << nl << "return " << typeToString(seq, metaData, _useWstring) << "();"; } else { @@ -5302,7 +6018,7 @@ Slice::Gen::ImplVisitor::visitClassDefStart(const ClassDefPtr& p) string opName = op->name(); TypePtr ret = op->returnType(); - string retS = returnTypeToString(ret, _useWstring, op->getMetaData()); + string retS = returnTypeToString(ret, op->getMetaData(), _useWstring); if(!p->isLocal() && (p->hasMetaData("amd") || op->hasMetaData("amd"))) { @@ -5315,7 +6031,7 @@ Slice::Gen::ImplVisitor::visitClassDefStart(const ClassDefPtr& p) { if(!(*q)->isOutParam()) { - H << ',' << nl << inputTypeToString((*q)->type(), _useWstring, (*q)->getMetaData()); + H << ',' << nl << inputTypeToString((*q)->type(), (*q)->getMetaData(), _useWstring); } } H << ',' << nl << "const Ice::Current&"; @@ -5332,7 +6048,7 @@ Slice::Gen::ImplVisitor::visitClassDefStart(const ClassDefPtr& p) { if(!(*q)->isOutParam()) { - C << ',' << nl << inputTypeToString((*q)->type(), _useWstring, (*q)->getMetaData()) << ' ' + C << ',' << nl << inputTypeToString((*q)->type(), (*q)->getMetaData(), _useWstring) << ' ' << fixKwd((*q)->name()); } } @@ -5402,15 +6118,15 @@ Slice::Gen::ImplVisitor::visitClassDefStart(const ClassDefPtr& p) string typeString; if((*q)->isOutParam()) { - typeString = outputTypeToString((*q)->type(), _useWstring, metaData); + typeString = outputTypeToString((*q)->type(), metaData, _useWstring); } else { - typeString = inputTypeToString((*q)->type(), _useWstring, metaData); + typeString = inputTypeToString((*q)->type(), metaData, _useWstring); } #else - string typeString = (*q)->isOutParam() ? outputTypeToString((*q)->type(), _useWstring, metaData) - : inputTypeToString((*q)->type(), _useWstring, metaData); + string typeString = (*q)->isOutParam() ? outputTypeToString((*q)->type(), metaData, _useWstring) + : inputTypeToString((*q)->type(), metaData, _useWstring); #endif H << typeString; } @@ -5452,8 +6168,8 @@ Slice::Gen::ImplVisitor::visitClassDefStart(const ClassDefPtr& p) typeString = inputTypeToString((*q)->type(), _useWstring, metaData); } #else - string typeString = (*q)->isOutParam() ? outputTypeToString((*q)->type(), _useWstring, metaData) - : inputTypeToString((*q)->type(), _useWstring, metaData); + string typeString = (*q)->isOutParam() ? outputTypeToString((*q)->type(), metaData, _useWstring) + : inputTypeToString((*q)->type(), metaData, _useWstring); #endif C << typeString << ' ' << fixKwd((*q)->name()); } @@ -5563,12 +6279,12 @@ Slice::Gen::AsyncVisitor::visitOperation(const OperationPtr& p) paramsDeclInvoke.push_back("const " + proxyName + "& __prx"); TypePtr ret = p->returnType(); - string retS = inputTypeToString(ret, _useWstring, p->getMetaData()); + string retS = inputTypeToString(ret, p->getMetaData(), _useWstring); if(ret) { params.push_back(retS); - paramsAMD.push_back(inputTypeToString(ret, _useWstring, p->getMetaData())); + paramsAMD.push_back(inputTypeToString(ret, p->getMetaData(), _useWstring)); paramsDecl.push_back(retS + " __ret"); args.push_back("__ret"); } @@ -5580,12 +6296,12 @@ Slice::Gen::AsyncVisitor::visitOperation(const OperationPtr& p) { string paramName = fixKwd((*q)->name()); TypePtr type = (*q)->type(); - string typeString = inputTypeToString(type, _useWstring, (*q)->getMetaData()); + string typeString = inputTypeToString(type, (*q)->getMetaData(), _useWstring); if((*q)->isOutParam()) { params.push_back(typeString); - paramsAMD.push_back(inputTypeToString(type, _useWstring, (*q)->getMetaData())); + paramsAMD.push_back(inputTypeToString(type, (*q)->getMetaData(), _useWstring)); paramsDecl.push_back(typeString + ' ' + paramName); args.push_back(paramName); @@ -5605,120 +6321,29 @@ Slice::Gen::AsyncVisitor::visitOperation(const OperationPtr& p) if(cl->hasMetaData("ami") || p->hasMetaData("ami")) { - H << sp << nl << "class " << _dllExport << classNameAMI << '_' << name - << " : public ::IceInternal::OutgoingAsync"; + H << sp << nl << "class " << _dllExport << classNameAMI << '_' << name <<" : public ::Ice::AMICallbackBase"; H << sb; H.dec(); H << nl << "public:"; H.inc(); H << sp; H << nl << "virtual void ice_response" << spar << params << epar << " = 0;"; - H << nl << "virtual void ice_exception(const ::Ice::Exception&) = 0;"; - H << sp; - H << nl << "bool __invoke" << spar << paramsInvoke << epar << ';'; H << sp; - H.dec(); - H << nl << "protected:"; - H.inc(); - H << sp; - H << nl << "virtual void __response(bool);"; + H << nl << "void __response" << spar << paramsDecl << epar; + H << sb; + H << nl << "ice_response" << spar << args << epar << ';'; + H << eb; + H << nl << "void __exception(const ::Ice::Exception& ex)"; + H << sb; + H << nl << "ice_exception(ex);"; + H << eb; + H << nl << "void __sent()"; + H << sb; + H << nl << "AMICallbackBase::__sent();"; + H << eb; H << eb << ';'; H << sp << nl << "typedef ::IceUtil::Handle< " << classScopedAMI << '_' << name << "> " << classNameAMI << '_' << name << "Ptr;"; - - string flatName = p->flattenedScope() + name + "_name"; - - C << sp << nl << "bool" << nl << classScopedAMI.substr(2) << '_' << name << "::__invoke" << spar - << paramsDeclInvoke << epar; - C << sb; - C << nl << "__acquireCallback(__prx);"; - C << nl << "try"; - C << sb; - if(p->returnsData()) - { - C << nl << "__prx->__checkTwowayOnly(" << flatName << ");"; - } - C << nl << "__prepare(__prx, " << flatName << ", " << operationModeToString(p->sendMode()) << ", __ctx);"; - writeMarshalCode(C, inParams, 0, StringList(), true); - if(p->sendsClasses()) - { - C << nl << "__os->writePendingObjects();"; - } - C << nl << "__os->endWriteEncaps();"; - C << nl << "return __send();"; - C << eb; - C << nl << "catch(const ::Ice::LocalException& __ex)"; - C << sb; - C << nl << "__releaseCallback(__ex);"; - C << nl << "return false;"; - C << eb; - C << eb; - - C << sp << nl << "void" << nl << classScopedAMI.substr(2) << '_' << name << "::__response(bool __ok)"; - C << sb; - writeAllocateCode(C, outParams, ret, p->getMetaData(), _useWstring, true); - C << nl << "try"; - C << sb; - C << nl << "if(!__ok)"; - C << sb; - C << nl << "try"; - C << sb; - C << nl << "__throwUserException();"; - C << eb; - // - // Generate a catch block for each legal user exception. - // (See comment in DelegateMVisitor::visitOperation() for details.) - // - ExceptionList throws = p->throws(); - throws.sort(); - throws.unique(); -#if defined(__SUNPRO_CC) - throws.sort(derivedToBaseCompare); -#else - throws.sort(Slice::DerivedToBaseCompare()); -#endif - for(ExceptionList::const_iterator i = throws.begin(); i != throws.end(); ++i) - { - string scoped = (*i)->scoped(); - C << nl << "catch(const " << fixKwd((*i)->scoped()) << "& __ex)"; - C << sb; - C << nl << "__exception(__ex);"; - C << eb; - } - C << nl << "catch(const ::Ice::UserException& __ex)"; - C << sb; - C << nl << "throw ::Ice::UnknownUserException(__FILE__, __LINE__, __ex.ice_name());"; - C << eb; - C << nl << "return;"; - C << eb; - - if(ret || !outParams.empty()) - { - C << nl << "__is->startReadEncaps();"; - writeUnmarshalCode(C, outParams, 0, StringList(), true); - if(ret) - { - writeMarshalUnmarshalCode(C, ret, "__ret", false, "", true, p->getMetaData(), true); - } - if(p->returnsClasses()) - { - C << nl << "__is->readPendingObjects();"; - } - C << nl << "__is->endReadEncaps();"; - } - else - { - C << nl << "__is->skipEmptyEncaps();"; - } - C << eb; - C << nl << "catch(const ::Ice::LocalException& __ex)"; - C << sb; - C << nl << "__finished(__ex);"; - C << nl << "return;"; - C << eb; - C << nl << "ice_response" << spar << args << epar << ';'; - C << nl << "__releaseCallback();"; - C << eb; } if(cl->hasMetaData("amd") || p->hasMetaData("amd")) @@ -5837,7 +6462,7 @@ Slice::Gen::AsyncImplVisitor::visitOperation(const OperationPtr& p) #endif TypePtr ret = p->returnType(); - string retS = inputTypeToString(ret, _useWstring, p->getMetaData()); + string retS = inputTypeToString(ret, p->getMetaData(), _useWstring); if(ret) { @@ -5856,7 +6481,7 @@ Slice::Gen::AsyncImplVisitor::visitOperation(const OperationPtr& p) { string paramName = fixKwd((*q)->name()); TypePtr type = (*q)->type(); - string typeString = inputTypeToString(type, _useWstring, (*q)->getMetaData()); + string typeString = inputTypeToString(type, (*q)->getMetaData(), _useWstring); if(ret || !outParams.empty()) { @@ -6353,26 +6978,26 @@ Slice::Gen::MetaDataVisitor::validate(const SyntaxTreeBasePtr& cont, const Strin } } -bool -Slice::Gen::setUseWstring(ContainedPtr p, list<bool>& hist, bool use) +int +Slice::Gen::setUseWstring(ContainedPtr p, list<int>& hist, int use) { hist.push_back(use); StringList metaData = p->getMetaData(); if(find(metaData.begin(), metaData.end(), "cpp:type:wstring") != metaData.end()) { - use = true; + use = TypeContextUseWstring; } else if(find(metaData.begin(), metaData.end(), "cpp:type:string") != metaData.end()) { - use = false; + use = 0; } return use; } -bool -Slice::Gen::resetUseWstring(list<bool>& hist) +int +Slice::Gen::resetUseWstring(list<int>& hist) { - bool use = hist.back(); + int use = hist.back(); hist.pop_back(); return use; } |