diff options
author | Benoit Foucher <benoit@zeroc.com> | 2012-06-11 18:53:17 +0200 |
---|---|---|
committer | Benoit Foucher <benoit@zeroc.com> | 2012-06-11 18:53:17 +0200 |
commit | 27b1f7cc1b061fbf3a1582963d0af08d5839d480 (patch) | |
tree | c93c4a0c885ec941ec33116dd2f5683042d96a34 /cpp/src/Slice/CPlusPlusUtil.cpp | |
parent | Java port (diff) | |
download | ice-27b1f7cc1b061fbf3a1582963d0af08d5839d480.tar.bz2 ice-27b1f7cc1b061fbf3a1582963d0af08d5839d480.tar.xz ice-27b1f7cc1b061fbf3a1582963d0af08d5839d480.zip |
Support for optionals
Diffstat (limited to 'cpp/src/Slice/CPlusPlusUtil.cpp')
-rw-r--r-- | cpp/src/Slice/CPlusPlusUtil.cpp | 1035 |
1 files changed, 386 insertions, 649 deletions
diff --git a/cpp/src/Slice/CPlusPlusUtil.cpp b/cpp/src/Slice/CPlusPlusUtil.cpp index 98d2aa98510..9b9cf36490c 100644 --- a/cpp/src/Slice/CPlusPlusUtil.cpp +++ b/cpp/src/Slice/CPlusPlusUtil.cpp @@ -20,6 +20,299 @@ using namespace Slice; using namespace IceUtil; using namespace IceUtilInternal; +namespace +{ + +string toTemplateArg(const string& arg) +{ + if(arg.empty()) + { + return arg; + } + string fixed = arg; + if(arg[0] == ':') + { + fixed = " " + fixed; + } + if(fixed[fixed.length() - 1] == '>') + { + fixed = fixed + " "; + } + return fixed; +} + +string +sequenceTypeToString(const SequencePtr& seq, const StringList& metaData, int typeCtx) +{ + string seqType = findMetaData(metaData, typeCtx); + if(!seqType.empty()) + { + if(seqType == "array" || seqType == "range:array") + { + BuiltinPtr builtin = BuiltinPtr::dynamicCast(seq->type()); + if(typeCtx & TypeContextAMIPrivateEnd) + { + if(builtin && builtin->kind() == Builtin::KindByte) + { + string s = typeToString(seq->type()); + return "::std::pair<const " + s + "*, const " + s + "*>"; + } + else if(builtin && + builtin->kind() != Builtin::KindString && + builtin->kind() != Builtin::KindObject && + builtin->kind() != Builtin::KindObjectProxy) + { + string s = toTemplateArg(typeToString(builtin)); + return "::std::pair< ::IceUtil::ScopedArray<" + s + ">, " + + "::std::pair<const " + s + "*, const " + s + "*> >"; + } + else + { + string s = toTemplateArg(typeToString(seq->type(), seq->typeMetaData(), + inWstringModule(seq) ? TypeContextUseWstring : 0)); + return "::std::vector<" + s + '>'; + } + } + string s = typeToString(seq->type(), seq->typeMetaData(), inWstringModule(seq) ? TypeContextUseWstring : 0); + return "::std::pair<const " + s + "*, const " + s + "*>"; + } + else if(seqType.find("range") == 0) + { + string s; + if(seqType.find("range:") == 0) + { + s = seqType.substr(strlen("range:")); + } + else + { + s = fixKwd(seq->scoped()); + } + if(typeCtx & TypeContextAMIPrivateEnd) + { + return s; + } + if(s[0] == ':') + { + s = " " + s; + } + return "::std::pair<" + s + "::const_iterator, " + s + "::const_iterator>"; + } + else + { + return seqType; + } + } + else + { + // Get the metadata associated at the point of definition. + bool protobuf; + seqType = findMetaData(seq, seq->getMetaData(), protobuf, typeCtx); + if(protobuf && !seqType.empty()) + { + return seqType; + } + return fixKwd(seq->scoped()); + } +} + +void +writeParamAllocateCode(Output& out, const TypePtr& type, bool optional, const string& fixedName, + const StringList& metaData, int typeCtx) +{ + string s = typeToString(type, metaData, typeCtx); + if(optional) + { + s = "IceUtil::Optional<" + toTemplateArg(s) + '>'; + } + out << nl << s << ' ' << fixedName << ';'; + + if(!(typeCtx & TypeContextInParam)) + { + return; // We're done. + } + + // + // If using a range or array we need to allocate the range container, or + // array as well now to ensure they are always in the same scope. + // + SequencePtr seq = SequencePtr::dynamicCast(type); + if(seq) + { + bool protobuf; + string seqType = findMetaData(seq, metaData, protobuf, typeCtx); + if(!protobuf && seqType.empty()) + { + seqType = findMetaData(seq, seq->getMetaData(), protobuf, typeCtx); + } + if(protobuf) + { + return; + } + + string s; + if(seqType == "array" || seqType == "range:array") + { + s = typeToString(seq, metaData, TypeContextAMIPrivateEnd); + } + else if(seqType.find("range") == 0) + { + StringList md; + if(seqType.find("range:") == 0) + { + md.push_back("cpp:type:" + seqType.substr(strlen("range:"))); + } + s = typeToString(seq, md); + } + + if(!s.empty()) + { + if(optional) + { + s = "IceUtil::Optional<" + toTemplateArg(s) + '>'; + } + out << nl << s << " ___" << fixedName << ";"; + } + } +} + +void +writeParamEndCode(Output& out, const TypePtr& type, bool optional, const string& fixedName, const StringList& metaData) +{ + SequencePtr seq = SequencePtr::dynamicCast(type); + if(seq) + { + bool protobuf; + string seqType = findMetaData(seq, metaData, protobuf, TypeContextInParam); + if(!protobuf && seqType.empty()) + { + seqType = findMetaData(seq, seq->getMetaData(), protobuf, TypeContextInParam); + } + if(!protobuf) + { + if(seqType == "array" || seqType == "range:array") + { + BuiltinPtr builtin = BuiltinPtr::dynamicCast(seq->type()); + if(builtin && + builtin->kind() != Builtin::KindByte && + builtin->kind() != Builtin::KindString && + builtin->kind() != Builtin::KindObject && + builtin->kind() != Builtin::KindObjectProxy) + { + if(optional) + { + out << nl << "if(___" << fixedName << ")"; + out << sb; + out << nl << fixedName << " = ___" << fixedName << "->second;"; + out << eb; + } + else + { + out << nl << fixedName << " = ___" << fixedName << ".second;"; + } + } + else if(!builtin || + builtin->kind() == Builtin::KindString || + builtin->kind() == Builtin::KindObject || + builtin->kind() == Builtin::KindObjectProxy) + { + if(optional) + { + out << nl << "if(___" << fixedName << ")"; + out << sb; + out << nl << fixedName << ".__setIsSet();"; + out << nl << fixedName << "->first" << " = &(*___" << fixedName << ")[0];"; + out << nl << fixedName << "->second" << " = " << fixedName << "->first + " << "___" + << fixedName << "->size();"; + out << eb; + } + else + { + out << nl << fixedName << ".first" << " = &___" << fixedName << "[0];"; + out << nl << fixedName << ".second" << " = " << fixedName << ".first + " << "___" + << fixedName << ".size();"; + } + } + } + else if(seqType.find("range") == 0) + { + if(optional) + { + out << nl << "if(___" << fixedName << ")"; + out << sb; + out << nl << fixedName << ".__setIsSet();"; + out << nl << fixedName << "->first = (*___" << fixedName << ").begin();"; + out << nl << fixedName << "->second = (*___" << fixedName << ").end();"; + out << eb; + } + else + { + out << nl << fixedName << ".first = ___" << fixedName << ".begin();"; + out << nl << fixedName << ".second = ___" << fixedName << ".end();"; + } + } + } + } +} + +void +writeMarshalUnmarshalParams(Output& out, const ParamDeclList& params, const OperationPtr& op, bool marshal, int typeCtx) +{ + // + // Marshal non optional parameters. + // + ParamDeclList optionals; + for(ParamDeclList::const_iterator p = params.begin(); p != params.end(); ++p) + { + if((*p)->optional()) + { + optionals.push_back(*p); + } + else + { + writeMarshalUnmarshalCode(out, (*p)->type(), false, 0, fixKwd((*p)->name()), marshal, (*p)->getMetaData(), + typeCtx); + } + } + if(op && op->returnType()) + { + if(!op->returnIsOptional()) + { + writeMarshalUnmarshalCode(out, op->returnType(), false, 0, "__ret", marshal, op->getMetaData(), typeCtx); + } + } + + // + // Sort optional parameters by tag. + // + class SortFn + { + public: + static bool compare(const ParamDeclPtr& lhs, const ParamDeclPtr& rhs) + { + return lhs->tag() < rhs->tag(); + } + }; + optionals.sort(SortFn::compare); + + // + // Marshal optional parameters. + // + bool checkReturnType = op && op->returnIsOptional(); + for(ParamDeclList::const_iterator p = optionals.begin(); p != optionals.end(); ++p) + { + if(checkReturnType && op->returnTag() < (*p)->tag()) + { + writeMarshalUnmarshalCode(out, op->returnType(), true, op->returnTag(), "__ret", marshal, + op->getMetaData(), typeCtx); + checkReturnType = false; + } + writeMarshalUnmarshalCode(out, (*p)->type(), true, (*p)->tag(), fixKwd((*p)->name()), marshal, + (*p)->getMetaData(), typeCtx); + } +} + +} + Slice::FeatureProfile Slice::featureProfile = Slice::Ice; char @@ -107,100 +400,6 @@ Slice::printDllExportStuff(Output& out, const string& dllExport) } } -namespace -{ - -string -sequenceTypeToString(const SequencePtr& seq, const StringList& metaData, int typeCtx) -{ - string seqType = findMetaData(metaData, typeCtx); - if(!seqType.empty()) - { - if(seqType == "array" || seqType == "range:array") - { - BuiltinPtr builtin = BuiltinPtr::dynamicCast(seq->type()); - if(typeCtx & TypeContextAMIPrivateEnd) - { - if(!builtin || builtin->kind() == Builtin::KindObject || builtin->kind() == Builtin::KindObjectProxy) - { - seqType = findMetaData(seq->getMetaData()); - if(seqType.empty()) - { - return typeToString(seq); - } - else - { - return "::std::vector< " + typeToString(seq->type()) + ">"; - } - } - else if(builtin->kind() == Builtin::KindByte) - { - string s = typeToString(seq->type()); - return "::std::pair<const " + s + "*, const " + s + "*>"; - } - else if(builtin->kind() != Builtin::KindString && - builtin->kind() != Builtin::KindObject && - builtin->kind() != Builtin::KindObjectProxy) - { - string s = typeToString(builtin); - if(s[0] == ':') - { - s = " " + s; - } - return "::std::pair< ::IceUtil::ScopedArray<" + s + ">," + - " ::std::pair<const " + s + "*, const " + s + "*> >"; - } - else - { - return "::std::vector< " + typeToString(seq->type(), - seq->typeMetaData(), - inWstringModule(seq) ? TypeContextUseWstring : 0) + ">"; - } - } - string s = typeToString(seq->type(), seq->typeMetaData(), inWstringModule(seq) ? TypeContextUseWstring : 0); - return "::std::pair<const " + s + "*, const " + s + "*>"; - } - else if(seqType.find("range") == 0) - { - string s; - if(seqType.find("range:") == 0) - { - s = seqType.substr(strlen("range:")); - } - else - { - s = fixKwd(seq->scoped()); - } - if(typeCtx & TypeContextAMIPrivateEnd) - { - return s; - } - if(s[0] == ':') - { - s = " " + s; - } - return "::std::pair<" + s + "::const_iterator, " + s + "::const_iterator>"; - } - else - { - return seqType; - } - } - else - { - // Get the metadata associated at the point of definition. - bool protobuf; - seqType = findMetaData(seq, seq->getMetaData(), protobuf, typeCtx); - if(protobuf && !seqType.empty()) - { - return seqType; - } - return fixKwd(seq->scoped()); - } -} - -} - string Slice::typeToString(const TypePtr& type, const StringList& metaData, int typeCtx) { @@ -284,18 +483,36 @@ Slice::typeToString(const TypePtr& type, const StringList& metaData, int typeCtx } string -Slice::returnTypeToString(const TypePtr& type, const StringList& metaData, int typeCtx) +Slice::typeToString(const TypePtr& type, bool optional, const StringList& metaData, int typeCtx) +{ + if(optional) + { + return "IceUtil::Optional<" + toTemplateArg(typeToString(type, metaData, typeCtx)) + ">"; + } + else + { + return typeToString(type, metaData, typeCtx); + } +} + +string +Slice::returnTypeToString(const TypePtr& type, bool optional, const StringList& metaData, int typeCtx) { if(!type) { return "void"; } + if(optional) + { + return "IceUtil::Optional<" + toTemplateArg(typeToString(type, metaData, typeCtx)) + ">"; + } + return typeToString(type, metaData, typeCtx); } string -Slice::inputTypeToString(const TypePtr& type, const StringList& metaData, int typeCtx) +Slice::inputTypeToString(const TypePtr& type, bool optional, const StringList& metaData, int typeCtx) { static const char* inputBuiltinTable[] = { @@ -314,6 +531,11 @@ Slice::inputTypeToString(const TypePtr& type, const StringList& metaData, int ty typeCtx |= TypeContextInParam; + if(optional) + { + return "const IceUtil::Optional<" + toTemplateArg(typeToString(type, metaData, typeCtx)) +">&"; + } + BuiltinPtr builtin = BuiltinPtr::dynamicCast(type); if(builtin) { @@ -379,7 +601,7 @@ Slice::inputTypeToString(const TypePtr& type, const StringList& metaData, int ty } string -Slice::outputTypeToString(const TypePtr& type, const StringList& metaData, int typeCtx) +Slice::outputTypeToString(const TypePtr& type, bool optional, const StringList& metaData, int typeCtx) { static const char* outputBuiltinTable[] = { @@ -395,6 +617,11 @@ Slice::outputTypeToString(const TypePtr& type, const StringList& metaData, int t "::Ice::ObjectPrx&", "::Ice::LocalObjectPtr&" }; + + if(optional) + { + return "IceUtil::Optional<" + toTemplateArg(typeToString(type, metaData, typeCtx)) +">&"; + } BuiltinPtr builtin = BuiltinPtr::dynamicCast(type); if(builtin) @@ -595,560 +822,97 @@ Slice::fixKwd(const string& name) } void -Slice::writeMarshalUnmarshalCode(Output& out, const TypePtr& type, const string& fixedParam, bool marshal, - const string& str, bool pointer, const StringList& metaData, int typeCtx) +Slice::writeMarshalUnmarshalCode(Output& out, const TypePtr& type, bool optional, int tag, const string& param, + bool marshal, const StringList& metaData, int typeCtx, const string& str, bool pointer) { - string stream; + ostringstream os; if(str.empty()) { - stream = marshal ? "__os" : "__is"; + os << (marshal ? "__os" : "__is"); } else { - stream = str; + os << str; } string deref; if(pointer) { - deref = "->"; + os << "->"; } else { - deref = '.'; + os << '.'; } - - string func = marshal ? "write(" : "read("; - BuiltinPtr builtin = BuiltinPtr::dynamicCast(type); - if(builtin) + if(marshal) { - if(builtin->kind() == Builtin::KindObject) - { - if(marshal) - { - out << nl << stream << deref << func << fixedParam << ");"; - } - else - { - out << nl << stream << deref << func << "::Ice::__patch__ObjectPtr, &" << fixedParam << ");"; - } - return; - } - else - { - out << nl << stream << deref << func << fixedParam << ");"; - return; - } + os << "write("; } - - ClassDeclPtr cl = ClassDeclPtr::dynamicCast(type); - if(cl) + else { - string scope = fixKwd(cl->scope()); - if(marshal) - { - out << nl << stream << deref << "write(::Ice::ObjectPtr(" << scope << "upCast(" << fixedParam - << ".get())));"; - } - else - { - out << nl << stream << deref << "read(" << scope << "__patch__" << cl->name() << "Ptr, &" << fixedParam - << ");"; - } - - return; + os << "read("; } - ProxyPtr px = ProxyPtr::dynamicCast(type); - if(px) - { - string scope = fixKwd(px->_class()->scope()); - if(marshal) - { - out << nl << stream << deref << "write(::Ice::ObjectPrx(::IceProxy" << scope << "upCast(" << fixedParam - << ".get())));"; - } - else - { - out << nl << scope << "__read(" << (pointer ? "" : "&") << stream << ", " << fixedParam << ");"; - } - return; - } - - StructPtr st = StructPtr::dynamicCast(type); - if(st) + if(optional) { - string deref; - if(findMetaData(st->getMetaData()) == "class") - { - if(!marshal) - { - out << nl << fixedParam << " = new " << fixKwd(st->scoped()) << ";"; - } - out << nl << fixedParam << "->__" << func << (pointer ? "" : "&") << stream << ");"; - } - else - { - out << nl << fixedParam << ".__" << func << (pointer ? "" : "&") << stream << ");"; - } - return; + os << tag << ", "; } - - SequencePtr seq = SequencePtr::dynamicCast(type); - if(seq) - { - builtin = BuiltinPtr::dynamicCast(seq->type()); - string funcSeq = (marshal ? "write" : "read") + fixKwd(seq->name()) + "("; - - if(marshal) - { - string seqType = findMetaData(metaData, typeCtx); - string scope = fixKwd(seq->scope()); - if(seqType == "array" || seqType == "range:array") - { - // - // Use array (pair<const TYPE*, const TYPE*>). In parameters only. - // - if(!builtin || builtin->kind() == Builtin::KindObject || builtin->kind() == Builtin::KindObjectProxy) - { - // - // Sequence type in not handled by BasicStream functions. If the sequence is the - // default vector than we can use the sequences generated write function. Otherwise - // we need to generate marshal code to write each element. - // - seqType = findMetaData(seq->getMetaData()); - if(seqType.empty()) - { - out << nl << scope << "__" << funcSeq << (pointer ? "" : "&") << stream << ", " - << fixedParam << ".first, " << fixedParam << ".second);"; - } - else - { - out << nl << "::Ice::Int __sz_" << fixedParam << " = static_cast< ::Ice::Int>(" << fixedParam - << ".second - " << fixedParam << ".first);"; - out << nl << stream << deref << "writeSize(__sz_" << fixedParam << ");"; - out << nl << "for(int __i_" << fixedParam << " = 0; __i_" << fixedParam << " < __sz_" - << fixedParam << "; ++__i_" << fixedParam << ")"; - out << sb; - writeMarshalUnmarshalCode(out, seq->type(), fixedParam + ".first[__i_" + fixedParam + "]", - true); - out << eb; - } - } - else - { - // - // Use BasicStream write functions. - // - out << nl << stream << deref << func << fixedParam << ".first, " << fixedParam << ".second);"; - } - } - else if(seqType.find("range") == 0) - { - // - // Use range (pair<TYPE::const_iterator, TYPE::const_iterator). Only for in paramaters. - // Need to check if the range defines an iterator type other than the actual sequence - // type. - // - StringList l; - if(seqType.find("range:") == 0) - { - seqType = seqType.substr(strlen("range:")); - l.push_back("cpp:" + seqType); - } - else - { - seqType = fixKwd(seq->scoped()); - } - out << nl << stream << deref << "writeSize(static_cast< ::Ice::Int>(IceUtilInternal::distance(" - << fixedParam << ".first, " << fixedParam << ".second)));"; - out << nl << "for(" << seqType << "::const_iterator ___" << fixedParam << " = " - << fixedParam << ".first; ___" << fixedParam << " != " << fixedParam << ".second; ++___" - << fixedParam << ")"; - out << sb; - writeMarshalUnmarshalCode(out, seq->type(), "(*___" + fixedParam + ")", true, "", true, l); - out << eb; - } - else if(!seqType.empty()) - { - out << nl << stream << deref << "writeSize(static_cast< ::Ice::Int>(" << fixedParam << ".size()));"; - out << nl << seqType << "::const_iterator __p_" << fixedParam << ";"; - out << nl << "for(__p_" << fixedParam << " = " << fixedParam << ".begin(); __p_" << fixedParam - << " != " << fixedParam << ".end(); ++__p_" << fixedParam << ")"; - out << sb; - writeMarshalUnmarshalCode(out, seq->type(), "(*__p_" + fixedParam + ")", true); - out << eb; - } - else - { - // - // No modifying metadata specified. Use appropriate write methods for type. - // - bool protobuf; - seqType = findMetaData(seq, seq->getMetaData(), protobuf); - if(protobuf || !seqType.empty()) - { - out << nl << scope << "__" << funcSeq << (pointer ? "" : "&") << stream << ", " << fixedParam - << ");"; - } - else if(!builtin || - builtin->kind() == Builtin::KindObject || - builtin->kind() == Builtin::KindObjectProxy) - { - out << nl << "if(" << fixedParam << ".size() == 0)"; - out << sb; - out << nl << stream << deref << "writeSize(0);"; - out << eb; - out << nl << "else"; - out << sb; - out << nl << scope << "__" << funcSeq << (pointer ? "" : "&") << stream << ", &" - << fixedParam << "[0], &" << fixedParam << "[0] + " << fixedParam << ".size());"; - out << eb; - } - else if(builtin->kind() == Builtin::KindBool) - { - out << nl << stream << deref << func << fixedParam << ");"; - } - else - { - out << nl << "if(" << fixedParam << ".size() == 0)"; - out << sb; - out << nl << stream << deref << "writeSize(0);"; - out << eb; - out << nl << "else"; - out << sb; - out << nl << stream << deref << func << "&" << fixedParam << "[0], &" << fixedParam - << "[0] + " << fixedParam << ".size());"; - out << eb; - } - } - } - else + string func = os.str(); + if(!marshal) + { + SequencePtr seq = SequencePtr::dynamicCast(type); + if(seq && !(typeCtx & TypeContextAMIPrivateEnd)) { string seqType = findMetaData(metaData, typeCtx); - string scope = fixKwd(seq->scope()); if(seqType == "array" || seqType == "range:array") { - // - // Use array (pair<const TYPE*, const TYPE*>). In parameters only. - // - if(!builtin || builtin->kind() == Builtin::KindObject || builtin->kind() == Builtin::KindObjectProxy) - { - seqType = findMetaData(seq->getMetaData()); - if(seqType.empty()) - { - out << nl << typeToString(type) << " ___" << fixedParam << ";"; - out << nl << scope << "__" << funcSeq << (pointer ? "" : "&") << stream << ", ___" - << fixedParam << ");"; - } - else - { - seqType = "::std::vector< " + typeToString(seq->type()) + ">"; - StringList l; - l.push_back("cpp:type:" + seqType); - out << nl << seqType << " ___" << fixedParam << ";"; - writeMarshalUnmarshalCode(out, seq, "___" + fixedParam, false, "", true, l); - } - } - else if(builtin->kind() == Builtin::KindByte) - { - out << nl << stream << deref << func << fixedParam << ");"; - } - else if(builtin->kind() != Builtin::KindString && builtin->kind() != Builtin::KindObject && - builtin->kind() != Builtin::KindObjectProxy) - { - string s = typeToString(builtin); - if(s[0] == ':') - { - s = " " + s; - } - - if(typeCtx & TypeContextAMIPrivateEnd) - { - out << nl << fixedParam << ".first.reset(" << stream << deref << func << fixedParam - << ".second));"; - } - else - { - out << nl << "::IceUtil::ScopedArray<" << s << "> ___" << fixedParam << '(' - << stream << deref << func << fixedParam << "));"; - } - } - else + BuiltinPtr builtin = BuiltinPtr::dynamicCast(seq->type()); + if(builtin && builtin->kind() == Builtin::KindByte) { - out << nl << "::std::vector< " - << typeToString(seq->type(), seq->typeMetaData(), - inWstringModule(seq) ? TypeContextUseWstring : 0) << "> ___" - << fixedParam << ";"; - out << nl << stream << deref << func << "___" << fixedParam << ");"; + out << nl << func << param << ");"; + return; } - if(!builtin || builtin->kind() == Builtin::KindString || builtin->kind() == Builtin::KindObject || - builtin->kind() == Builtin::KindObjectProxy) - { - if(typeCtx & TypeContextAMIPrivateEnd) - { - out << nl << fixedParam << ".swap(" << "___" << fixedParam << ");"; - } - else - { - out << nl << fixedParam << ".first" << " = &___" << fixedParam << "[0];"; - out << nl << fixedParam << ".second" << " = " << fixedParam << ".first + " << "___" - << fixedParam << ".size();"; - } - } + out << nl << func << "___" << param << ");"; + writeParamEndCode(out, seq, optional, param, metaData); + return; } else if(seqType.find("range") == 0) { - // - // Use range (pair<TYPE::const_iterator, TYPE::const_iterator>). In paramters only. - // Need to check if iterator type other than default is specified. - // - StringList md; - if(seqType.find("range:") == 0) - { - md.push_back("cpp:type:" + seqType.substr(strlen("range:"))); - } - if(typeCtx & TypeContextAMIPrivateEnd) - { - writeMarshalUnmarshalCode(out, seq, fixedParam, false, "", true, md); - } - else - { - writeMarshalUnmarshalCode(out, seq, "___" + fixedParam, false, "", true, md); - out << nl << fixedParam << ".first = ___" << fixedParam << ".begin();"; - out << nl << fixedParam << ".second = ___" << fixedParam << ".end();"; - } - } - else if(!seqType.empty()) - { - // - // Using alternate sequence type. - // - out << nl << "::Ice::Int __sz_" << fixedParam << ";"; - out << nl << stream << deref << "readAndCheckSeqSize(" << seq->type()->minWireSize() << ", __sz_" - << fixedParam << ");"; - out << nl << seqType << "(__sz_" << fixedParam << ").swap(" << fixedParam << ");"; - out << nl << seqType << "::iterator __p_" << fixedParam << ";"; - out << nl << "for(__p_" << fixedParam << " = " << fixedParam << ".begin(); __p_" << fixedParam - << " != " << fixedParam << ".end(); ++__p_" << fixedParam << ")"; - out << sb; - writeMarshalUnmarshalCode(out, seq->type(), "(*__p_" + fixedParam + ")", false); - out << eb; - } - else - { - // - // No modifying metadata supplied. Just use - // appropriate read function. - // - bool protobuf; - seqType = findMetaData(seq, seq->getMetaData(), protobuf); - if(protobuf || - !seqType.empty() || - !builtin || - builtin->kind() == Builtin::KindObject || - builtin->kind() == Builtin::KindObjectProxy) - { - out << nl << scope << "__" << funcSeq << (pointer ? "" : "&") << stream << ", " - << fixedParam << ");"; - } - else if(builtin->kind() == Builtin::KindByte) - { - StringList md; - md.push_back("cpp:array"); - string tmpParam = "___"; - - // - // Catch some case in which it is not possible to just prepend - // underscores to param to use as temporary variable. - // - if(fixedParam.find("(*") == 0) - { - tmpParam += fixedParam.substr(2, fixedParam.length() - 3); - } - else if(fixedParam.find("[i]") != string::npos) - { - tmpParam += fixedParam.substr(0, fixedParam.length() - 3); - } - else if(fixedParam.find("->second") != string::npos) - { - tmpParam += fixedParam.substr(0, fixedParam.length() - 8); - } - else - { - tmpParam += fixedParam; - } - out << nl << typeToString(type, md, TypeContextInParam) << " " << tmpParam << ";"; - out << nl << stream << deref << func << tmpParam << ");"; - out << nl << "::std::vector< ::Ice::Byte>(" << tmpParam << ".first, " << tmpParam - << ".second).swap(" << fixedParam << ");"; - } - else - { - out << nl << stream << deref << func << fixedParam << ");"; - } + out << nl << func << "___" << param << ");"; + writeParamEndCode(out, seq, optional, param, metaData); + return; } } - return; } - - DictionaryPtr dict = DictionaryPtr::dynamicCast(type); - if(dict) - { - string scope = fixKwd(dict->scope()); - string funcDict = (marshal ? "write" : "read") + fixKwd(dict->name()) + "("; - out << nl << scope << "__" << funcDict << (pointer ? "" : "&") << stream << ", " << fixedParam << ");"; - return; - } - - ConstructedPtr constructed = ConstructedPtr::dynamicCast(type); - assert(constructed); - out << nl << fixKwd(constructed->scope()) << "__" << func << (pointer ? "" : "&") << stream << ", " - << fixedParam << ");"; + out << nl << func << param << ");"; } void -Slice::writeMarshalCode(Output& out, const ParamDeclList& params, const TypePtr& ret, const StringList& metaData, - int typeCtx) +Slice::writeMarshalCode(Output& out, const ParamDeclList& params, const OperationPtr& op, int typeCtx) { - for(ParamDeclList::const_iterator p = params.begin(); p != params.end(); ++p) - { - writeMarshalUnmarshalCode(out, (*p)->type(), fixKwd((*p)->name()), true, "", true, (*p)->getMetaData(), - typeCtx); - } - if(ret) - { - writeMarshalUnmarshalCode(out, ret, "__ret", true, "", true, metaData); - } + writeMarshalUnmarshalParams(out, params, op, true, typeCtx); } void -Slice::writeUnmarshalCode(Output& out, const ParamDeclList& params, const TypePtr& ret, const StringList& metaData, - int typeCtx) -{ - for(ParamDeclList::const_iterator p = params.begin(); p != params.end(); ++p) - { - writeMarshalUnmarshalCode(out, (*p)->type(), fixKwd((*p)->name()), false, "", true, (*p)->getMetaData(), - typeCtx); - } - if(ret) - { - writeMarshalUnmarshalCode(out, ret, "__ret", false, "", true, metaData, typeCtx); - } -} - -namespace -{ - -void -writeParamAllocateCode(Output& out, const TypePtr& type, const string& fixedName, const StringList& metaData, - int typeCtx) +Slice::writeUnmarshalCode(Output& out, const ParamDeclList& params, const OperationPtr& op, int typeCtx) { - out << nl << typeToString(type, metaData, typeCtx) << ' ' << fixedName; - StructPtr st = StructPtr::dynamicCast(type); - if(st && findMetaData(st->getMetaData()) == "class") - { - out << " = new " << fixKwd(st->scoped()); - } - out << ';'; - - if(!(typeCtx & TypeContextInParam)) - { - return; // We're done. - } - - // - // If using a range or array we need to allocate the range container, or - // array as well now to ensure they are always in the same scope. - // - SequencePtr seq = SequencePtr::dynamicCast(type); - if(seq) - { - bool protobuf; - string seqType = findMetaData(seq, metaData, protobuf, typeCtx); - if(!protobuf && seqType.empty()) - { - seqType = findMetaData(seq, seq->getMetaData(), protobuf, typeCtx); - } - if(protobuf) - { - return; - } - if(seqType == "array" || seqType == "range:array") - { - if(typeCtx & TypeContextAMICallPrivateEnd) - { - out << nl << typeToString(seq, metaData, TypeContextAMIPrivateEnd) << " ___" << fixedName << ";"; -// BuiltinPtr builtin = BuiltinPtr::dynamicCast(seq->type()); -// if(builtin && -// builtin->kind() != Builtin::KindByte && -// builtin->kind() != Builtin::KindString && -// builtin->kind() != Builtin::KindObject && -// builtin->kind() != Builtin::KindObjectProxy) -// { -// out << nl << typeToString(seq, metaData, TypeContextAMIPrivateEnd) << " ___" << fixedName << ";"; -// } -// else if(!builtin || builtin->kind() != Builtin::KindByte) -// { -// out << nl << typeToString(seq, metaData) << " ___" << fixedName << ";"; -// } - } - } - else if(seqType.find("range") == 0) - { - StringList md; - if(seqType.find("range:") == 0) - { - md.push_back("cpp:type:" + seqType.substr(strlen("range:"))); - } - out << nl << typeToString(seq, md) << " ___" << fixedName << ";"; - } - } -} - + writeMarshalUnmarshalParams(out, params, op, false, typeCtx); } void -Slice::writeAllocateCode(Output& out, const ParamDeclList& params, const TypePtr& ret, const StringList& metaData, - int typeCtx) +Slice::writeAllocateCode(Output& out, const ParamDeclList& params, const OperationPtr& op, int typeCtx) { for(ParamDeclList::const_iterator p = params.begin(); p != params.end(); ++p) { - writeParamAllocateCode(out, (*p)->type(), fixKwd((*p)->name()), (*p)->getMetaData(), typeCtx); - } - if(ret) - { - writeParamAllocateCode(out, ret, "__ret", metaData, typeCtx); - } -} - -void -Slice::writeStreamMarshalUnmarshalCode(Output& out, const TypePtr& type, const string& param, bool marshal, - const string& str, const StringList& metaData, int typeCtx) -{ - string fixedParam = fixKwd(param); - - string stream; - if(str.empty()) - { - stream = marshal ? "__outS" : "__inS"; - } - else - { - stream = str; + writeParamAllocateCode(out, (*p)->type(), (*p)->optional(), fixKwd((*p)->name()), (*p)->getMetaData(), typeCtx); } - - if(marshal) - { - out << nl << stream << "->write(" << fixedParam << ");"; - } - else + if(op && op->returnType()) { - out << nl << stream << "->read(" << fixedParam << ");"; + writeParamAllocateCode(out, op->returnType(), op->returnIsOptional(), "__ret", op->getMetaData(), typeCtx); } } @@ -1197,63 +961,16 @@ Slice::getEndArg(const TypePtr& type, const StringList& metaData, const string& return endArg; } -namespace -{ - -void -writeParamEndCode(Output& out, const TypePtr& type, const string& fixedName, const StringList& metaData) -{ - SequencePtr seq = SequencePtr::dynamicCast(type); - if(seq) - { - bool protobuf; - string seqType = findMetaData(seq, metaData, protobuf, TypeContextInParam); - if(!protobuf && seqType.empty()) - { - seqType = findMetaData(seq, seq->getMetaData(), protobuf, TypeContextInParam); - } - if(!protobuf) - { - if(seqType == "array" || seqType == "range:array") - { - BuiltinPtr builtin = BuiltinPtr::dynamicCast(seq->type()); - if(builtin && - builtin->kind() != Builtin::KindByte && - builtin->kind() != Builtin::KindString && - builtin->kind() != Builtin::KindObject && - builtin->kind() != Builtin::KindObjectProxy) - { - out << nl << fixedName << " = ___" << fixedName << ".second;"; - } - else if(!builtin || builtin->kind() == Builtin::KindString || builtin->kind() == Builtin::KindObject || - builtin->kind() == Builtin::KindObjectProxy) - { - out << nl << fixedName << ".first" << " = &___" << fixedName << "[0];"; - out << nl << fixedName << ".second" << " = " << fixedName << ".first + " << "___" - << fixedName << ".size();"; - } - } - else if(seqType.find("range") == 0) - { - out << nl << fixedName << ".first = ___" << fixedName << ".begin();"; - out << nl << fixedName << ".second = ___" << fixedName << ".end();"; - } - } - } -} - -} - void -Slice::writeEndCode(Output& out, const ParamDeclList& params, const TypePtr& ret, const StringList& metaData) +Slice::writeEndCode(Output& out, const ParamDeclList& params, const OperationPtr& op) { for(ParamDeclList::const_iterator p = params.begin(); p != params.end(); ++p) { - writeParamEndCode(out, (*p)->type(), fixKwd((*p)->name()), (*p)->getMetaData()); + writeParamEndCode(out, (*p)->type(), (*p)->optional(), fixKwd((*p)->name()), (*p)->getMetaData()); } - if(ret) + if(op && op->returnType()) { - writeParamEndCode(out, ret, "__ret", metaData); + writeParamEndCode(out, op->returnType(), op->returnIsOptional(), "__ret", op->getMetaData()); } } @@ -1307,7 +1024,7 @@ Slice::findMetaData(const SequencePtr& seq, const StringList& metaData, bool& is } return ""; } - else if((typeCtx & (TypeContextInParam | TypeContextAMIPrivateEnd)) && + else if((typeCtx & (TypeContextInParam | TypeContextAMIPrivateEnd)) && !(typeCtx & TypeContextAMIEnd) && ss.find("range:") == 0) { return str.substr(prefix.size()); @@ -1434,3 +1151,23 @@ Slice::inWstringModule(const SequencePtr& seq) } return false; } + + +string +Slice::getDataMemberRef(const DataMemberPtr& p) +{ + string name = fixKwd(p->name()); + if(!p->optional()) + { + return name; + } + + if(BuiltinPtr::dynamicCast(p->type())) + { + return "*" + name; + } + else + { + return "(*" + name + ")"; + } +} |