summaryrefslogtreecommitdiff
path: root/cpp/src
diff options
context:
space:
mode:
authorDwayne Boone <dwayne@zeroc.com>2005-03-18 17:24:43 +0000
committerDwayne Boone <dwayne@zeroc.com>2005-03-18 17:24:43 +0000
commit18dd6970efb0bd518fb84dc3d7bb27a94298d785 (patch)
tree931de6d02b2c743cfd87274d7190a5745ffc57c0 /cpp/src
parentAdded support for perf with CosEvent (diff)
downloadice-18dd6970efb0bd518fb84dc3d7bb27a94298d785.tar.bz2
ice-18dd6970efb0bd518fb84dc3d7bb27a94298d785.tar.xz
ice-18dd6970efb0bd518fb84dc3d7bb27a94298d785.zip
Adde embedded ice compilers
Diffstat (limited to 'cpp/src')
-rw-r--r--cpp/src/Makefile2
-rw-r--r--cpp/src/slice2cppe/.depend2
-rw-r--r--cpp/src/slice2cppe/Gen.cpp4362
-rw-r--r--cpp/src/slice2cppe/Gen.h383
-rw-r--r--cpp/src/slice2cppe/Main.cpp205
-rw-r--r--cpp/src/slice2cppe/Makefile32
-rw-r--r--cpp/src/slice2cppe/slice2cppe.dsp126
-rw-r--r--cpp/src/slice2javae/.depend2
-rw-r--r--cpp/src/slice2javae/Gen.cpp5008
-rw-r--r--cpp/src/slice2javae/Gen.h281
-rw-r--r--cpp/src/slice2javae/Main.cpp226
-rw-r--r--cpp/src/slice2javae/Makefile32
-rw-r--r--cpp/src/slice2javae/slice2javae.dsp126
13 files changed, 10787 insertions, 0 deletions
diff --git a/cpp/src/Makefile b/cpp/src/Makefile
index 161db603988..c8e4a7854b3 100644
--- a/cpp/src/Makefile
+++ b/cpp/src/Makefile
@@ -22,6 +22,8 @@ SUBDIRS = IceUtil \
slice2docbook \
slice2java \
slice2py \
+ slice2cppe \
+ slice2javae \
Ice \
IceXML \
IceSSL \
diff --git a/cpp/src/slice2cppe/.depend b/cpp/src/slice2cppe/.depend
new file mode 100644
index 00000000000..73b2db66ce7
--- /dev/null
+++ b/cpp/src/slice2cppe/.depend
@@ -0,0 +1,2 @@
+Gen.o: Gen.cpp Gen.h ../../include/Slice/Parser.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/IceUtil/Handle.h ../../include/IceUtil/Exception.h ../../include/IceUtil/InputUtil.h ../../include/IceUtil/OutputUtil.h ../../include/Slice/CPlusPlusUtil.h ../../include/IceUtil/Functional.h ../../include/IceUtil/Iterator.h ../../include/Slice/Checksum.h
+Main.o: Main.cpp ../../include/IceUtil/Options.h ../../include/IceUtil/Config.h ../../include/IceUtil/RecMutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/Exception.h ../../include/Slice/Preprocessor.h Gen.h ../../include/Slice/Parser.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Handle.h ../../include/IceUtil/InputUtil.h ../../include/IceUtil/OutputUtil.h
diff --git a/cpp/src/slice2cppe/Gen.cpp b/cpp/src/slice2cppe/Gen.cpp
new file mode 100644
index 00000000000..ef49c9f0eb5
--- /dev/null
+++ b/cpp/src/slice2cppe/Gen.cpp
@@ -0,0 +1,4362 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2005 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#include <Gen.h>
+#include <Slice/CPlusPlusUtil.h>
+#include <IceUtil/Functional.h>
+#include <IceUtil/Iterator.h>
+#include <Slice/Checksum.h>
+
+#include <limits>
+#include <sys/stat.h>
+
+using namespace std;
+using namespace Slice;
+using namespace IceUtil;
+
+Slice::Gen::Gen(const string& name, const string& base, const string& headerExtension,
+ const string& sourceExtension, const string& include, const vector<string>& includePaths,
+ const string& dllExport, const string& dir, bool imp, bool checksum, bool stream) :
+ _base(base),
+ _headerExtension(headerExtension),
+ _sourceExtension(sourceExtension),
+ _include(include),
+ _includePaths(includePaths),
+ _dllExport(dllExport),
+ _impl(imp),
+ _checksum(checksum),
+ _stream(stream)
+{
+ for(vector<string>::iterator p = _includePaths.begin(); p != _includePaths.end(); ++p)
+ {
+ if(p->length() && (*p)[p->length() - 1] != '/')
+ {
+ *p += '/';
+ }
+ }
+
+ string::size_type pos = _base.rfind('/');
+ if(pos == string::npos)
+ {
+ pos = _base.rfind('\\');
+ }
+ if(pos != string::npos)
+ {
+ _base.erase(0, pos + 1);
+ }
+
+ if(_impl)
+ {
+ string fileImplH = _base + "I." + _headerExtension;
+ string fileImplC = _base + "I." + _sourceExtension;
+ if(!dir.empty())
+ {
+ fileImplH = dir + '/' + fileImplH;
+ fileImplC = dir + '/' + fileImplC;
+ }
+
+ struct stat st;
+ if(stat(fileImplH.c_str(), &st) == 0)
+ {
+ cerr << name << ": `" << fileImplH << "' already exists - will not overwrite" << endl;
+ return;
+ }
+ if(stat(fileImplC.c_str(), &st) == 0)
+ {
+ cerr << name << ": `" << fileImplC << "' already exists - will not overwrite" << endl;
+ return;
+ }
+
+ implH.open(fileImplH.c_str());
+ if(!implH)
+ {
+ cerr << name << ": can't open `" << fileImplH << "' for writing" << endl;
+ return;
+ }
+
+ implC.open(fileImplC.c_str());
+ if(!implC)
+ {
+ cerr << name << ": can't open `" << fileImplC << "' for writing" << endl;
+ return;
+ }
+
+ string s = fileImplH;
+ if(_include.size())
+ {
+ s = _include + '/' + s;
+ }
+ transform(s.begin(), s.end(), s.begin(), ToIfdef());
+ implH << "#ifndef __" << s << "__";
+ implH << "\n#define __" << s << "__";
+ implH << '\n';
+ }
+
+ string fileH = _base + "." + _headerExtension;
+ string fileC = _base + "." + _sourceExtension;
+ if(!dir.empty())
+ {
+ fileH = dir + '/' + fileH;
+ fileC = dir + '/' + fileC;
+ }
+
+ H.open(fileH.c_str());
+ if(!H)
+ {
+ cerr << name << ": can't open `" << fileH << "' for writing" << endl;
+ return;
+ }
+
+ C.open(fileC.c_str());
+ if(!C)
+ {
+ cerr << name << ": can't open `" << fileC << "' for writing" << endl;
+ return;
+ }
+
+ printHeader(H);
+ printHeader(C);
+ H << "\n// Generated from file `" << changeInclude(_base, _includePaths) << ".ice'\n";
+ C << "\n// Generated from file `" << changeInclude(_base, _includePaths) << ".ice'\n";
+
+ string s = fileH;
+ if(_include.size())
+ {
+ s = _include + '/' + s;
+ }
+ transform(s.begin(), s.end(), s.begin(), ToIfdef());
+ H << "\n#ifndef __" << s << "__";
+ H << "\n#define __" << s << "__";
+ H << '\n';
+}
+
+Slice::Gen::~Gen()
+{
+ H << "\n\n#endif\n";
+ C << '\n';
+
+ if(_impl)
+ {
+ implH << "\n\n#endif\n";
+ implC << '\n';
+ }
+}
+
+bool
+Slice::Gen::operator!() const
+{
+ if(!H || !C)
+ {
+ return true;
+ }
+ if(_impl && (!implH || !implC))
+ {
+ return true;
+ }
+ return false;
+}
+
+void
+Slice::Gen::generate(const UnitPtr& p)
+{
+ validateMetaData(p);
+
+ C << "\n#include <";
+ if(_include.size())
+ {
+ C << _include << '/';
+ }
+ C << _base << "." << _headerExtension << ">";
+
+ H << "\n#include <Ice/LocalObjectF.h>";
+ H << "\n#include <Ice/ProxyF.h>";
+ H << "\n#include <Ice/ObjectF.h>";
+ H << "\n#include <Ice/Exception.h>";
+ H << "\n#include <Ice/LocalObject.h>";
+
+ if(p->usesProxies())
+ {
+ H << "\n#include <Ice/Proxy.h>";
+ }
+
+ if(p->hasNonLocalClassDefs())
+ {
+ 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/Incoming.h>";
+ if(p->hasContentsWithMetaData("amd"))
+ {
+ H << "\n#include <Ice/IncomingAsync.h>";
+ }
+ H << "\n#include <Ice/Direct.h>";
+ C << "\n#include <Ice/LocalException.h>";
+ C << "\n#include <Ice/ObjectFactory.h>";
+ }
+
+ if(p->hasNonLocalExceptions())
+ {
+ H << "\n#include <Ice/UserExceptionFactory.h>";
+ }
+
+ if(p->hasDataOnlyClasses() || p->hasNonLocalExceptions())
+ {
+ H << "\n#include <Ice/FactoryTable.h>";
+ }
+
+ if(p->usesNonLocals())
+ {
+ C << "\n#include <Ice/BasicStream.h>";
+ C << "\n#include <Ice/Object.h>";
+ }
+
+ if(_stream || p->hasNonLocalClassDefs() || p->hasNonLocalExceptions())
+ {
+ H << "\n#include <Ice/StreamF.h>";
+
+ if(!p->hasNonLocalClassDefs())
+ {
+ C << "\n#include <Ice/LocalException.h>";
+ }
+
+ if(_stream)
+ {
+ C << "\n#include <Ice/Stream.h>";
+ }
+ }
+
+ if(_checksum)
+ {
+ C << "\n#include <Ice/SliceChecksums.h>";
+ }
+
+ StringList includes = p->includeFiles();
+
+ for(StringList::const_iterator q = includes.begin(); q != includes.end(); ++q)
+ {
+ H << "\n#include <" << changeInclude(*q, _includePaths) << "." << _headerExtension << ">";
+ }
+
+ printVersionCheck(H);
+ printVersionCheck(C);
+
+ printDllExportStuff(H, _dllExport);
+ if(_dllExport.size())
+ {
+ _dllExport += " ";
+ }
+
+ ProxyDeclVisitor proxyDeclVisitor(H, C, _dllExport);
+ p->visit(&proxyDeclVisitor, false);
+
+ ObjectDeclVisitor objectDeclVisitor(H, C, _dllExport);
+ p->visit(&objectDeclVisitor, false);
+
+ IceInternalVisitor iceInternalVisitor(H, C, _dllExport);
+ p->visit(&iceInternalVisitor, false);
+
+ HandleVisitor handleVisitor(H, C, _dllExport, _stream);
+ p->visit(&handleVisitor, false);
+
+ TypesVisitor typesVisitor(H, C, _dllExport, _stream);
+ p->visit(&typesVisitor, false);
+
+ AsyncVisitor asyncVisitor(H, C, _dllExport);
+ p->visit(&asyncVisitor, false);
+
+ AsyncImplVisitor asyncImplVisitor(H, C, _dllExport);
+ p->visit(&asyncImplVisitor, false);
+
+ ProxyVisitor proxyVisitor(H, C, _dllExport);
+ p->visit(&proxyVisitor, false);
+
+ DelegateVisitor delegateVisitor(H, C, _dllExport);
+ p->visit(&delegateVisitor, false);
+
+ DelegateMVisitor delegateMVisitor(H, C, _dllExport);
+ p->visit(&delegateMVisitor, false);
+
+ DelegateDVisitor delegateDVisitor(H, C, _dllExport);
+ p->visit(&delegateDVisitor, false);
+
+ ObjectVisitor objectVisitor(H, C, _dllExport, _stream);
+ p->visit(&objectVisitor, false);
+
+ if(_impl)
+ {
+ implH << "\n#include <";
+ if(_include.size())
+ {
+ implH << _include << '/';
+ }
+ implH << _base << ".h>";
+
+ implC << "#include <";
+ if(_include.size())
+ {
+ implC << _include << '/';
+ }
+ implC << _base << "I.h>";
+
+ ImplVisitor implVisitor(implH, implC, _dllExport);
+ p->visit(&implVisitor, false);
+ }
+
+ if(_checksum)
+ {
+ ChecksumMap map = createChecksums(p);
+ if(!map.empty())
+ {
+ C << sp << nl << "static const char* __sliceChecksums[] =";
+ C << sb;
+ for(ChecksumMap::const_iterator p = map.begin(); p != map.end(); ++p)
+ {
+ C << nl << "\"" << p->first << "\", \"";
+ ostringstream str;
+ str.flags(ios_base::hex);
+ str.fill('0');
+ for(vector<unsigned char>::const_iterator q = p->second.begin(); q != p->second.end(); ++q)
+ {
+ str << (int)(*q);
+ }
+ C << str.str() << "\",";
+ }
+ C << nl << "0";
+ C << eb << ';';
+ C << nl << "static IceInternal::SliceChecksumInit __sliceChecksumInit(__sliceChecksums);";
+ }
+ }
+}
+
+Slice::Gen::TypesVisitor::TypesVisitor(Output& h, Output& c, const string& dllExport, bool stream) :
+ H(h), C(c), _dllExport(dllExport), _stream(stream)
+{
+}
+
+bool
+Slice::Gen::TypesVisitor::visitModuleStart(const ModulePtr& p)
+{
+ string name = fixKwd(p->name());
+
+ H << sp << nl << "namespace " << name << nl << '{';
+
+ return true;
+}
+
+void
+Slice::Gen::TypesVisitor::visitModuleEnd(const ModulePtr& p)
+{
+ H << sp << nl << '}';
+}
+
+bool
+Slice::Gen::TypesVisitor::visitClassDefStart(const ClassDefPtr&)
+{
+ return false;
+}
+
+bool
+Slice::Gen::TypesVisitor::visitExceptionStart(const ExceptionPtr& p)
+{
+ string name = fixKwd(p->name());
+ string scoped = fixKwd(p->scoped());
+ ExceptionPtr base = p->base();
+
+ H << sp << nl << "class " << _dllExport << name << " : ";
+ H.useCurrentPosAsIndent();
+ if(!base)
+ {
+ if(p->isLocal())
+ {
+ H << "public ::Ice::LocalException";
+ }
+ else
+ {
+ H << "public ::Ice::UserException";
+ }
+ }
+ else
+ {
+ H << "public " << fixKwd(base->scoped());
+ }
+ H.restoreIndent();
+ H << sb;
+
+ H.dec();
+ H << nl << "public:";
+ H.inc();
+
+ H << sp;
+ if(p->isLocal())
+ {
+ H << nl << name << "(const char*, int);";
+ C << sp << nl << scoped.substr(2) << "::" << name << "(const char* file, int line) : ";
+ C.inc();
+ if(!base)
+ {
+ C << nl << "::Ice::LocalException(file, line)";
+ }
+ else
+ {
+ C << nl << fixKwd(base->scoped()) << "(file, line)";
+ }
+ C.dec();
+ C << sb;
+ C << eb;
+ }
+
+ H << nl << "virtual const ::std::string& ice_name() const;";
+
+ string flatName = p->flattenedScope() + p->name() + "_name";
+
+ C << sp << nl << "static const ::std::string " << flatName << " = \"" << p->scoped().substr(2) << "\";";
+ C << sp << nl << "const ::std::string&" << nl << scoped.substr(2) << "::ice_name() const";
+ C << sb;
+ C << nl << "return " << flatName << ';';
+ C << eb;
+
+ if(p->isLocal())
+ {
+ H << nl << "virtual void ice_print(::std::ostream&) const;";
+ }
+
+ H << nl << "virtual ::Ice::Exception* ice_clone() const;";
+ C << sp << nl << "::Ice::Exception*" << nl << scoped.substr(2) << "::ice_clone() const";
+ C << sb;
+ C << nl << "return new " << name << "(*this);";
+ C << eb;
+
+ H << nl << "virtual void ice_throw() const;";
+ C << sp << nl << "void" << nl << scoped.substr(2) << "::ice_throw() const";
+ C << sb;
+ C << nl << "throw *this;";
+ C << eb;
+
+ if(!p->isLocal())
+ {
+ H << sp << nl << "static const ::IceInternal::UserExceptionFactoryPtr& ice_factory();";
+ }
+ return true;
+}
+
+void
+Slice::Gen::TypesVisitor::visitExceptionEnd(const ExceptionPtr& p)
+{
+ string name = fixKwd(p->name());
+ string scope = fixKwd(p->scope());
+ string scoped = fixKwd(p->scoped());
+ DataMemberList dataMembers = p->dataMembers();
+ DataMemberList::const_iterator q;
+
+ string factoryName;
+
+ if(!p->isLocal())
+ {
+ ExceptionPtr base = p->base();
+
+ H << sp << nl << "virtual void __write(::IceInternal::BasicStream*) const;";
+ H << nl << "virtual void __read(::IceInternal::BasicStream*, bool);";
+
+ H << sp << nl << "virtual void __write(const ::Ice::OutputStreamPtr&) const;";
+ H << nl << "virtual void __read(const ::Ice::InputStreamPtr&, bool);";
+
+ TypeStringList memberList;
+ for(q = dataMembers.begin(); q != dataMembers.end(); ++q)
+ {
+ memberList.push_back(make_pair((*q)->type(), (*q)->name()));
+ }
+ C << sp << nl << "void" << nl << scoped.substr(2) << "::__write(::IceInternal::BasicStream* __os) const";
+ C << sb;
+ C << nl << "__os->write(::std::string(\"" << p->scoped() << "\"));";
+ C << nl << "__os->startWriteSlice();";
+ writeMarshalCode(C, memberList, 0);
+ C << nl << "__os->endWriteSlice();";
+ if(base)
+ {
+ C.zeroIndent();
+ C << nl << "#if defined(_MSC_VER) && (_MSC_VER < 1300) // VC++ 6 compiler bug"; // COMPILERBUG
+ C.restoreIndent();
+ C << nl << fixKwd(base->name()) << "::__write(__os);";
+ C.zeroIndent();
+ C << nl << "#else";
+ C.restoreIndent();
+ C << nl << fixKwd(base->scoped()) << "::__write(__os);";
+ C.zeroIndent();
+ C << nl << "#endif";
+ C.restoreIndent();
+ }
+ C << eb;
+
+ C << sp << nl << "void" << nl << scoped.substr(2) << "::__read(::IceInternal::BasicStream* __is, bool __rid)";
+ C << sb;
+ C << nl << "if(__rid)";
+ C << sb;
+ C << nl << "::std::string myId;";
+ C << nl << "__is->read(myId);";
+ C << eb;
+ C << nl << "__is->startReadSlice();";
+ writeUnmarshalCode(C, memberList, 0);
+ C << nl << "__is->endReadSlice();";
+ if(base)
+ {
+ C.zeroIndent();
+ C << nl << "#if defined(_MSC_VER) && (_MSC_VER < 1300) // VC++ 6 compiler bug"; // COMPILERBUG
+ C.restoreIndent();
+ C << nl << fixKwd(base->name()) << "::__read(__is, true);";
+ C.zeroIndent();
+ C << nl << "#else";
+ C.restoreIndent();
+ C << nl << fixKwd(base->scoped()) << "::__read(__is, true);";
+ C.zeroIndent();
+ C << nl << "#endif";
+ C.restoreIndent();
+ }
+ C << eb;
+
+ if(_stream)
+ {
+ C << sp << nl << "void" << nl << scoped.substr(2) << "::__write(const ::Ice::OutputStreamPtr& __out) const";
+ C << sb;
+ C << nl << "__out->writeString(::std::string(\"" << p->scoped() << "\"));";
+ C << nl << "__out->startSlice();";
+ writeStreamMarshalCode(C, memberList, 0);
+ C << nl << "__out->endSlice();";
+ if(base)
+ {
+ C.zeroIndent();
+ C << nl << "#if defined(_MSC_VER) && (_MSC_VER < 1300) // VC++ 6 compiler bug"; // COMPILERBUG
+ C.restoreIndent();
+ C << nl << fixKwd(base->name()) << "::__write(__out);";
+ C.zeroIndent();
+ C << nl << "#else";
+ C.restoreIndent();
+ C << nl << fixKwd(base->scoped()) << "::__write(__out);";
+ C.zeroIndent();
+ C << nl << "#endif";
+ C.restoreIndent();
+ }
+ C << eb;
+
+ C << sp << nl << "void" << nl << scoped.substr(2)
+ << "::__read(const ::Ice::InputStreamPtr& __in, bool __rid)";
+ C << sb;
+ C << nl << "if(__rid)";
+ C << sb;
+ C << nl << "__in->readString();";
+ C << eb;
+ C << nl << "__in->startSlice();";
+ writeStreamUnmarshalCode(C, memberList, 0);
+ C << nl << "__in->endSlice();";
+ if(base)
+ {
+ C.zeroIndent();
+ C << nl << "#if defined(_MSC_VER) && (_MSC_VER < 1300) // VC++ 6 compiler bug"; // COMPILERBUG
+ C.restoreIndent();
+ C << nl << fixKwd(base->name()) << "::__read(__in, true);";
+ C.zeroIndent();
+ C << nl << "#else";
+ C.restoreIndent();
+ C << nl << fixKwd(base->scoped()) << "::__read(__in, true);";
+ C.zeroIndent();
+ C << nl << "#endif";
+ C.restoreIndent();
+ }
+ C << eb;
+ }
+ else
+ {
+ //
+ // Emit placeholder functions to catch errors.
+ //
+ C << sp << nl << "void" << nl << scoped.substr(2) << "::__write(const ::Ice::OutputStreamPtr&) const";
+ C << sb;
+ C << nl << "Ice::MarshalException ex(__FILE__, __LINE__);";
+ C << nl << "ex.reason = \"exception " << scoped.substr(2) << " was not generated with stream support\";";
+ C << nl << "throw ex;";
+ C << eb;
+
+ C << sp << nl << "void" << nl << scoped.substr(2) << "::__read(const ::Ice::InputStreamPtr&, bool)";
+ C << sb;
+ C << nl << "Ice::MarshalException ex(__FILE__, __LINE__);";
+ C << nl << "ex.reason = \"exception " << scoped .substr(2)<< " was not generated with stream support\";";
+ C << nl << "throw ex;";
+ C << eb;
+ }
+
+ if(p->usesClasses())
+ {
+ if(!base || (base && !base->usesClasses()))
+ {
+ H << nl << "virtual bool __usesClasses() const;";
+
+ C << sp << nl << "bool";
+ C << nl << scoped.substr(2) << "::__usesClasses() const";
+ C << sb;
+ C << nl << "return true;";
+ C << eb;
+ }
+ }
+
+ factoryName = "__F" + p->flattenedScope() + p->name();
+
+ C << sp << nl << "struct " << factoryName << " : public ::IceInternal::UserExceptionFactory";
+ C << sb;
+ C << sp << nl << "virtual void";
+ C << nl << "createAndThrow()";
+ C << sb;
+ C << nl << "throw " << scoped << "();";
+ C << eb;
+ C << eb << ';';
+
+ C << sp << nl << "static ::IceInternal::UserExceptionFactoryPtr " << factoryName
+ << "__Ptr = new " << factoryName << ';';
+
+ C << sp << nl << "const ::IceInternal::UserExceptionFactoryPtr&";
+ C << nl << scoped.substr(2) << "::ice_factory()";
+ C << sb;
+ C << nl << "return " << factoryName << "__Ptr;";
+ C << eb;
+
+ C << sp << nl << "class " << factoryName << "__Init";
+ C << sb;
+ C.dec();
+ C << nl << "public:";
+ C.inc();
+ C << sp << nl << factoryName << "__Init()";
+ C << sb;
+ C << nl << "::Ice::factoryTable->addExceptionFactory(\"" << p->scoped() << "\", " << scoped
+ << "::ice_factory());";
+ C << eb;
+ C << sp << nl << "~" << factoryName << "__Init()";
+ C << sb;
+ C << nl << "::Ice::factoryTable->removeExceptionFactory(\"" << p->scoped() << "\");";
+ C << eb;
+ C << eb << ';';
+ C << sp << nl << "static " << factoryName << "__Init "<< factoryName << "__i;";
+ C << sp << nl << "#ifdef __APPLE__";
+
+ string initfuncname = "__F" + p->flattenedScope() + p->name() + "__initializer";
+ C << nl << "extern \"C\" { void " << initfuncname << "() {} }";
+ C << nl << "#endif";
+ }
+ H << eb << ';';
+
+ if(!p->isLocal())
+ {
+ H << sp << nl << "static " << name << " __" << p->name() << "_init;";
+ }
+}
+
+bool
+Slice::Gen::TypesVisitor::visitStructStart(const StructPtr& p)
+{
+ string name = fixKwd(p->name());
+
+ H << sp << nl << "struct " << name;
+ H << sb;
+
+ return true;
+}
+
+void
+Slice::Gen::TypesVisitor::visitStructEnd(const StructPtr& p)
+{
+ string name = fixKwd(p->name());
+ string scoped = fixKwd(p->scoped());
+ string scope = fixKwd(p->scope());
+
+ H << sp;
+ H << nl << _dllExport << "bool operator==(const " << name << "&) const;";
+ H << nl << _dllExport << "bool operator!=(const " << name << "&) const;";
+ H << nl << _dllExport << "bool operator<(const " << name << "&) const;";
+
+ DataMemberList dataMembers = p->dataMembers();
+ DataMemberList::const_iterator q;
+ C << sp << nl << "bool" << nl << scoped.substr(2) << "::operator==(const " << name << "& __rhs) const";
+ C << sb;
+ C << nl << "return !operator!=(__rhs);";
+ C << eb;
+ C << sp << nl << "bool" << nl << scoped.substr(2) << "::operator!=(const " << name << "& __rhs) const";
+ C << sb;
+ C << nl << "if(this == &__rhs)";
+ C << sb;
+ C << nl << "return false;";
+ C << eb;
+ for(q = dataMembers.begin(); q != dataMembers.end(); ++q)
+ {
+ C << nl << "if(" << fixKwd((*q)->name()) << " != __rhs." << fixKwd((*q)->name()) << ')';
+ C << sb;
+ C << nl << "return true;";
+ C << eb;
+ }
+ C << nl << "return false;";
+ C << eb;
+ C << sp << nl << "bool" << nl << scoped.substr(2) << "::operator<(const " << name << "& __rhs) const";
+ C << sb;
+ C << nl << "if(this == &__rhs)";
+ C << sb;
+ C << nl << "return false;";
+ C << eb;
+ for(q = dataMembers.begin(); q != dataMembers.end(); ++q)
+ {
+ C << nl << "if(" << fixKwd((*q)->name()) << " < __rhs." << fixKwd((*q)->name()) << ')';
+ C << sb;
+ C << nl << "return true;";
+ C << eb;
+ C << nl << "else if(__rhs." << fixKwd((*q)->name()) << " < " << fixKwd((*q)->name()) << ')';
+ C << sb;
+ C << nl << "return false;";
+ C << eb;
+ }
+ C << nl << "return false;";
+ C << eb;
+
+ if(!p->isLocal())
+ {
+ //
+ // None of these member functions is virtual!
+ //
+ H << sp << nl << _dllExport << "void __write(::IceInternal::BasicStream*) const;";
+ H << nl << _dllExport << "void __read(::IceInternal::BasicStream*);";
+
+ if(_stream)
+ {
+ H << sp << nl << _dllExport << "void __write(const ::Ice::OutputStreamPtr&) const;";
+ H << nl << _dllExport << "void __read(const ::Ice::InputStreamPtr&);";
+ }
+
+ TypeStringList memberList;
+ for(q = dataMembers.begin(); q != dataMembers.end(); ++q)
+ {
+ memberList.push_back(make_pair((*q)->type(), (*q)->name()));
+ }
+ C << sp << nl << "void" << nl << scoped.substr(2) << "::__write(::IceInternal::BasicStream* __os) const";
+ C << sb;
+ writeMarshalCode(C, memberList, 0);
+ C << eb;
+
+ C << sp << nl << "void" << nl << scoped.substr(2) << "::__read(::IceInternal::BasicStream* __is)";
+ C << sb;
+ writeUnmarshalCode(C, memberList, 0);
+ C << eb;
+
+ if(_stream)
+ {
+ C << sp << nl << "void" << nl << scoped.substr(2) << "::__write(const ::Ice::OutputStreamPtr& __out) const";
+ C << sb;
+ writeStreamMarshalCode(C, memberList, 0);
+ C << eb;
+
+ C << sp << nl << "void" << nl << scoped.substr(2) << "::__read(const ::Ice::InputStreamPtr& __in)";
+ C << sb;
+ writeStreamUnmarshalCode(C, memberList, 0);
+ C << eb;
+ }
+ }
+
+ H << eb << ';';
+
+ if(!p->isLocal() && _stream)
+ {
+ H << sp << nl << _dllExport << "void ice_write" << p->name() << "(const ::Ice::OutputStreamPtr&, const "
+ << name << "&);";
+ H << nl << _dllExport << "void ice_read" << p->name() << "(const ::Ice::InputStreamPtr&, " << name << "&);";
+
+ C << sp << nl << "void" << nl << scope.substr(2) << "ice_write" << p->name()
+ << "(const ::Ice::OutputStreamPtr& __out, const " << scoped << "& __v)";
+ C << sb;
+ C << nl << "__v.__write(__out);";
+ C << eb;
+
+ C << sp << nl << "void" << nl << scope.substr(2) << "ice_read" << p->name()
+ << "(const ::Ice::InputStreamPtr& __in, " << scoped << "& __v)";
+ C << sb;
+ C << nl << "__v.__read(__in);";
+ C << eb;
+ }
+}
+
+void
+Slice::Gen::TypesVisitor::visitDataMember(const DataMemberPtr& p)
+{
+ string name = fixKwd(p->name());
+ string s = typeToString(p->type());
+ H << sp << nl << s << ' ' << name << ';';
+}
+
+void
+Slice::Gen::TypesVisitor::visitSequence(const SequencePtr& p)
+{
+ string name = fixKwd(p->name());
+ TypePtr type = p->type();
+ string s = typeToString(type);
+ if(s[0] == ':')
+ {
+ s.insert(0, " ");
+ }
+ H << sp << nl << "typedef ::std::vector<" << s << "> " << name << ';';
+
+ BuiltinPtr builtin = BuiltinPtr::dynamicCast(type);
+ if(!p->isLocal() &&
+ (!builtin || builtin->kind() == Builtin::KindObject || builtin->kind() == Builtin::KindObjectProxy))
+ {
+ string scoped = fixKwd(p->scoped());
+ string scope = fixKwd(p->scope());
+
+ H << sp << nl << "class __U__" << name << " { };";
+ H << nl << _dllExport << "void __write(::IceInternal::BasicStream*, const " << name << "&, __U__" << name
+ << ");";
+ H << nl << _dllExport << "void __read(::IceInternal::BasicStream*, " << name << "&, __U__" << name << ");";
+
+ if(_stream)
+ {
+ H << nl << _dllExport << "void ice_write" << p->name() << "(const ::Ice::OutputStreamPtr&, const "
+ << name << "&);";
+ H << nl << _dllExport << "void ice_read" << p->name() << "(const ::Ice::InputStreamPtr&, " << name << "&);";
+ }
+
+ C << sp << nl << "void" << nl << scope.substr(2) << "__write(::IceInternal::BasicStream* __os, const "
+ << scoped << "& v, " << scope << "__U__" << name << ")";
+ C << sb;
+ C << nl << "__os->writeSize(::Ice::Int(v.size()));";
+ C << nl << scoped << "::const_iterator p;";
+ C << nl << "for(p = v.begin(); p != v.end(); ++p)";
+ C << sb;
+ writeMarshalUnmarshalCode(C, type, "(*p)", true);
+ C << eb;
+ C << eb;
+
+ C << sp << nl << "void" << nl << scope.substr(2) << "__read(::IceInternal::BasicStream* __is, " << scoped
+ << "& v, " << scope << "__U__" << name << ')';
+ C << sb;
+ C << nl << "::Ice::Int sz;";
+ C << nl << "__is->readSize(sz);";
+ if(type->isVariableLength())
+ {
+ C << nl << "__is->startSeq(sz, " << type->minWireSize() << ");"; // Protect against bogus sequence sizes.
+ }
+ else
+ {
+ C << nl << "__is->checkFixedSeq(sz, " << type->minWireSize() << ");";
+ }
+ C << nl << "v.resize(sz);";
+ C << nl << "for(int i = 0; i < sz; ++i)";
+ C << sb;
+ writeMarshalUnmarshalCode(C, type, "v[i]", false);
+
+ //
+ // After unmarshaling each element, check that there are still enough bytes left in the stream
+ // to unmarshal the remainder of the sequence, and decrement the count of elements
+ // yet to be unmarshaled for sequences with variable-length element type (that is, for sequences
+ // of classes, structs, dictionaries, sequences, strings, or proxies). This allows us to
+ // abort unmarshaling for bogus sequence sizes at the earliest possible moment.
+ // (For fixed-length sequences, we don't need to do this because the prediction of how many
+ // bytes will be taken up by the sequence is accurate.)
+ //
+ if(type->isVariableLength())
+ {
+ if(!SequencePtr::dynamicCast(type))
+ {
+ //
+ // No need to check for directly nested sequences because, at the start of each
+ // sequence, we check anyway.
+ //
+ C << nl << "__is->checkSeq();";
+ }
+ C << nl << "__is->endElement();";
+ }
+ C << eb;
+ if(type->isVariableLength())
+ {
+ C << nl << "__is->endSeq(sz);";
+ }
+ C << eb;
+
+ if(_stream)
+ {
+ C << sp << nl << "void" << nl << scope.substr(2) << "ice_write" << p->name()
+ << "(const ::Ice::OutputStreamPtr& __out, const " << scoped << "& v)";
+ C << sb;
+ C << nl << "__out->writeSize(::Ice::Int(v.size()));";
+ C << nl << scoped << "::const_iterator p;";
+ C << nl << "for(p = v.begin(); p != v.end(); ++p)";
+ C << sb;
+ writeStreamMarshalUnmarshalCode(C, type, "(*p)", true);
+ C << eb;
+ C << eb;
+
+ C << sp << nl << "void" << nl << scope.substr(2) << "ice_read" << p->name()
+ << "(const ::Ice::InputStreamPtr& __in, " << scoped << "& v)";
+ C << sb;
+ C << nl << "::Ice::Int sz = __in->readSize();";
+ C << nl << "v.resize(sz);";
+ C << nl << "for(int i = 0; i < sz; ++i)";
+ C << sb;
+ writeStreamMarshalUnmarshalCode(C, type, "v[i]", false);
+ C << eb;
+ C << eb;
+ }
+ }
+}
+
+void
+Slice::Gen::TypesVisitor::visitDictionary(const DictionaryPtr& p)
+{
+ string name = fixKwd(p->name());
+ TypePtr keyType = p->keyType();
+ TypePtr valueType = p->valueType();
+ string ks = typeToString(keyType);
+ if(ks[0] == ':')
+ {
+ ks.insert(0, " ");
+ }
+ string vs = typeToString(valueType);
+ H << sp << nl << "typedef ::std::map<" << ks << ", " << vs << "> " << name << ';';
+
+ if(!p->isLocal())
+ {
+ string scoped = fixKwd(p->scoped());
+ string scope = fixKwd(p->scope());
+
+ H << sp << nl << "class __U__" << name << " { };";
+ H << nl << _dllExport << "void __write(::IceInternal::BasicStream*, const " << name
+ << "&, __U__" << name << ");";
+ H << nl << _dllExport << "void __read(::IceInternal::BasicStream*, " << name
+ << "&, __U__" << name << ");";
+
+ if(_stream)
+ {
+ H << nl << _dllExport << "void ice_write" << p->name() << "(const ::Ice::OutputStreamPtr&, const " << name
+ << "&);";
+ H << nl << _dllExport << "void ice_read" << p->name() << "(const ::Ice::InputStreamPtr&, " << name << "&);";
+ }
+
+ C << sp << nl << "void" << nl << scope.substr(2) << "__write(::IceInternal::BasicStream* __os, const "
+ << scoped << "& v, " << scope << "__U__" << name << ")";
+ C << sb;
+ C << nl << "__os->writeSize(::Ice::Int(v.size()));";
+ C << nl << scoped << "::const_iterator p;";
+ C << nl << "for(p = v.begin(); p != v.end(); ++p)";
+ C << sb;
+ writeMarshalUnmarshalCode(C, keyType, "p->first", true);
+ writeMarshalUnmarshalCode(C, valueType, "p->second", true);
+ C << eb;
+ C << eb;
+
+ C << sp << nl << "void" << nl << scope.substr(2) << "__read(::IceInternal::BasicStream* __is, " << scoped
+ << "& v, " << scope << "__U__" << name << ')';
+ C << sb;
+ C << nl << "::Ice::Int sz;";
+ C << nl << "__is->readSize(sz);";
+ C << nl << "while(sz--)";
+ C << sb;
+ C << nl << "::std::pair<const " << ks << ", " << vs << "> pair;";
+ string pf = string("const_cast<") + ks + "&>(pair.first)";
+ writeMarshalUnmarshalCode(C, keyType, pf, false);
+ C << nl << scoped << "::iterator __i = v.insert(v.end(), pair);";
+ writeMarshalUnmarshalCode(C, valueType, "__i->second", false);
+ C << eb;
+ C << eb;
+
+ if(_stream)
+ {
+ C << sp << nl << "void" << nl << scope.substr(2) << "ice_write" << p->name()
+ << "(const ::Ice::OutputStreamPtr& __out, const " << scoped << "& v)";
+ C << sb;
+ C << nl << "__out->writeSize(::Ice::Int(v.size()));";
+ C << nl << scoped << "::const_iterator p;";
+ C << nl << "for(p = v.begin(); p != v.end(); ++p)";
+ C << sb;
+ writeStreamMarshalUnmarshalCode(C, keyType, "p->first", true);
+ writeStreamMarshalUnmarshalCode(C, valueType, "p->second", true);
+ C << eb;
+ C << eb;
+
+ C << sp << nl << "void" << nl << scope.substr(2) << "ice_read" << p->name()
+ << "(const ::Ice::InputStreamPtr& __in, " << scoped << "& v)";
+ C << sb;
+ C << nl << "::Ice::Int sz = __in->readSize();";
+ C << nl << "while(sz--)";
+ C << sb;
+ C << nl << "::std::pair<const " << ks << ", " << vs << "> pair;";
+ string pf = string("const_cast<") + ks + "&>(pair.first)";
+ writeStreamMarshalUnmarshalCode(C, keyType, pf, false);
+ C << nl << scoped << "::iterator __i = v.insert(v.end(), pair);";
+ writeStreamMarshalUnmarshalCode(C, valueType, "__i->second", false);
+ C << eb;
+ C << eb;
+ }
+ }
+}
+
+void
+Slice::Gen::TypesVisitor::visitEnum(const EnumPtr& p)
+{
+ string name = fixKwd(p->name());
+ EnumeratorList enumerators = p->getEnumerators();
+ H << sp << nl << "enum " << name;
+ H << sb;
+ EnumeratorList::const_iterator en = enumerators.begin();
+ while(en != enumerators.end())
+ {
+ H << nl << fixKwd((*en)->name());
+ if(++en != enumerators.end())
+ {
+ H << ',';
+ }
+ }
+ H << eb << ';';
+
+ if(!p->isLocal())
+ {
+ string scoped = fixKwd(p->scoped());
+ string scope = fixKwd(p->scope());
+
+ size_t sz = enumerators.size();
+ assert(sz <= 0x7fffffff); // 64-bit enums are not supported
+
+ H << sp << nl << _dllExport << "void __write(::IceInternal::BasicStream*, " << name << ");";
+ H << nl << _dllExport << "void __read(::IceInternal::BasicStream*, " << name << "&);";
+
+ if(_stream)
+ {
+ H << sp << nl << _dllExport << "void ice_write" << p->name()
+ << "(const ::Ice::OutputStreamPtr&, " << name << ");";
+ H << nl << _dllExport << "void ice_read" << p->name() << "(const ::Ice::InputStreamPtr&, " << name << "&);";
+ }
+
+ C << sp << nl << "void" << nl << scope.substr(2) << "__write(::IceInternal::BasicStream* __os, " << scoped
+ << " v)";
+ C << sb;
+ if(sz <= 0x7f)
+ {
+ C << nl << "__os->write(static_cast< ::Ice::Byte>(v));";
+ }
+ else if(sz <= 0x7fff)
+ {
+ C << nl << "__os->write(static_cast< ::Ice::Short>(v));";
+ }
+ else
+ {
+ C << nl << "__os->write(static_cast< ::Ice::Int>(v));";
+ }
+ C << eb;
+
+ C << sp << nl << "void" << nl << scope.substr(2) << "__read(::IceInternal::BasicStream* __is, " << scoped
+ << "& v)";
+ C << sb;
+ if(sz <= 0x7f)
+ {
+ C << nl << "::Ice::Byte val;";
+ C << nl << "__is->read(val);";
+ C << nl << "v = static_cast< " << scoped << ">(val);";
+ }
+ else if(sz <= 0x7fff)
+ {
+ C << nl << "::Ice::Short val;";
+ C << nl << "__is->read(val);";
+ C << nl << "v = static_cast< " << scoped << ">(val);";
+ }
+ else
+ {
+ C << nl << "::Ice::Int val;";
+ C << nl << "__is->read(val);";
+ C << nl << "v = static_cast< " << scoped << ">(val);";
+ }
+ C << eb;
+
+ if(_stream)
+ {
+ C << sp << nl << "void" << nl << scope.substr(2) << "ice_write" << p->name()
+ << "(const ::Ice::OutputStreamPtr& __out, " << scoped << " v)";
+ C << sb;
+ if(sz <= 0x7f)
+ {
+ C << nl << "__out->writeByte(static_cast< ::Ice::Byte>(v));";
+ }
+ else if(sz <= 0x7fff)
+ {
+ C << nl << "__out->writeShort(static_cast< ::Ice::Short>(v));";
+ }
+ else
+ {
+ C << nl << "__out->writeInt(static_cast< ::Ice::Int>(v));";
+ }
+ C << eb;
+
+ C << sp << nl << "void" << nl << scope.substr(2) << "ice_read" << p->name()
+ << "(const ::Ice::InputStreamPtr& __in, " << scoped << "& v)";
+ C << sb;
+ if(sz <= 0x7f)
+ {
+ C << nl << "::Ice::Byte val = __in->readByte();";
+ C << nl << "v = static_cast< " << scoped << ">(val);";
+ }
+ else if(sz <= 0x7fff)
+ {
+ C << nl << "::Ice::Short val = __in->readShort();";
+ C << nl << "v = static_cast< " << scoped << ">(val);";
+ }
+ else
+ {
+ C << nl << "::Ice::Int val = __in->readInt();";
+ C << nl << "v = static_cast< " << scoped << ">(val);";
+ }
+ C << eb;
+ }
+ }
+}
+
+void
+Slice::Gen::TypesVisitor::visitConst(const ConstPtr& p)
+{
+ H << sp;
+ H << nl << "const " << typeToString(p->type()) << " " << fixKwd(p->name()) << " = ";
+
+ BuiltinPtr bp = BuiltinPtr::dynamicCast(p->type());
+ if(bp && bp->kind() == Builtin::KindString)
+ {
+ //
+ // Expand strings into the basic source character set. We can't use isalpha() and the like
+ // here because they are sensitive to the current locale.
+ //
+ static const string basicSourceChars = "abcdefghijklmnopqrstuvwxyz"
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ "0123456789"
+ "_{}[]#()<>%:;,?*+=/^&|~!=,\\\"' \t";
+ static const set<char> charSet(basicSourceChars.begin(), basicSourceChars.end());
+
+ H << "\""; // Opening "
+
+ ios_base::fmtflags originalFlags = H.flags(); // Save stream state
+ streamsize originalWidth = H.width();
+ ostream::char_type originalFill = H.fill();
+
+ const string val = p->value();
+ for(string::const_iterator c = val.begin(); c != val.end(); ++c)
+ {
+ if(charSet.find(*c) == charSet.end())
+ {
+ unsigned char uc = *c; // char may be signed, so make it positive
+ H << "\\"; // Print as octal if not in basic source character set
+ H.flags(ios_base::oct);
+ H.width(3);
+ H.fill('0');
+ H << static_cast<unsigned>(uc);
+ }
+ else
+ {
+ H << *c; // Print normally if in basic source character set
+ }
+ }
+
+ H.fill(originalFill); // Restore stream state
+ H.width(originalWidth);
+ H.flags(originalFlags);
+
+ H << "\""; // Closing "
+ }
+ else if(bp && bp->kind() == Builtin::KindLong)
+ {
+ H << "ICE_INT64(" << p->value() << ")";
+ }
+ else
+ {
+ EnumPtr ep = EnumPtr::dynamicCast(p->type());
+ if(ep)
+ {
+ H << fixKwd(p->value());
+ }
+ else
+ {
+ H << p->value();
+ }
+ }
+
+ H << ';';
+}
+
+Slice::Gen::ProxyDeclVisitor::ProxyDeclVisitor(Output& h, Output& c, const string& dllExport) :
+ H(h), C(c), _dllExport(dllExport)
+{
+}
+
+bool
+Slice::Gen::ProxyDeclVisitor::visitUnitStart(const UnitPtr& p)
+{
+ if(!p->hasNonLocalClassDecls())
+ {
+ return false;
+ }
+
+ H << sp << nl << "namespace IceProxy" << nl << '{';
+
+ return true;
+}
+
+void
+Slice::Gen::ProxyDeclVisitor::visitUnitEnd(const UnitPtr& p)
+{
+ H << sp << nl << '}';
+}
+
+bool
+Slice::Gen::ProxyDeclVisitor::visitModuleStart(const ModulePtr& p)
+{
+ if(!p->hasNonLocalClassDecls())
+ {
+ return false;
+ }
+
+ string name = fixKwd(p->name());
+
+ H << sp << nl << "namespace " << name << nl << '{';
+
+ return true;
+}
+
+void
+Slice::Gen::ProxyDeclVisitor::visitModuleEnd(const ModulePtr& p)
+{
+ H << sp << nl << '}';
+}
+
+void
+Slice::Gen::ProxyDeclVisitor::visitClassDecl(const ClassDeclPtr& p)
+{
+ if(p->isLocal())
+ {
+ return;
+ }
+
+ string name = fixKwd(p->name());
+
+ H << sp << nl << "class " << name << ';';
+ H << nl << _dllExport << "bool operator==(const " << name << "&, const " << name << "&);";
+ H << nl << _dllExport << "bool operator!=(const " << name << "&, const " << name << "&);";
+ H << nl << _dllExport << "bool operator<(const " << name << "&, const " << name << "&);";
+}
+
+Slice::Gen::ProxyVisitor::ProxyVisitor(Output& h, Output& c, const string& dllExport) :
+ H(h), C(c), _dllExport(dllExport)
+{
+}
+
+bool
+Slice::Gen::ProxyVisitor::visitUnitStart(const UnitPtr& p)
+{
+ if(!p->hasNonLocalClassDecls())
+ {
+ return false;
+ }
+
+ H << sp << nl << "namespace IceProxy" << nl << '{';
+
+ return true;
+}
+
+void
+Slice::Gen::ProxyVisitor::visitUnitEnd(const UnitPtr& p)
+{
+ H << sp << nl << '}';
+}
+
+bool
+Slice::Gen::ProxyVisitor::visitModuleStart(const ModulePtr& p)
+{
+ if(!p->hasNonLocalClassDecls())
+ {
+ return false;
+ }
+
+ string name = fixKwd(p->name());
+
+ H << sp << nl << "namespace " << name << nl << '{';
+
+ return true;
+}
+
+void
+Slice::Gen::ProxyVisitor::visitModuleEnd(const ModulePtr& p)
+{
+ H << sp << nl << '}';
+}
+
+bool
+Slice::Gen::ProxyVisitor::visitClassDefStart(const ClassDefPtr& p)
+{
+ if(p->isLocal())
+ {
+ return false;
+ }
+
+ string name = fixKwd(p->name());
+ string scoped = fixKwd(p->scoped());
+ ClassList bases = p->bases();
+
+ H << sp << nl << "class " << _dllExport << name << " : ";
+ if(bases.empty())
+ {
+ H << "virtual public ::IceProxy::Ice::Object";
+ }
+ else
+ {
+ H.useCurrentPosAsIndent();
+ ClassList::const_iterator q = bases.begin();
+ while(q != bases.end())
+ {
+ H << "virtual public ::IceProxy" << fixKwd((*q)->scoped());
+ if(++q != bases.end())
+ {
+ H << ',' << nl;
+ }
+ }
+ H.restoreIndent();
+ }
+
+ H << sb;
+ H.dec();
+ H << nl << "public:";
+ H.inc();
+
+ return true;
+}
+
+void
+Slice::Gen::ProxyVisitor::visitClassDefEnd(const ClassDefPtr& p)
+{
+ string scoped = fixKwd(p->scoped());
+ string scope = fixKwd(p->scope());
+
+ H << nl << nl << "static const ::std::string& ice_staticId();";
+
+ H.dec();
+ H << sp << nl << "private: ";
+ H.inc();
+ H << sp << nl << "virtual ::IceInternal::Handle< ::IceDelegateM::Ice::Object> __createDelegateM();";
+ H << nl << "virtual ::IceInternal::Handle< ::IceDelegateD::Ice::Object> __createDelegateD();";
+ H << eb << ';';
+
+ C << sp;
+ C << nl << "const ::std::string&" << nl << "IceProxy" << scoped << "::ice_staticId()";
+ C << sb;
+ C << nl << "return "<< scoped << "::ice_staticId();";
+ C << eb;
+
+ C << sp << nl << "::IceInternal::Handle< ::IceDelegateM::Ice::Object>";
+ C << nl << "IceProxy" << scoped << "::__createDelegateM()";
+ C << sb;
+ C << nl << "return ::IceInternal::Handle< ::IceDelegateM::Ice::Object>(new ::IceDelegateM" << scoped << ");";
+ C << eb;
+ C << sp << nl << "::IceInternal::Handle< ::IceDelegateD::Ice::Object>";
+ C << nl << "IceProxy" << scoped << "::__createDelegateD()";
+ C << sb;
+ C << nl << "return ::IceInternal::Handle< ::IceDelegateD::Ice::Object>(new ::IceDelegateD" << scoped << ");";
+ C << eb;
+
+ C << sp;
+ C << nl << "bool" << nl << "IceProxy" << scope << "operator==(const ::IceProxy" << scoped
+ << "& l, const ::IceProxy" << scoped << "& r)";
+ C << sb;
+ C << nl << "return static_cast<const ::IceProxy::Ice::Object&>(l) == "
+ << "static_cast<const ::IceProxy::Ice::Object&>(r);";
+ C << eb;
+ C << sp;
+ C << nl << "bool" << nl << "IceProxy" << scope << "operator!=(const ::IceProxy" << scoped
+ << "& l, const ::IceProxy" << scoped << "& r)";
+ C << sb;
+ C << nl << "return static_cast<const ::IceProxy::Ice::Object&>(l) != "
+ << "static_cast<const ::IceProxy::Ice::Object&>(r);";
+ C << eb;
+ C << sp;
+ C << nl << "bool" << nl << "IceProxy" << scope << "operator<(const ::IceProxy" << scoped
+ << "& l, const ::IceProxy" << scoped << "& r)";
+ C << sb;
+ C << nl << "return static_cast<const ::IceProxy::Ice::Object&>(l) < "
+ << "static_cast<const ::IceProxy::Ice::Object&>(r);";
+ C << eb;
+}
+
+void
+Slice::Gen::ProxyVisitor::visitOperation(const OperationPtr& p)
+{
+ string name = p->name();
+ string scoped = fixKwd(p->scoped());
+ string scope = fixKwd(p->scope());
+
+ TypePtr ret = p->returnType();
+ string retS = returnTypeToString(ret);
+
+ vector<string> params;
+ vector<string> paramsDecl;
+ vector<string> args;
+
+ vector<string> paramsAMI;
+ vector<string> paramsDeclAMI;
+ vector<string> argsAMI;
+
+ ParamDeclList paramList = p->parameters();
+ for(ParamDeclList::const_iterator q = paramList.begin(); q != paramList.end(); ++q)
+ {
+ string paramName = fixKwd((*q)->name());
+
+#if defined(__SUNPRO_CC) && (__SUNPRO_CC==0x550)
+ //
+ // Work around for Sun CC 5.5 bug #4853566
+ //
+ string typeString;
+ if((*q)->isOutParam())
+ {
+ typeString = outputTypeToString((*q)->type());
+ }
+ else
+ {
+ typeString = inputTypeToString((*q)->type());
+ }
+#else
+ string typeString = (*q)->isOutParam() ? outputTypeToString((*q)->type()) : inputTypeToString((*q)->type());
+#endif
+
+ params.push_back(typeString);
+ paramsDecl.push_back(typeString + ' ' + paramName);
+ args.push_back(paramName);
+
+ if(!(*q)->isOutParam())
+ {
+ string inputTypeString = inputTypeToString((*q)->type());
+
+ paramsAMI.push_back(inputTypeString);
+ paramsDeclAMI.push_back(inputTypeString + ' ' + paramName);
+ argsAMI.push_back(paramName);
+ }
+ }
+
+ string thisPointer = fixKwd(scope.substr(0, scope.size() - 2)) + "*";
+
+ H << sp;
+ H << nl << retS << ' ' << fixKwd(name) << spar << params << epar << ';';
+ H << nl << retS << ' ' << fixKwd(name) << spar << params << "const ::Ice::Context&" << epar << ';';
+
+ C << sp << nl << retS << nl << "IceProxy" << scoped << spar << paramsDecl << epar;
+ C << sb;
+ C << nl;
+ if(ret)
+ {
+ C << "return ";
+ }
+ C << fixKwd(name) << spar << args << "__defaultContext()" << epar << ';';
+ C << eb;
+
+ C << sp << nl << retS << nl << "IceProxy" << scoped << spar << paramsDecl << "const ::Ice::Context& __ctx" << epar;
+ C << sb;
+ C << nl << "int __cnt = 0;";
+ C << nl << "while(true)";
+ C << sb;
+ C << nl << "try";
+ C << sb;
+ if(p->returnsData())
+ {
+ C << nl << "__checkTwowayOnly(\"" << name << "\");";
+ }
+ C << nl << "::IceInternal::Handle< ::IceDelegate::Ice::Object> __delBase = __getDelegate();";
+ C << nl << "::IceDelegate" << thisPointer << " __del = dynamic_cast< ::IceDelegate"
+ << thisPointer << ">(__delBase.get());";
+ C << nl;
+ if(ret)
+ {
+ C << "return ";
+ }
+ C << "__del->" << fixKwd(name) << spar << args << "__ctx" << epar << ';';
+ if(!ret)
+ {
+ C << nl << "return;";
+ }
+ C << eb;
+ C << nl << "catch(const ::IceInternal::NonRepeatable& __ex)";
+ C << sb;
+ if(p->mode() == Operation::Idempotent || p->mode() == Operation::Nonmutating)
+ {
+ C << nl << "__handleException(*__ex.get(), __cnt);";
+ }
+ else
+ {
+ C << nl << "__rethrowException(*__ex.get());";
+ }
+ C << eb;
+ C << nl << "catch(const ::Ice::LocalException& __ex)";
+ C << sb;
+ C << nl << "__handleException(__ex, __cnt);";
+ C << eb;
+ C << eb;
+ C << eb;
+
+ ContainerPtr container = p->container();
+ ClassDefPtr cl = ClassDefPtr::dynamicCast(container);
+ if(cl->hasMetaData("ami") || p->hasMetaData("ami"))
+ {
+ string classNameAMI = "AMI_" + cl->name();
+ string classScope = fixKwd(cl->scope());
+ string classScopedAMI = classScope + classNameAMI;
+
+ H << nl << "void " << name << "_async" << spar << ("const" + classScopedAMI + '_' + name + "Ptr&")
+ << paramsAMI << epar << ';';
+ H << nl << "void " << name << "_async" << spar << ("const" + classScopedAMI + '_' + name + "Ptr&")
+ << paramsAMI << "const ::Ice::Context&" << epar << ';';
+
+ C << sp << nl << "void" << nl << "IceProxy" << scope << name << "_async" << spar
+ << ("const " + classScopedAMI + '_' + name + "Ptr& __cb") << paramsDeclAMI << epar;
+ C << sb;
+ C << nl << name << "_async" << spar << "__cb" << argsAMI << "__defaultContext()" << epar << ';';
+ C << eb;
+
+ C << sp << nl << "void" << nl << "IceProxy" << scope << name << "_async" << spar
+ << ("const " + classScopedAMI + '_' + name + "Ptr& __cb") << paramsDeclAMI << "const ::Ice::Context& __ctx"
+ << epar;
+ C << sb;
+ // Async requests may only be sent twoway.
+ C << nl << "__checkTwowayOnly(\"" << name << "\");";
+ C << nl << "__cb->__invoke" << spar << "this" << argsAMI << "__ctx" << epar << ';';
+ C << eb;
+ }
+}
+
+Slice::Gen::DelegateVisitor::DelegateVisitor(Output& h, Output& c, const string& dllExport) :
+ H(h), C(c), _dllExport(dllExport)
+{
+}
+
+bool
+Slice::Gen::DelegateVisitor::visitUnitStart(const UnitPtr& p)
+{
+ if(!p->hasNonLocalClassDecls())
+ {
+ return false;
+ }
+
+ H << sp << nl << "namespace IceDelegate" << nl << '{';
+
+ return true;
+}
+
+void
+Slice::Gen::DelegateVisitor::visitUnitEnd(const UnitPtr& p)
+{
+ H << sp << nl << '}';
+}
+
+bool
+Slice::Gen::DelegateVisitor::visitModuleStart(const ModulePtr& p)
+{
+ if(!p->hasNonLocalClassDecls())
+ {
+ return false;
+ }
+
+ string name = fixKwd(p->name());
+
+ H << sp << nl << "namespace " << name << nl << '{';
+
+ return true;
+}
+
+void
+Slice::Gen::DelegateVisitor::visitModuleEnd(const ModulePtr& p)
+{
+ H << sp << nl << '}';
+}
+
+bool
+Slice::Gen::DelegateVisitor::visitClassDefStart(const ClassDefPtr& p)
+{
+ if(p->isLocal())
+ {
+ return false;
+ }
+
+ string name = fixKwd(p->name());
+ ClassList bases = p->bases();
+
+ H << sp << nl << "class " << _dllExport << name << " : ";
+ if(bases.empty())
+ {
+ H << "virtual public ::IceDelegate::Ice::Object";
+ }
+ else
+ {
+ H.useCurrentPosAsIndent();
+ ClassList::const_iterator q = bases.begin();
+ while(q != bases.end())
+ {
+ H << "virtual public ::IceDelegate" << fixKwd((*q)->scoped());
+ if(++q != bases.end())
+ {
+ H << ',' << nl;
+ }
+ }
+ H.restoreIndent();
+ }
+ H << sb;
+ H.dec();
+ H << nl << "public:";
+ H.inc();
+
+ return true;
+}
+
+void
+Slice::Gen::DelegateVisitor::visitClassDefEnd(const ClassDefPtr& p)
+{
+ H << eb << ';';
+}
+
+void
+Slice::Gen::DelegateVisitor::visitOperation(const OperationPtr& p)
+{
+ string name = fixKwd(p->name());
+
+ TypePtr ret = p->returnType();
+ string retS = returnTypeToString(ret);
+
+ vector<string> params;
+
+ ParamDeclList paramList = p->parameters();
+ for(ParamDeclList::const_iterator q = paramList.begin(); q != paramList.end(); ++q)
+ {
+#if defined(__SUNPRO_CC) && (__SUNPRO_CC==0x550)
+ //
+ // Work around for Sun CC 5.5 bug #4853566
+ //
+ string typeString;
+ if((*q)->isOutParam())
+ {
+ typeString = outputTypeToString((*q)->type());
+ }
+ else
+ {
+ typeString = inputTypeToString((*q)->type());
+ }
+#else
+ string typeString = (*q)->isOutParam() ? outputTypeToString((*q)->type()) : inputTypeToString((*q)->type());
+#endif
+
+ params.push_back(typeString);
+ }
+
+ params.push_back("const ::Ice::Context&");
+
+ H << sp << nl << "virtual " << retS << ' ' << name << spar << params << epar << " = 0;";
+}
+
+Slice::Gen::DelegateMVisitor::DelegateMVisitor(Output& h, Output& c, const string& dllExport) :
+ H(h), C(c), _dllExport(dllExport)
+{
+}
+
+bool
+Slice::Gen::DelegateMVisitor::visitUnitStart(const UnitPtr& p)
+{
+ if(!p->hasNonLocalClassDecls())
+ {
+ return false;
+ }
+
+ H << sp << nl << "namespace IceDelegateM" << nl << '{';
+
+ return true;
+}
+
+void
+Slice::Gen::DelegateMVisitor::visitUnitEnd(const UnitPtr& p)
+{
+ H << sp << nl << '}';
+}
+
+bool
+Slice::Gen::DelegateMVisitor::visitModuleStart(const ModulePtr& p)
+{
+ if(!p->hasNonLocalClassDecls())
+ {
+ return false;
+ }
+
+ string name = fixKwd(p->name());
+
+ H << sp << nl << "namespace " << name << nl << '{';
+
+ return true;
+}
+
+void
+Slice::Gen::DelegateMVisitor::visitModuleEnd(const ModulePtr& p)
+{
+ H << sp << nl << '}';
+}
+
+bool
+Slice::Gen::DelegateMVisitor::visitClassDefStart(const ClassDefPtr& p)
+{
+ if(p->isLocal())
+ {
+ return false;
+ }
+
+ string name = fixKwd(p->name());
+ string scoped = fixKwd(p->scoped());
+ ClassList bases = p->bases();
+
+ H << sp << nl << "class " << _dllExport << name << " : ";
+ H.useCurrentPosAsIndent();
+ H << "virtual public ::IceDelegate" << scoped << ',';
+ if(bases.empty())
+ {
+ H << nl << "virtual public ::IceDelegateM::Ice::Object";
+ }
+ else
+ {
+ ClassList::const_iterator q = bases.begin();
+ while(q != bases.end())
+ {
+ H << nl << "virtual public ::IceDelegateM" << fixKwd((*q)->scoped());
+ if(++q != bases.end())
+ {
+ H << ',';
+ }
+ }
+ }
+ H.restoreIndent();
+ H << sb;
+ H.dec();
+ H << nl << "public:";
+ H.inc();
+
+ return true;
+}
+
+void
+Slice::Gen::DelegateMVisitor::visitClassDefEnd(const ClassDefPtr& p)
+{
+ H << eb << ';';
+}
+
+void
+Slice::Gen::DelegateMVisitor::visitOperation(const OperationPtr& p)
+{
+ string name = fixKwd(p->name());
+ string scoped = fixKwd(p->scoped());
+
+ TypePtr ret = p->returnType();
+ string retS = returnTypeToString(ret);
+
+ vector<string> params;
+ vector<string> paramsDecl;
+
+ TypeStringList inParams;
+ TypeStringList outParams;
+ ParamDeclList paramList = p->parameters();
+ for(ParamDeclList::const_iterator q = paramList.begin(); q != paramList.end(); ++q)
+ {
+ string paramName = fixKwd((*q)->name());
+ TypePtr type = (*q)->type();
+ bool isOutParam = (*q)->isOutParam();
+ string typeString;
+ if(isOutParam)
+ {
+ outParams.push_back(make_pair(type, paramName));
+ typeString = outputTypeToString(type);
+ }
+ else
+ {
+ inParams.push_back(make_pair(type, paramName));
+ typeString = inputTypeToString(type);
+ }
+
+ params.push_back(typeString);
+ paramsDecl.push_back(typeString + ' ' + paramName);
+ }
+
+ params.push_back("const ::Ice::Context&");
+ paramsDecl.push_back("const ::Ice::Context& __context");
+
+ H << sp << nl << "virtual " << retS << ' ' << name << spar << params << epar << ';';
+ C << sp << nl << retS << nl << "IceDelegateM" << scoped << spar << paramsDecl << epar;
+ C << sb;
+ C << nl << "static const ::std::string __operation(\"" << p->name() << "\");";
+ C << nl << "::IceInternal::Outgoing __out(__connection.get(), __reference.get(), __operation, "
+ << "static_cast< ::Ice::OperationMode>(" << p->mode() << "), __context, __compress);";
+ if(!inParams.empty())
+ {
+ C << nl << "try";
+ C << sb;
+ C << nl << "::IceInternal::BasicStream* __os = __out.os();";
+ writeMarshalCode(C, inParams, 0);
+ if(p->sendsClasses())
+ {
+ C << nl << "__os->writePendingObjects();";
+ }
+ C << eb;
+ C << nl << "catch(const ::Ice::LocalException& __ex)";
+ C << sb;
+ C << nl << "__out.abort(__ex);";
+ C << eb;
+ }
+ C << nl << "bool __ok = __out.invoke();";
+ C << nl << "try";
+ C << sb;
+ C << nl << "::IceInternal::BasicStream* __is = __out.is();";
+ C << nl << "if(!__ok)";
+ C << sb;
+ C << nl << "__is->throwException();";
+ C << eb;
+ writeAllocateCode(C, TypeStringList(), ret);
+ writeUnmarshalCode(C, outParams, ret);
+ if(p->returnsClasses())
+ {
+ C << nl << "__is->readPendingObjects();";
+ }
+ if(ret)
+ {
+ C << nl << "return __ret;";
+ }
+ C << eb;
+
+ //
+ // Generate a catch block for each legal user exception. This is necessary
+ // to prevent an "impossible" user exception to be thrown if client and
+ // and server use different exception specifications for an operation. For
+ // example:
+ //
+ // Client compiled with:
+ // exception A {};
+ // exception B {};
+ // interface I {
+ // void op() throws A;
+ // };
+ //
+ // Server compiled with:
+ // exception A {};
+ // exception B {};
+ // interface I {
+ // void op() throws B; // Differs from client
+ // };
+ //
+ // We need the catch blocks so, if the server throws B from op(), the
+ // client receives UnknownUserException instead of B.
+ //
+ 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&)";
+ C << sb;
+ C << nl << "throw ::Ice::UnknownUserException(__FILE__, __LINE__);";
+ C << eb;
+ C << nl << "catch(const ::Ice::LocalException& __ex)";
+ C << sb;
+ C << nl << "throw ::IceInternal::NonRepeatable(__ex);";
+ C << eb;
+ C << eb;
+}
+
+Slice::Gen::DelegateDVisitor::DelegateDVisitor(Output& h, Output& c, const string& dllExport) :
+ H(h), C(c), _dllExport(dllExport)
+{
+}
+
+bool
+Slice::Gen::DelegateDVisitor::visitUnitStart(const UnitPtr& p)
+{
+ if(!p->hasNonLocalClassDecls())
+ {
+ return false;
+ }
+
+ H << sp << nl << "namespace IceDelegateD" << nl << '{';
+
+ return true;
+}
+
+void
+Slice::Gen::DelegateDVisitor::visitUnitEnd(const UnitPtr& p)
+{
+ H << sp << nl << '}';
+}
+
+bool
+Slice::Gen::DelegateDVisitor::visitModuleStart(const ModulePtr& p)
+{
+ if(!p->hasNonLocalClassDecls())
+ {
+ return false;
+ }
+
+ string name = fixKwd(p->name());
+
+ H << sp << nl << "namespace " << name << nl << '{';
+
+ return true;
+}
+
+void
+Slice::Gen::DelegateDVisitor::visitModuleEnd(const ModulePtr& p)
+{
+ H << sp << nl << '}';
+}
+
+bool
+Slice::Gen::DelegateDVisitor::visitClassDefStart(const ClassDefPtr& p)
+{
+ if(p->isLocal())
+ {
+ return false;
+ }
+
+ string name = fixKwd(p->name());
+ string scoped = fixKwd(p->scoped());
+ ClassList bases = p->bases();
+
+ H << sp << nl << "class " << _dllExport << name << " : ";
+ H.useCurrentPosAsIndent();
+ H << "virtual public ::IceDelegate" << scoped << ',';
+ if(bases.empty())
+ {
+ H << nl << "virtual public ::IceDelegateD::Ice::Object";
+ }
+ else
+ {
+ ClassList::const_iterator q = bases.begin();
+ while(q != bases.end())
+ {
+ H << nl << "virtual public ::IceDelegateD" << fixKwd((*q)->scoped());
+ if(++q != bases.end())
+ {
+ H << ',';
+ }
+ }
+ }
+ H.restoreIndent();
+ H << sb;
+ H.dec();
+ H << nl << "public:";
+ H.inc();
+
+ return true;
+}
+
+void
+Slice::Gen::DelegateDVisitor::visitClassDefEnd(const ClassDefPtr& p)
+{
+ H << eb << ';';
+}
+
+void
+Slice::Gen::DelegateDVisitor::visitOperation(const OperationPtr& p)
+{
+ string name = fixKwd(p->name());
+ string scoped = fixKwd(p->scoped());
+
+ TypePtr ret = p->returnType();
+ string retS = returnTypeToString(ret);
+
+ vector<string> params;
+ vector<string> paramsDecl;
+ vector<string> args;
+
+ ParamDeclList paramList = p->parameters();
+ for(ParamDeclList::const_iterator q = paramList.begin(); q != paramList.end(); ++q)
+ {
+ string paramName = fixKwd((*q)->name());
+
+#if defined(__SUNPRO_CC) && (__SUNPRO_CC==0x550)
+ //
+ // Work around for Sun CC 5.5 bug #4853566
+ //
+ string typeString;
+ if((*q)->isOutParam())
+ {
+ typeString = outputTypeToString((*q)->type());
+ }
+ else
+ {
+ typeString = inputTypeToString((*q)->type());
+ }
+#else
+ string typeString = (*q)->isOutParam() ? outputTypeToString((*q)->type()) : inputTypeToString((*q)->type());
+#endif
+
+ params.push_back(typeString);
+ paramsDecl.push_back(typeString + ' ' + paramName);
+ args.push_back(paramName);
+ }
+
+ params.push_back("const ::Ice::Context&");
+ paramsDecl.push_back("const ::Ice::Context& __context");
+ args.push_back("__current");
+
+ ContainerPtr container = p->container();
+ ClassDefPtr cl = ClassDefPtr::dynamicCast(container);
+ string thisPointer = fixKwd(cl->scoped()) + "*";
+
+ H << sp;
+
+ H << nl << "virtual " << retS << ' ' << name << spar << params << epar << ';';
+ bool amd = !cl->isLocal() && (cl->hasMetaData("amd") || p->hasMetaData("amd"));
+ if(amd)
+ {
+ C << sp << nl << retS << nl << "IceDelegateD" << scoped << spar << params << epar;
+ C << sb;
+ C << nl << "throw ::Ice::CollocationOptimizationException(__FILE__, __LINE__);";
+ C << eb;
+ }
+ else
+ {
+ C << sp << nl << retS << nl << "IceDelegateD" << scoped << spar << paramsDecl << epar;
+ C << sb;
+ C << nl << "::Ice::Current __current;";
+ C << nl << "__initCurrent(__current, \"" << p->name()
+ << "\", static_cast< ::Ice::OperationMode>(" << p->mode() << "), __context);";
+ C << nl << "while(true)";
+ C << sb;
+ C << nl << "::IceInternal::Direct __direct(__current);";
+ C << nl << thisPointer << " __servant = dynamic_cast< " << thisPointer << ">(__direct.servant().get());";
+ C << nl << "if(!__servant)";
+ C << sb;
+ C << nl << "::Ice::OperationNotExistException __opEx(__FILE__, __LINE__);";
+ C << nl << "__opEx.id = __current.id;";
+ C << nl << "__opEx.facet = __current.facet;";
+ C << nl << "__opEx.operation = __current.operation;";
+ C << nl << "throw __opEx;";
+ C << eb;
+ C << nl << "try";
+ C << sb;
+ C << nl;
+ if(ret)
+ {
+ C << "return ";
+ }
+ C << "__servant->" << name << spar << args << epar << ';';
+ if(!ret)
+ {
+ C << nl << "return;";
+ }
+ C << eb;
+ C << nl << "catch(const ::Ice::LocalException& __ex)";
+ C << sb;
+ C << nl << "throw ::IceInternal::NonRepeatable(__ex);";
+ C << eb;
+ C << eb;
+ C << eb;
+ }
+}
+
+Slice::Gen::ObjectDeclVisitor::ObjectDeclVisitor(Output& h, Output& c, const string& dllExport) :
+ H(h), C(c), _dllExport(dllExport)
+{
+}
+
+bool
+Slice::Gen::ObjectDeclVisitor::visitModuleStart(const ModulePtr& p)
+{
+ if(!p->hasClassDecls())
+ {
+ return false;
+ }
+
+ string name = fixKwd(p->name());
+
+ H << sp << nl << "namespace " << name << nl << '{';
+
+ return true;
+}
+
+void
+Slice::Gen::ObjectDeclVisitor::visitModuleEnd(const ModulePtr& p)
+{
+ H << sp << nl << '}';
+}
+
+void
+Slice::Gen::ObjectDeclVisitor::visitClassDecl(const ClassDeclPtr& p)
+{
+ string name = fixKwd(p->name());
+
+ H << sp << nl << "class " << name << ';';
+ H << nl << _dllExport << "bool operator==(const " << name << "&, const " << name << "&);";
+ H << nl << _dllExport << "bool operator!=(const " << name << "&, const " << name << "&);";
+ H << nl << _dllExport << "bool operator<(const " << name << "&, const " << name << "&);";
+}
+
+Slice::Gen::ObjectVisitor::ObjectVisitor(Output& h, Output& c, const string& dllExport, bool stream) :
+ H(h), C(c), _dllExport(dllExport), _stream(stream)
+{
+}
+
+bool
+Slice::Gen::ObjectVisitor::visitModuleStart(const ModulePtr& p)
+{
+ if(!p->hasClassDefs())
+ {
+ return false;
+ }
+
+ string name = fixKwd(p->name());
+
+ H << sp << nl << "namespace " << name << nl << '{';
+
+ return true;
+}
+
+void
+Slice::Gen::ObjectVisitor::visitModuleEnd(const ModulePtr& p)
+{
+ H << sp;
+ H << nl << '}';
+}
+
+bool
+Slice::Gen::ObjectVisitor::visitClassDefStart(const ClassDefPtr& p)
+{
+ string name = fixKwd(p->name());
+ ClassList bases = p->bases();
+
+ H << sp;
+ H << nl << "class " << _dllExport << name << " : ";
+ H.useCurrentPosAsIndent();
+ if(bases.empty())
+ {
+ if(p->isLocal())
+ {
+ H << "virtual public ::Ice::LocalObject";
+ }
+ else
+ {
+ H << "virtual public ::Ice::Object";
+ }
+ }
+ else
+ {
+ ClassList::const_iterator q = bases.begin();
+ while(q != bases.end())
+ {
+ H << "virtual public " << fixKwd((*q)->scoped());
+ if(++q != bases.end())
+ {
+ H << ',' << nl;
+ }
+ }
+ }
+ H.restoreIndent();
+ H << sb;
+ H.dec();
+ H << nl << "public:";
+ H.inc();
+
+ if(!p->isAbstract() && !p->isLocal())
+ {
+ H << sp << nl << "void __copyMembers(" << fixKwd(p->scoped() + "Ptr") + ") const;";
+
+ C << sp;
+ C << nl << "void ";
+ C << nl << fixKwd(p->scoped()).substr(2) << "::__copyMembers(" << fixKwd(p->scoped() + "Ptr") << " __to) const";
+ C << sb;
+ string winUpcall;
+ string unixUpcall;
+ if(!bases.empty() && !bases.front()->isInterface())
+ {
+ winUpcall = fixKwd(bases.front()->name()) + "::__copyMembers(__to);";
+ unixUpcall = fixKwd(bases.front()->scoped()) + "::__copyMembers(__to);";
+ }
+ else
+ {
+ winUpcall = "Object::__copyMembers(__to);";
+ unixUpcall = "::Ice::Object::__copyMembers(__to);";
+ }
+ C.zeroIndent();
+ C << nl << "#if defined(_MSC_VER) && (_MSC_VER < 1300) // VC++ 6 compiler bug"; // COMPILERBUG
+ C.restoreIndent();
+ C << nl << winUpcall;
+ C.zeroIndent();
+ C << nl << "#else";
+ C.restoreIndent();
+ C << nl << unixUpcall;
+ C.zeroIndent();
+ C << nl << "#endif";
+ C.restoreIndent();
+ DataMemberList dataMembers = p->dataMembers();
+ for(DataMemberList::const_iterator q = dataMembers.begin(); q != dataMembers.end(); ++q)
+ {
+ C << nl << "__to->" << fixKwd((*q)->name()) << " = " << fixKwd((*q)->name()) << ';';
+ }
+ C << eb;
+
+ H << nl << "virtual ::Ice::ObjectPtr ice_clone() const;";
+
+ C << sp;
+ C << nl << "::Ice::ObjectPtr";
+ C << nl << fixKwd(p->scoped()).substr(2) << "::ice_clone() const";
+ C << sb;
+ C << nl << fixKwd(p->scope()) << p->name() << "Ptr __p = new " << fixKwd(p->scoped()) << ';';
+ C.zeroIndent();
+ C << nl << "#if defined(_MSC_VER) && (_MSC_VER < 1300) // VC++ 6 compiler bug"; // COMPILERBUG
+ C.restoreIndent();
+ C << nl << fixKwd(name) + "::__copyMembers(__p);";
+ C.zeroIndent();
+ C << nl << "#else";
+ C.restoreIndent();
+ C << nl << fixKwd(p->scoped()) + "::__copyMembers(__p);";
+ C.zeroIndent();
+ C << nl << "#endif";
+ C.restoreIndent();
+ C << nl << "return __p;";
+ C << eb;
+ }
+
+ if(!p->isLocal())
+ {
+ ClassList allBases = p->allBases();
+ StringList ids;
+#if defined(__IBMCPP__) && defined(NDEBUG)
+//
+// VisualAge C++ 6.0 does not see that ClassDef is a Contained,
+// when inlining is on. The code below issues a warning: better
+// than an error!
+//
+ transform(allBases.begin(), allBases.end(), back_inserter(ids), ::IceUtil::constMemFun<string,ClassDef>(&Contained::scoped));
+#else
+ transform(allBases.begin(), allBases.end(), back_inserter(ids), ::IceUtil::constMemFun(&Contained::scoped));
+#endif
+ StringList other;
+ other.push_back(p->scoped());
+ other.push_back("::Ice::Object");
+ other.sort();
+ ids.merge(other);
+ ids.unique();
+ StringList::const_iterator firstIter = ids.begin();
+ StringList::const_iterator scopedIter = find(ids.begin(), ids.end(), p->scoped());
+ assert(scopedIter != ids.end());
+ StringList::difference_type scopedPos = ice_distance(firstIter, scopedIter);
+
+ StringList::const_iterator q;
+
+ H << sp;
+ H << nl << "virtual bool ice_isA"
+ << "(const ::std::string&, const ::Ice::Current& = ::Ice::Current()) const;";
+ H << nl << "virtual ::std::vector< ::std::string> ice_ids"
+ << "(const ::Ice::Current& = ::Ice::Current()) const;";
+ H << nl << "virtual const ::std::string& ice_id(const ::Ice::Current& = ::Ice::Current()) const;";
+ H << nl << "static const ::std::string& ice_staticId();";
+
+ string flatName = p->flattenedScope() + p->name() + "_ids";
+
+ C << sp;
+ C << nl << "static const ::std::string " << flatName << '[' << ids.size() << "] =";
+ C << sb;
+ q = ids.begin();
+ while(q != ids.end())
+ {
+ C << nl << '"' << *q << '"';
+ if(++q != ids.end())
+ {
+ C << ',';
+ }
+ }
+ C << eb << ';';
+
+ C << sp;
+ C << nl << "bool" << nl << fixKwd(p->scoped()).substr(2)
+ << "::ice_isA(const ::std::string& _s, const ::Ice::Current&) const";
+ C << sb;
+ C << nl << "return ::std::binary_search(" << flatName << ", " << flatName << " + " << ids.size() << ", _s);";
+ C << eb;
+
+ C << sp;
+ C << nl << "::std::vector< ::std::string>" << nl << fixKwd(p->scoped()).substr(2)
+ << "::ice_ids(const ::Ice::Current&) const";
+ C << sb;
+ C << nl << "return ::std::vector< ::std::string>(&" << flatName << "[0], &" << flatName
+ << '[' << ids.size() << "]);";
+ C << eb;
+
+ C << sp;
+ C << nl << "const ::std::string&" << nl << fixKwd(p->scoped()).substr(2)
+ << "::ice_id(const ::Ice::Current&) const";
+ C << sb;
+ C << nl << "return " << flatName << '[' << scopedPos << "];";
+ C << eb;
+
+ C << sp;
+ C << nl << "const ::std::string&" << nl << fixKwd(p->scoped()).substr(2) << "::ice_staticId()";
+ C << sb;
+ C << nl << "return " << flatName << '[' << scopedPos << "];";
+ C << eb;
+
+ emitGCFunctions(p);
+ }
+
+ return true;
+}
+
+void
+Slice::Gen::ObjectVisitor::visitClassDefEnd(const ClassDefPtr& p)
+{
+ string scoped = fixKwd(p->scoped());
+ string scope = fixKwd(p->scope());
+
+ if(!p->isLocal())
+ {
+ ClassList bases = p->bases();
+ ClassDefPtr base;
+ if(!bases.empty() && !bases.front()->isInterface())
+ {
+ base = bases.front();
+ }
+
+ OperationList allOps = p->allOperations();
+ if(!allOps.empty())
+ {
+ StringList allOpNames;
+#if defined(__IBMCPP__) && defined(NDEBUG)
+//
+// See comment for transform above
+//
+ transform(allOps.begin(), allOps.end(), back_inserter(allOpNames),
+ ::IceUtil::constMemFun<string,Operation>(&Contained::name));
+#else
+ transform(allOps.begin(), allOps.end(), back_inserter(allOpNames),
+ ::IceUtil::constMemFun(&Contained::name));
+#endif
+ allOpNames.push_back("ice_id");
+ allOpNames.push_back("ice_ids");
+ allOpNames.push_back("ice_isA");
+ allOpNames.push_back("ice_ping");
+ allOpNames.sort();
+ allOpNames.unique();
+
+ StringList::const_iterator q;
+
+ H << sp;
+ H << nl
+ << "virtual ::IceInternal::DispatchStatus __dispatch(::IceInternal::Incoming&, const ::Ice::Current&);";
+
+ string flatName = p->flattenedScope() + p->name() + "_all";
+ C << sp;
+ C << nl << "static ::std::string " << flatName << "[] =";
+ C << sb;
+ q = allOpNames.begin();
+ while(q != allOpNames.end())
+ {
+ C << nl << '"' << *q << '"';
+ if(++q != allOpNames.end())
+ {
+ C << ',';
+ }
+ }
+ C << eb << ';';
+ C << sp;
+ C << nl << "::IceInternal::DispatchStatus" << nl << scoped.substr(2)
+ << "::__dispatch(::IceInternal::Incoming& in, const ::Ice::Current& current)";
+ C << sb;
+
+ C << nl << "::std::pair< ::std::string*, ::std::string*> r = "
+ << "::std::equal_range(" << flatName << ", " << flatName << " + " << allOpNames.size()
+ << ", current.operation);";
+ C << nl << "if(r.first == r.second)";
+ C << sb;
+ C << nl << "return ::IceInternal::DispatchOperationNotExist;";
+ C << eb;
+ C << sp;
+ C << nl << "switch(r.first - " << flatName << ')';
+ C << sb;
+ int i = 0;
+ for(q = allOpNames.begin(); q != allOpNames.end(); ++q)
+ {
+ C << nl << "case " << i++ << ':';
+ C << sb;
+ C << nl << "return ___" << *q << "(in, current);";
+ C << eb;
+ }
+ C << eb;
+ C << sp;
+ C << nl << "assert(false);";
+ C << nl << "return ::IceInternal::DispatchOperationNotExist;";
+ C << eb;
+ }
+
+ H << sp;
+ H << nl << "virtual void __write(::IceInternal::BasicStream*) const;";
+ H << nl << "virtual void __read(::IceInternal::BasicStream*, bool);";
+ H << nl << "virtual void __write(const ::Ice::OutputStreamPtr&) const;";
+ H << nl << "virtual void __read(const ::Ice::InputStreamPtr&, bool);";
+
+ TypeStringList memberList;
+ DataMemberList dataMembers = p->dataMembers();
+ for(DataMemberList::const_iterator q = dataMembers.begin(); q != dataMembers.end(); ++q)
+ {
+ memberList.push_back(make_pair((*q)->type(), (*q)->name()));
+ }
+ C << sp;
+ C << nl << "void" << nl << scoped.substr(2)
+ << "::__write(::IceInternal::BasicStream* __os) const";
+ C << sb;
+ C << nl << "__os->writeTypeId(ice_staticId());";
+ C << nl << "__os->startWriteSlice();";
+ writeMarshalCode(C, memberList, 0);
+ C << nl << "__os->endWriteSlice();";
+ C.zeroIndent();
+ C << nl << "#if defined(_MSC_VER) && (_MSC_VER < 1300) // VC++ 6 compiler bug"; // COMPILERBUG
+ C.restoreIndent();
+ C << nl << (base ? fixKwd(base->name()) : "Object") << "::__write(__os);";
+ C.zeroIndent();
+ C << nl << "#else";
+ C.restoreIndent();
+ C << nl << (base ? fixKwd(base->scoped()) : "::Ice::Object") << "::__write(__os);";
+ C.zeroIndent();
+ C << nl << "#endif";
+ C.restoreIndent();
+ C << eb;
+ C << sp;
+ C << nl << "void" << nl << scoped.substr(2) << "::__read(::IceInternal::BasicStream* __is, bool __rid)";
+ C << sb;
+ C << nl << "if(__rid)";
+ C << sb;
+ C << nl << "::std::string myId;";
+ C << nl << "__is->readTypeId(myId);";
+ C << eb;
+ C << nl << "__is->startReadSlice();";
+ writeUnmarshalCode(C, memberList, 0);
+ C << nl << "__is->endReadSlice();";
+ C.zeroIndent();
+ C << nl << "#if defined(_MSC_VER) && (_MSC_VER < 1300) // VC++ 6 compiler bug"; // COMPILERBUG
+ C.restoreIndent();
+ C << nl << (base ? fixKwd(base->name()) : "Object") << "::__read(__is, true);";
+ C.zeroIndent();
+ C << nl << "#else";
+ C.restoreIndent();
+ C << nl << (base ? fixKwd(base->scoped()) : "::Ice::Object") << "::__read(__is, true);";
+ C.zeroIndent();
+ C << nl << "#endif";
+ C.restoreIndent();
+ C << eb;
+
+ if(_stream)
+ {
+ C << sp;
+ C << nl << "void" << nl << scoped.substr(2) << "::__write(const ::Ice::OutputStreamPtr& __out) const";
+ C << sb;
+ C << nl << "__out->writeTypeId(ice_staticId());";
+ C << nl << "__out->startSlice();";
+ writeStreamMarshalCode(C, memberList, 0);
+ C << nl << "__out->endSlice();";
+ C.zeroIndent();
+ C << nl << "#if defined(_MSC_VER) && (_MSC_VER < 1300) // VC++ 6 compiler bug"; // COMPILERBUG
+ C.restoreIndent();
+ C << nl << (base ? fixKwd(base->name()) : "Object") << "::__write(__out);";
+ C.zeroIndent();
+ C << nl << "#else";
+ C.restoreIndent();
+ C << nl << (base ? fixKwd(base->scoped()) : "::Ice::Object") << "::__write(__out);";
+ C.zeroIndent();
+ C << nl << "#endif";
+ C.restoreIndent();
+ C << eb;
+ C << sp;
+ C << nl << "void" << nl << scoped.substr(2) << "::__read(const ::Ice::InputStreamPtr& __in, bool __rid)";
+ C << sb;
+ C << nl << "if(__rid)";
+ C << sb;
+ C << nl << "__in->readTypeId();";
+ C << eb;
+ C << nl << "__in->startSlice();";
+ writeStreamUnmarshalCode(C, memberList, 0);
+ C << nl << "__in->endSlice();";
+ C.zeroIndent();
+ C << nl << "#if defined(_MSC_VER) && (_MSC_VER < 1300) // VC++ 6 compiler bug"; // COMPILERBUG
+ C.restoreIndent();
+ C << nl << (base ? fixKwd(base->name()) : "Object") << "::__read(__in, true);";
+ C.zeroIndent();
+ C << nl << "#else";
+ C.restoreIndent();
+ C << nl << (base ? fixKwd(base->scoped()) : "::Ice::Object") << "::__read(__in, true);";
+ C.zeroIndent();
+ C << nl << "#endif";
+ C.restoreIndent();
+ C << eb;
+ }
+ else
+ {
+ //
+ // Emit placeholder functions to catch errors.
+ //
+ C << sp;
+ C << nl << "void" << nl << scoped.substr(2) << "::__write(const ::Ice::OutputStreamPtr&) const";
+ C << sb;
+ C << nl << "Ice::MarshalException ex(__FILE__, __LINE__);";
+ C << nl << "ex.reason = \"type " << scoped.substr(2) << " was not generated with stream support\";";
+ C << nl << "throw ex;";
+ C << eb;
+ C << sp;
+ C << nl << "void" << nl << scoped.substr(2) << "::__read(const ::Ice::InputStreamPtr&, bool)";
+ C << sb;
+ C << nl << "Ice::MarshalException ex(__FILE__, __LINE__);";
+ C << nl << "ex.reason = \"type " << scoped.substr(2) << " was not generated with stream support\";";
+ C << nl << "throw ex;";
+ C << eb;
+ }
+
+ if(!p->isAbstract())
+ {
+ H << sp << nl << "static const ::Ice::ObjectFactoryPtr& ice_factory();";
+
+ string factoryName = "__F" + p->flattenedScope() + p->name();
+ C << sp;
+ C << nl << "class " << factoryName << " : public ::Ice::ObjectFactory";
+ C << sb;
+ C.dec();
+ C << nl << "public:";
+ C.inc();
+ C << sp << nl << "virtual ::Ice::ObjectPtr" << nl << "create(const ::std::string& type)";
+ C << sb;
+ C << nl << "assert(type == " << scoped << "::ice_staticId());";
+ C << nl << "return new " << scoped << ';';
+ C << eb;
+ C << sp << nl << "virtual void" << nl << "destroy()";
+ C << sb;
+ C << eb;
+ C << eb << ';';
+
+ string flatName = factoryName + "_Ptr";
+ C << sp;
+ C << nl << "static ::Ice::ObjectFactoryPtr " << flatName << " = new " << factoryName << ';';
+
+ C << sp << nl << "const ::Ice::ObjectFactoryPtr&" << nl << scoped.substr(2) << "::ice_factory()";
+ C << sb;
+ C << nl << "return " << flatName << ';';
+ C << eb;
+
+ C << sp;
+ C << nl << "class " << factoryName << "__Init";
+ C << sb;
+ C.dec();
+ C << nl << "public:";
+ C.inc();
+ C << sp << nl << factoryName << "__Init()";
+ C << sb;
+ C << nl << "::Ice::factoryTable->addObjectFactory(" << scoped << "::ice_staticId(), "
+ << scoped << "::ice_factory());";
+ C << eb;
+ C << sp << nl << "~" << factoryName << "__Init()";
+ C << sb;
+ C << nl << "::Ice::factoryTable->removeObjectFactory(" << scoped << "::ice_staticId());";
+ C << eb;
+ C << eb << ';';
+
+ C << sp;
+ C << nl << "static " << factoryName << "__Init " << factoryName << "__i;";
+ C << sp << nl << "#ifdef __APPLE__";
+ std::string initfuncname = "__F" + p->flattenedScope() + p->name() + "__initializer";
+ C << nl << "extern \"C\" { void " << initfuncname << "() {} }";
+ C << nl << "#endif";
+ }
+ }
+
+ H << eb << ';';
+
+ if(!p->isAbstract() && !p->isLocal())
+ {
+ H << sp << nl << "static " << scoped << " __" << p->name() << "_init;";
+ }
+
+ if(p->isLocal())
+ {
+ C << sp;
+ C << nl << "bool" << nl << scope.substr(2) << "operator==(const " << scoped
+ << "& l, const " << scoped << "& r)";
+ C << sb;
+ C << nl << "return static_cast<const ::Ice::LocalObject&>(l) == static_cast<const ::Ice::LocalObject&>(r);";
+ C << eb;
+ C << sp;
+ C << nl << "bool" << nl << scope.substr(2) << "operator!=(const " << scoped
+ << "& l, const " << scoped << "& r)";
+ C << sb;
+ C << nl << "return static_cast<const ::Ice::LocalObject&>(l) != static_cast<const ::Ice::LocalObject&>(r);";
+ C << eb;
+ C << sp;
+ C << nl << "bool" << nl << scope.substr(2) << "operator<(const " << scoped
+ << "& l, const " << scoped << "& r)";
+ C << sb;
+ C << nl << "return static_cast<const ::Ice::LocalObject&>(l) < static_cast<const ::Ice::LocalObject&>(r);";
+ C << eb;
+ }
+ else
+ {
+ string name = p->name();
+
+ H << sp << nl << "void " << _dllExport << "__patch__" << name << "Ptr(void*, ::Ice::ObjectPtr&);";
+
+ C << sp << nl << "void " << _dllExport;
+ C << nl << scope.substr(2) << "__patch__" << name << "Ptr(void* __addr, ::Ice::ObjectPtr& v)";
+ C << sb;
+ C << nl << scope << name << "Ptr* p = static_cast< " << scope << name << "Ptr*>(__addr);";
+ C << nl << "assert(p);";
+ C << nl << "*p = " << scope << name << "Ptr::dynamicCast(v);";
+ C << nl << "if(v && !*p)";
+ C << sb;
+ C << nl << "::Ice::NoObjectFactoryException e(__FILE__, __LINE__);";
+ C << nl << "e.type = " << scope << fixKwd(name) << "::ice_staticId();";
+ C << nl << "throw e;";
+ C << eb;
+ C << eb;
+
+ C << sp;
+ C << nl << "bool" << nl << scope.substr(2) << "operator==(const " << scoped
+ << "& l, const " << scoped << "& r)";
+ C << sb;
+ C << nl << "return static_cast<const ::Ice::Object&>(l) == static_cast<const ::Ice::Object&>(r);";
+ C << eb;
+ C << sp;
+ C << nl << "bool" << nl << scope.substr(2) << "operator!=(const " << scoped
+ << "& l, const " << scoped << "& r)";
+ C << sb;
+ C << nl << "return static_cast<const ::Ice::Object&>(l) != static_cast<const ::Ice::Object&>(r);";
+ C << eb;
+ C << sp;
+ C << nl << "bool" << nl << scope.substr(2) << "operator<(const " << scoped
+ << "& l, const " << scoped << "& r)";
+ C << sb;
+ C << nl << "return static_cast<const ::Ice::Object&>(l) < static_cast<const ::Ice::Object&>(r);";
+ C << eb;
+ }
+}
+
+bool
+Slice::Gen::ObjectVisitor::visitExceptionStart(const ExceptionPtr&)
+{
+ return false;
+}
+
+bool
+Slice::Gen::ObjectVisitor::visitStructStart(const StructPtr&)
+{
+ return false;
+}
+
+void
+Slice::Gen::ObjectVisitor::visitOperation(const OperationPtr& p)
+{
+ string name = p->name();
+ string scoped = fixKwd(p->scoped());
+ string scope = fixKwd(p->scope());
+
+ TypePtr ret = p->returnType();
+ string retS = returnTypeToString(ret);
+
+ string params = "(";
+ string paramsDecl = "(";
+ string args = "(";
+
+ ContainerPtr container = p->container();
+ ClassDefPtr cl = ClassDefPtr::dynamicCast(container);
+ string classNameAMD = "AMD_" + cl->name();
+ string classScope = fixKwd(cl->scope());
+ string classScopedAMD = classScope + classNameAMD;
+
+ string paramsAMD = "(const " + classScopedAMD + '_' + name + "Ptr&, ";
+ string paramsDeclAMD = "(const " + classScopedAMD + '_' + name + "Ptr& __cb, ";
+ string argsAMD = "(__cb, ";
+
+ TypeStringList inParams;
+ TypeStringList outParams;
+ ParamDeclList paramList = p->parameters();
+ for(ParamDeclList::const_iterator q = paramList.begin(); q != paramList.end(); ++q)
+ {
+ string paramName = fixKwd((*q)->name());
+ TypePtr type = (*q)->type();
+ bool isOutParam = (*q)->isOutParam();
+ string typeString;
+ if(isOutParam)
+ {
+ outParams.push_back(make_pair(type, paramName));
+ typeString = outputTypeToString(type);
+ }
+ else
+ {
+ inParams.push_back(make_pair(type, paramName));
+ typeString = inputTypeToString((*q)->type());
+ }
+
+ if(q != paramList.begin())
+ {
+ params += ", ";
+ paramsDecl += ", ";
+ args += ", ";
+ }
+
+ params += typeString;
+ paramsDecl += typeString;
+ paramsDecl += ' ';
+ paramsDecl += paramName;
+ args += paramName;
+
+ if(!isOutParam)
+ {
+ paramsAMD += typeString;
+ paramsAMD += ", ";
+ paramsDeclAMD += typeString;
+ paramsDeclAMD += ' ';
+ paramsDeclAMD += paramName;
+ paramsDeclAMD += ", ";
+ argsAMD += paramName;
+ argsAMD += ", ";
+ }
+ }
+
+ if(!cl->isLocal())
+ {
+ if(!paramList.empty())
+ {
+ params += ", ";
+ paramsDecl += ", ";
+ args += ", ";
+ }
+
+ params += "const ::Ice::Current& = ::Ice::Current())";
+ paramsDecl += "const ::Ice::Current& __current)";
+ args += "__current)";
+ }
+ else
+ {
+ params += ')';
+ paramsDecl += ')';
+ args += ')';
+ }
+
+ paramsAMD += "const ::Ice::Current& = ::Ice::Current())";
+ paramsDeclAMD += "const ::Ice::Current& __current)";
+ argsAMD += "__current)";
+
+ bool nonmutating = p->mode() == Operation::Nonmutating;
+ bool amd = !cl->isLocal() && (cl->hasMetaData("amd") || p->hasMetaData("amd"));
+
+ H << sp;
+ if(!amd)
+ {
+ H << nl << "virtual " << retS << ' ' << fixKwd(name) << params
+ << (nonmutating ? " const" : "") << " = 0;";
+ }
+ else
+ {
+ H << nl << "virtual void " << name << "_async" << paramsAMD
+ << (nonmutating ? " const" : "") << " = 0;";
+ }
+
+ if(!cl->isLocal())
+ {
+ H << nl << "::IceInternal::DispatchStatus ___" << name
+ << "(::IceInternal::Incoming&, const ::Ice::Current&)" << (nonmutating ? " const" : "") << ';';
+
+ C << sp;
+ C << nl << "::IceInternal::DispatchStatus" << nl << scope.substr(2) << "___" << name
+ << "(::IceInternal::Incoming& __in, const ::Ice::Current& __current)" << (nonmutating ? " const" : "");
+ C << sb;
+ if(!amd)
+ {
+ ExceptionList throws = p->throws();
+ throws.sort();
+ throws.unique();
+
+ //
+ // Arrange exceptions into most-derived to least-derived order. If we don't
+ // do this, a base exception handler can appear before a derived exception
+ // handler, causing compiler warnings and resulting in the base exception
+ // being marshaled instead of the derived exception.
+ //
+
+#if defined(__SUNPRO_CC)
+ throws.sort(derivedToBaseCompare);
+#else
+ throws.sort(Slice::DerivedToBaseCompare());
+#endif
+
+ if(!inParams.empty())
+ {
+ C << nl << "::IceInternal::BasicStream* __is = __in.is();";
+ }
+ if(ret || !outParams.empty() || !throws.empty())
+ {
+ C << nl << "::IceInternal::BasicStream* __os = __in.os();";
+ }
+ writeAllocateCode(C, inParams, 0);
+ writeUnmarshalCode(C, inParams, 0);
+ if(p->sendsClasses())
+ {
+ C << nl << "__is->readPendingObjects();";
+ }
+ writeAllocateCode(C, outParams, 0);
+ if(!throws.empty())
+ {
+ C << nl << "try";
+ C << sb;
+ }
+ C << nl;
+ if(ret)
+ {
+ C << retS << " __ret = ";
+ }
+ C << fixKwd(name) << args << ';';
+ writeMarshalCode(C, outParams, ret);
+ if(p->returnsClasses())
+ {
+ C << nl << "__os->writePendingObjects();";
+ }
+ if(!throws.empty())
+ {
+ C << eb;
+ ExceptionList::const_iterator r;
+ for(r = throws.begin(); r != throws.end(); ++r)
+ {
+ C << nl << "catch(const " << fixKwd((*r)->scoped()) << "& __ex)";
+ C << sb;
+ C << nl << "__os->write(__ex);";
+ C << nl << "return ::IceInternal::DispatchUserException;";
+ C << eb;
+ }
+ }
+ C << nl << "return ::IceInternal::DispatchOK;";
+ }
+ else
+ {
+ if(!inParams.empty())
+ {
+ C << nl << "::IceInternal::BasicStream* __is = __in.is();";
+ }
+ writeAllocateCode(C, inParams, 0);
+ writeUnmarshalCode(C, inParams, 0);
+ if(p->sendsClasses())
+ {
+ C << nl << "__is->readPendingObjects();";
+ }
+ C << nl << classScopedAMD << '_' << name << "Ptr __cb = new IceAsync" << classScopedAMD << '_' << name
+ << "(__in);";
+ C << nl << "try";
+ C << sb;
+ C << nl << name << "_async" << argsAMD << ';';
+ C << eb;
+ C << nl << "catch(const ::Ice::Exception& __ex)";
+ C << sb;
+ C << nl << "__cb->ice_exception(__ex);";
+ C << eb;
+ C << nl << "catch(const ::std::exception& __ex)";
+ C << sb;
+ C << nl << "__cb->ice_exception(__ex);";
+ C << eb;
+ C << nl << "catch(...)";
+ C << sb;
+ C << nl << "__cb->ice_exception();";
+ C << eb;
+ C << nl << "return ::IceInternal::DispatchAsync;";
+ }
+ C << eb;
+ }
+}
+
+void
+Slice::Gen::ObjectVisitor::visitDataMember(const DataMemberPtr& p)
+{
+ string name = fixKwd(p->name());
+ string s = typeToString(p->type());
+ H << sp;
+ H << nl << s << ' ' << name << ';';
+}
+
+void
+Slice::Gen::ObjectVisitor::emitGCFunctions(const ClassDefPtr& p)
+{
+ string scoped = fixKwd(p->scoped());
+ ClassList bases = p->bases();
+ DataMemberList dataMembers = p->dataMembers();
+
+ //
+ // A class can potentially be part of a cycle if it (recursively) contains class
+ // members. If so, we override __incRef() and __decRef() and, hence, consider instances
+ // of the class as candidates for collection by the garbage collector.
+ // We override __incRef() and __decRef() only once, in the basemost potentially cyclic class
+ // in an inheritance hierarchy.
+ //
+ bool hasBaseClass = !bases.empty() && !bases.front()->isInterface();
+ bool canBeCyclic = p->canBeCyclic();
+ bool override = canBeCyclic && (!hasBaseClass || !bases.front()->canBeCyclic());
+
+ if(override)
+ {
+ H << nl << "virtual void __incRef();";
+
+ C << sp << nl << "void" << nl << scoped.substr(2) << "::__incRef()";
+ C << sb;
+ C << nl << "IceUtil::gcRecMutex._m->lock();";
+ C << nl << "assert(_ref >= 0);";
+ C << nl << "if(_ref == 0)";
+ C << sb;
+ C.zeroIndent();
+ C << nl << "#ifdef NDEBUG // To avoid annoying warnings about variables that are not used...";
+ C.restoreIndent();
+ C << nl << "IceUtil::gcObjects.insert(this);";
+ C.zeroIndent();
+ C << nl << "#else";
+ C.restoreIndent();
+ C << nl << "std::pair<IceUtil::GCObjectSet::iterator, bool> rc = IceUtil::gcObjects.insert(this);";
+ C << nl << "assert(rc.second);";
+ C.zeroIndent();
+ C << nl << "#endif";
+ C.restoreIndent();
+ C << eb;
+ C << nl << "++_ref;";
+ C << nl << "IceUtil::gcRecMutex._m->unlock();";
+ C << eb;
+
+ H << nl << "virtual void __decRef();";
+
+ C << sp << nl << "void" << nl << scoped.substr(2) << "::__decRef()";
+ C << sb;
+ C << nl << "IceUtil::gcRecMutex._m->lock();";
+ C << nl << "bool doDelete = false;";
+ C << nl << "assert(_ref > 0);";
+ C << nl << "if(--_ref == 0)";
+ C << sb;
+ C << nl << "doDelete = !_noDelete;";
+ C << nl << "_noDelete = true;";
+ C.zeroIndent();
+ C << nl << "#ifdef NDEBUG // To avoid annoying warnings about variables that are not used...";
+ C.restoreIndent();
+ C << nl << "IceUtil::gcObjects.erase(this);";
+ C.zeroIndent();
+ C << nl << "#else";
+ C.restoreIndent();
+ C << nl << "IceUtil::GCObjectSet::size_type num = IceUtil::gcObjects.erase(this);";
+ C << nl << "assert(num == 1);";
+ C.zeroIndent();
+ C << nl << "#endif";
+ C.restoreIndent();
+ C << eb;
+ C << nl << "IceUtil::gcRecMutex._m->unlock();";
+ C << nl << "if(doDelete)";
+ C << sb;
+ C << nl << "delete this;";
+ C << eb;
+ C << eb;
+ }
+
+ //
+ // __gcReachable() and __gcClear() are overridden by the basemost class that
+ // can be cyclic, plus all classes derived from that class.
+ //
+ if(canBeCyclic)
+ {
+ H << nl << "virtual void __gcReachable(::IceUtil::GCObjectMultiSet&) const;";
+
+ C << sp << nl << "void" << nl << scoped.substr(2) << "::__gcReachable(::IceUtil::GCObjectMultiSet& _c) const";
+ C << sb;
+
+ string vc6Prefix;
+ string otherPrefix;
+
+ bool hasCyclicBase = hasBaseClass && bases.front()->canBeCyclic();
+ if(hasCyclicBase)
+ {
+ vc6Prefix = bases.front()->name();
+ otherPrefix = bases.front()->scoped();
+
+ //
+ // Up-call to the base's __gcReachable() member function.
+ //
+ C.zeroIndent();
+ C << nl << "#if defined(_MSC_VER) && (MSC_VER < 1300) // VC++ 6 compiler bug";
+ C.restoreIndent();
+ C << nl << vc6Prefix << "::__gcReachable(_c);";
+ C.zeroIndent();
+ C << nl << "#else";
+ C.restoreIndent();
+ C << nl << otherPrefix << "::__gcReachable(_c);";
+ C.zeroIndent();
+ C << nl << "#endif";
+ C.restoreIndent();
+ }
+ for(DataMemberList::const_iterator i = dataMembers.begin(); i != dataMembers.end(); ++i)
+ {
+ if((*i)->type()->usesClasses())
+ {
+ emitGCInsertCode((*i)->type(), fixKwd((*i)->name()), "", 0);
+ }
+ }
+ C << eb;
+
+ H << nl << "virtual void __gcClear();";
+
+ C << sp << nl << "void" << nl << scoped.substr(2) << "::__gcClear()";
+ C << sb;
+ if(hasCyclicBase)
+ {
+ //
+ // Up-call to the base's __gcClear() member function.
+ //
+ C.zeroIndent();
+ C << nl << "#if defined(_MSC_VER) && (MSC_VER < 1300) // VC++ 6 compiler bug";
+ C.restoreIndent();
+ C << nl << vc6Prefix<< "::__gcClear();";
+ C.zeroIndent();
+ C << nl << "#else";
+ C.restoreIndent();
+ C << nl << otherPrefix << "::__gcClear();";
+ C.zeroIndent();
+ C << nl << "#endif";
+ C.restoreIndent();
+ }
+ for(DataMemberList::const_iterator j = dataMembers.begin(); j != dataMembers.end(); ++j)
+ {
+ if((*j)->type()->usesClasses())
+ {
+ emitGCClearCode((*j)->type(), fixKwd((*j)->name()), "", 0);
+ }
+ }
+ C << eb;
+ }
+}
+
+void
+Slice::Gen::ObjectVisitor::emitGCInsertCode(const TypePtr& p, const string& prefix, const string& name, int level)
+{
+ if((BuiltinPtr::dynamicCast(p) && BuiltinPtr::dynamicCast(p)->kind() == Builtin::KindObject)
+ || ClassDeclPtr::dynamicCast(p))
+ {
+ C << nl << "__addObject(_c, " << prefix << name << ".get());";
+ }
+ else if(StructPtr s = StructPtr::dynamicCast(p))
+ {
+ DataMemberList dml = s->dataMembers();
+ for(DataMemberList::const_iterator i = dml.begin(); i != dml.end(); ++i)
+ {
+ if((*i)->type()->usesClasses())
+ {
+ emitGCInsertCode((*i)->type(), prefix + name + ".", fixKwd((*i)->name()), ++level);
+ }
+ }
+ }
+ else if(DictionaryPtr d = DictionaryPtr::dynamicCast(p))
+ {
+ string scoped = fixKwd(d->scoped());
+ stringstream tmp;
+ tmp << "_i" << level;
+ string iterName = tmp.str();
+ C << sb;
+ C << nl << "for(" << scoped << "::const_iterator " << iterName << " = " << prefix + name
+ << ".begin(); " << iterName << " != " << prefix + name << ".end(); ++" << iterName << ")";
+ C << sb;
+ emitGCInsertCode(d->valueType(), "", string("(*") + iterName + ").second", ++level);
+ C << eb;
+ C << eb;
+ }
+ else if(SequencePtr s = SequencePtr::dynamicCast(p))
+ {
+ string scoped = fixKwd(s->scoped());
+ stringstream tmp;
+ tmp << "_i" << level;
+ string iterName = tmp.str();
+ C << sb;
+ C << nl << "for(" << scoped << "::const_iterator " << iterName << " = " << prefix + name
+ << ".begin(); " << iterName << " != " << prefix + name << ".end(); ++" << iterName << ")";
+ C << sb;
+ emitGCInsertCode(s->type(), string("(*") + iterName + ")", "", ++level);
+ C << eb;
+ C << eb;
+ }
+}
+
+void
+Slice::Gen::ObjectVisitor::emitGCClearCode(const TypePtr& p, const string& prefix, const string& name, int level)
+{
+ if((BuiltinPtr::dynamicCast(p) && BuiltinPtr::dynamicCast(p)->kind() == Builtin::KindObject)
+ || ClassDeclPtr::dynamicCast(p))
+ {
+ C << nl << "if(" << prefix << name << ")";
+ C << sb;
+ C << nl << prefix << name << "->__decRefUnsafe();";
+ C << nl << prefix << name << ".__clearHandleUnsafe();";
+ C << eb;
+ }
+ else if(StructPtr s = StructPtr::dynamicCast(p))
+ {
+ DataMemberList dml = s->dataMembers();
+ for(DataMemberList::const_iterator i = dml.begin(); i != dml.end(); ++i)
+ {
+ if((*i)->type()->usesClasses())
+ {
+ emitGCClearCode((*i)->type(), prefix + name + ".", fixKwd((*i)->name()), ++level);
+ }
+ }
+ }
+ else if(DictionaryPtr d = DictionaryPtr::dynamicCast(p))
+ {
+ string scoped = fixKwd(d->scoped());
+ stringstream tmp;
+ tmp << "_i" << level;
+ string iterName = tmp.str();
+ C << sb;
+ C << nl << "for(" << scoped << "::iterator " << iterName << " = " << prefix + name
+ << ".begin(); " << iterName << " != " << prefix + name << ".end(); ++" << iterName << ")";
+ C << sb;
+ emitGCClearCode(d->valueType(), "", string("(*") + iterName + ").second", ++level);
+ C << eb;
+ C << eb;
+ }
+ else if(SequencePtr s = SequencePtr::dynamicCast(p))
+ {
+ string scoped = fixKwd(s->scoped());
+ stringstream tmp;
+ tmp << "_i" << level;
+ string iterName = tmp.str();
+ C << sb;
+ C << nl << "for(" << scoped << "::iterator " << iterName << " = " << prefix + name
+ << ".begin(); " << iterName << " != " << prefix + name << ".end(); ++" << iterName << ")";
+ C << sb;
+ emitGCClearCode(s->type(), "", string("(*") + iterName + ")", ++level);
+ C << eb;
+ C << eb;;
+ }
+}
+
+Slice::Gen::IceInternalVisitor::IceInternalVisitor(Output& h, Output& c, const string& dllExport) :
+ H(h), C(c), _dllExport(dllExport)
+{
+}
+
+bool
+Slice::Gen::IceInternalVisitor::visitUnitStart(const UnitPtr& p)
+{
+ if(!p->hasClassDecls())
+ {
+ return false;
+ }
+
+ H << sp;
+ H << nl << "namespace IceInternal" << nl << '{';
+
+ return true;
+}
+
+void
+Slice::Gen::IceInternalVisitor::visitUnitEnd(const UnitPtr& p)
+{
+ H << sp;
+ H << nl << '}';
+}
+
+void
+Slice::Gen::IceInternalVisitor::visitClassDecl(const ClassDeclPtr& p)
+{
+ string scoped = fixKwd(p->scoped());
+
+ H << sp;
+ H << nl << _dllExport << "void incRef(" << scoped << "*);";
+ H << nl << _dllExport << "void decRef(" << scoped << "*);";
+ if(!p->isLocal())
+ {
+ H << sp;
+ H << nl << _dllExport << "void incRef(::IceProxy" << scoped << "*);";
+ H << nl << _dllExport << "void decRef(::IceProxy" << scoped << "*);";
+ }
+}
+
+bool
+Slice::Gen::IceInternalVisitor::visitClassDefStart(const ClassDefPtr& p)
+{
+ string scoped = fixKwd(p->scoped());
+
+ C << sp;
+ C << nl << "void" << nl << "IceInternal::incRef(" << scoped << "* p)";
+ C << sb;
+ C << nl << "p->__incRef();";
+ C << eb;
+
+ C << sp;
+ C << nl << "void" << nl << "IceInternal::decRef(" << scoped << "* p)";
+ C << sb;
+ C << nl << "p->__decRef();";
+ C << eb;
+
+ if(!p->isLocal())
+ {
+ C << sp;
+ C << nl << "void" << nl << "IceInternal::incRef(::IceProxy" << scoped << "* p)";
+ C << sb;
+ C << nl << "p->__incRef();";
+ C << eb;
+
+ C << sp;
+ C << nl << "void" << nl << "IceInternal::decRef(::IceProxy" << scoped << "* p)";
+ C << sb;
+ C << nl << "p->__decRef();";
+ C << eb;
+ }
+
+ return true;
+}
+
+Slice::Gen::HandleVisitor::HandleVisitor(Output& h, Output& c, const string& dllExport, bool stream) :
+ H(h), C(c), _dllExport(dllExport), _stream(stream)
+{
+}
+
+bool
+Slice::Gen::HandleVisitor::visitModuleStart(const ModulePtr& p)
+{
+ if(!p->hasClassDecls())
+ {
+ return false;
+ }
+
+ string name = fixKwd(p->name());
+
+ H << sp;
+ H << nl << "namespace " << name << nl << '{';
+
+ return true;
+}
+
+void
+Slice::Gen::HandleVisitor::visitModuleEnd(const ModulePtr& p)
+{
+ H << sp;
+ H << nl << '}';
+}
+
+void
+Slice::Gen::HandleVisitor::visitClassDecl(const ClassDeclPtr& p)
+{
+ string name = p->name();
+ string scoped = fixKwd(p->scoped());
+
+ H << sp;
+ H << nl << "typedef ::IceInternal::Handle< " << scoped << "> " << name << "Ptr;";
+ if(!p->isLocal())
+ {
+ H << nl << "typedef ::IceInternal::ProxyHandle< ::IceProxy" << scoped << "> " << name << "Prx;";
+
+ H << sp;
+ H << nl << _dllExport << "void __write(::IceInternal::BasicStream*, const " << name << "Prx&);";
+ H << nl << _dllExport << "void __read(::IceInternal::BasicStream*, " << name << "Prx&);";
+ H << nl << _dllExport << "void __write(::IceInternal::BasicStream*, const " << name << "Ptr&);";
+ H << nl << _dllExport << "void __patch__" << name << "Ptr(void*, ::Ice::ObjectPtr&);";
+ if(_stream)
+ {
+ H << sp;
+ H << nl << _dllExport << "void ice_write" << name << "Prx(const ::Ice::OutputStreamPtr&, const " << name
+ << "Prx&);";
+ H << nl << _dllExport << "void ice_read" << name << "Prx(const ::Ice::InputStreamPtr&, " << name
+ << "Prx&);";
+
+ H << nl << _dllExport << "void ice_write" << name << "(const ::Ice::OutputStreamPtr&, const "
+ << name << "Ptr&);";
+ H << nl << _dllExport << "void ice_read" << name << "(const ::Ice::InputStreamPtr&, " << name << "Ptr&);";
+ }
+ }
+}
+
+bool
+Slice::Gen::HandleVisitor::visitClassDefStart(const ClassDefPtr& p)
+{
+ if(!p->isLocal())
+ {
+ string name = p->name();
+ string scoped = fixKwd(p->scoped());
+ string scope = fixKwd(p->scope());
+
+ string factory;
+ string type;
+ if(!p->isAbstract())
+ {
+ type = scoped + "::ice_staticId()";
+ factory = scoped + "::ice_factory()";
+ }
+ else
+ {
+ type = "\"\"";
+ factory = "0";
+ }
+
+ C << sp;
+ C << nl << "void" << nl << scope.substr(2) << "__write(::IceInternal::BasicStream* __os, const "
+ << scope << name << "Prx& v)";
+ C << sb;
+ C << nl << "__os->write(::Ice::ObjectPrx(v));";
+ C << eb;
+
+ C << sp;
+ C << nl << "void" << nl << scope.substr(2) << "__read(::IceInternal::BasicStream* __is, "
+ << scope << name << "Prx& v)";
+ C << sb;
+ C << nl << "::Ice::ObjectPrx proxy;";
+ C << nl << "__is->read(proxy);";
+ C << nl << "if(!proxy)";
+ C << sb;
+ C << nl << "v = 0;";
+ C << eb;
+ C << nl << "else";
+ C << sb;
+ C << nl << "v = new ::IceProxy" << scoped << ';';
+ C << nl << "v->__copyFrom(proxy);";
+ C << eb;
+ C << eb;
+
+ C << sp;
+ C << nl << "void" << nl << scope.substr(2) << "__write(::IceInternal::BasicStream* __os, const "
+ << scope << name << "Ptr& v)";
+ C << sb;
+ C << nl << "__os->write(::Ice::ObjectPtr(v));";
+ C << eb;
+
+ if(_stream)
+ {
+ C << sp;
+ C << nl << "void" << nl << scope.substr(2) << "ice_write" << name
+ << "Prx(const ::Ice::OutputStreamPtr& __out, const " << scope << name << "Prx& v)";
+ C << sb;
+ C << nl << "__out->writeProxy(v);";
+ C << eb;
+
+ C << sp;
+ C << nl << "void" << nl << scope.substr(2) << "ice_read" << name
+ << "Prx(const ::Ice::InputStreamPtr& __in, " << scope << name << "Prx& v)";
+ C << sb;
+ C << nl << "::Ice::ObjectPrx proxy = __in->readProxy();";
+ C << nl << "if(!proxy)";
+ C << sb;
+ C << nl << "v = 0;";
+ C << eb;
+ C << nl << "else";
+ C << sb;
+ C << nl << "v = new ::IceProxy" << scoped << ';';
+ C << nl << "v->__copyFrom(proxy);";
+ C << eb;
+ C << eb;
+
+ C << sp;
+ C << nl << "void" << nl << scope.substr(2) << "ice_write" << name
+ << "(const ::Ice::OutputStreamPtr& __out, const " << scope << name << "Ptr& v)";
+ C << sb;
+ C << nl << "__out->writeObject(v);";
+ C << eb;
+
+ C << sp;
+ C << nl << "void" << nl << scope.substr(2) << "ice_read" << name << "(const ::Ice::InputStreamPtr& __in, "
+ << scoped << "Ptr& __v)";
+ C << sb;
+ C << nl << "::Ice::ReadObjectCallbackPtr __cb = new ::Ice::ReadObjectCallbackI(" << scope << "__patch__"
+ << name << "Ptr, &__v);";
+ C << nl << "__in->readObject(__cb);";
+ C << eb;
+ }
+ }
+
+ return true;
+}
+
+Slice::Gen::ImplVisitor::ImplVisitor(Output& h, Output& c,
+ const string& dllExport) :
+ H(h), C(c), _dllExport(dllExport)
+{
+}
+
+void
+Slice::Gen::ImplVisitor::writeDecl(Output& out, const string& name, const TypePtr& type)
+{
+ out << nl << typeToString(type) << ' ' << name;
+
+ BuiltinPtr builtin = BuiltinPtr::dynamicCast(type);
+ if(builtin)
+ {
+ switch(builtin->kind())
+ {
+ case Builtin::KindBool:
+ {
+ out << " = false";
+ break;
+ }
+ case Builtin::KindByte:
+ case Builtin::KindShort:
+ case Builtin::KindInt:
+ case Builtin::KindLong:
+ {
+ out << " = 0";
+ break;
+ }
+ case Builtin::KindFloat:
+ case Builtin::KindDouble:
+ {
+ out << " = 0.0";
+ break;
+ }
+ case Builtin::KindString:
+ case Builtin::KindObject:
+ case Builtin::KindObjectProxy:
+ case Builtin::KindLocalObject:
+ {
+ break;
+ }
+ }
+ }
+
+ EnumPtr en = EnumPtr::dynamicCast(type);
+ if(en)
+ {
+ EnumeratorList enumerators = en->getEnumerators();
+ out << " = " << fixKwd(en->scope()) << fixKwd(enumerators.front()->name());
+ }
+
+ out << ';';
+}
+
+void
+Slice::Gen::ImplVisitor::writeReturn(Output& out, const TypePtr& type)
+{
+ BuiltinPtr builtin = BuiltinPtr::dynamicCast(type);
+ if(builtin)
+ {
+ switch(builtin->kind())
+ {
+ case Builtin::KindBool:
+ {
+ out << nl << "return false;";
+ break;
+ }
+ case Builtin::KindByte:
+ case Builtin::KindShort:
+ case Builtin::KindInt:
+ case Builtin::KindLong:
+ {
+ out << nl << "return 0;";
+ break;
+ }
+ case Builtin::KindFloat:
+ case Builtin::KindDouble:
+ {
+ out << nl << "return 0.0;";
+ break;
+ }
+ case Builtin::KindString:
+ {
+ out << nl << "return ::std::string();";
+ break;
+ }
+ case Builtin::KindObject:
+ case Builtin::KindObjectProxy:
+ case Builtin::KindLocalObject:
+ {
+ out << nl << "return 0;";
+ break;
+ }
+ }
+ }
+ else
+ {
+ ProxyPtr prx = ProxyPtr::dynamicCast(type);
+ if(prx)
+ {
+ out << nl << "return 0;";
+ }
+ else
+ {
+ ClassDeclPtr cl = ClassDeclPtr::dynamicCast(type);
+ if(cl)
+ {
+ out << nl << "return 0;";
+ }
+ else
+ {
+ StructPtr st = StructPtr::dynamicCast(type);
+ if(st)
+ {
+ out << nl << "return " << fixKwd(st->scoped()) << "();";
+ }
+ else
+ {
+ EnumPtr en = EnumPtr::dynamicCast(type);
+ if(en)
+ {
+ EnumeratorList enumerators = en->getEnumerators();
+ out << nl << "return " << fixKwd(en->scope()) << fixKwd(enumerators.front()->name()) << ';';
+ }
+ else
+ {
+ SequencePtr seq = SequencePtr::dynamicCast(type);
+ if(seq)
+ {
+ out << nl << "return " << fixKwd(seq->scoped()) << "();";
+ }
+ else
+ {
+ DictionaryPtr dict = DictionaryPtr::dynamicCast(type);
+ assert(dict);
+ out << nl << "return " << fixKwd(dict->scoped()) << "();";
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+bool
+Slice::Gen::ImplVisitor::visitModuleStart(const ModulePtr& p)
+{
+ if(!p->hasClassDefs())
+ {
+ return false;
+ }
+
+ string name = fixKwd(p->name());
+
+ H << sp << nl << "namespace " << name << nl << '{';
+
+ return true;
+}
+
+void
+Slice::Gen::ImplVisitor::visitModuleEnd(const ModulePtr& p)
+{
+ H << sp;
+ H << nl << '}';
+}
+
+bool
+Slice::Gen::ImplVisitor::visitClassDefStart(const ClassDefPtr& p)
+{
+ if(!p->isAbstract())
+ {
+ return false;
+ }
+
+ string name = p->name();
+ string scope = fixKwd(p->scope());
+ string cls = scope.substr(2) + name + "I";
+ string classScopedAMD = scope + "AMD_" + name;
+
+ ClassList bases = p->bases();
+ ClassDefPtr base;
+ if(!bases.empty() && !bases.front()->isInterface())
+ {
+ base = bases.front();
+ }
+
+ H << sp;
+ H << nl << "class " << name << "I : ";
+ H.useCurrentPosAsIndent();
+ H << "virtual public " << fixKwd(name);
+ for(ClassList::const_iterator q = bases.begin(); q != bases.end(); ++q)
+ {
+ H << ',' << nl << "virtual public " << fixKwd((*q)->scope());
+ if((*q)->isAbstract())
+ {
+ H << (*q)->name() << "I";
+ }
+ else
+ {
+ H << fixKwd((*q)->name());
+ }
+ }
+ H.restoreIndent();
+
+ H << sb;
+ H.dec();
+ H << nl << "public:";
+ H.inc();
+
+ OperationList ops = p->operations();
+ OperationList::const_iterator r;
+
+ for(r = ops.begin(); r != ops.end(); ++r)
+ {
+ OperationPtr op = (*r);
+ string opName = op->name();
+
+ TypePtr ret = op->returnType();
+ string retS = returnTypeToString(ret);
+
+ if(!p->isLocal() && (p->hasMetaData("amd") || op->hasMetaData("amd")))
+ {
+ H << sp << nl << "virtual void " << opName << "_async(";
+ H.useCurrentPosAsIndent();
+ H << "const " << classScopedAMD << '_' << opName << "Ptr&";
+ ParamDeclList paramList = op->parameters();
+ ParamDeclList::const_iterator q;
+ for(q = paramList.begin(); q != paramList.end(); ++q)
+ {
+ if(!(*q)->isOutParam())
+ {
+ H << ',' << nl << inputTypeToString((*q)->type());
+ }
+ }
+ H << ',' << nl << "const Ice::Current&";
+ H.restoreIndent();
+
+ bool nonmutating = op->mode() == Operation::Nonmutating;
+
+ H << ")" << (nonmutating ? " const" : "") << ';';
+
+ C << sp << nl << "void" << nl << scope << name << "I::" << opName << "_async(";
+ C.useCurrentPosAsIndent();
+ C << "const " << classScopedAMD << '_' << opName << "Ptr& " << opName << "CB";
+ for(q = paramList.begin(); q != paramList.end(); ++q)
+ {
+ if(!(*q)->isOutParam())
+ {
+ C << ',' << nl << inputTypeToString((*q)->type()) << ' ' << fixKwd((*q)->name());
+ }
+ }
+ C << ',' << nl << "const Ice::Current& current";
+ C.restoreIndent();
+ C << ")" << (nonmutating ? " const" : "");
+ C << sb;
+
+ string result = "r";
+ for(q = paramList.begin(); q != paramList.end(); ++q)
+ {
+ if((*q)->name() == result)
+ {
+ result = "_" + result;
+ break;
+ }
+ }
+ if(ret)
+ {
+ writeDecl(C, result, ret);
+ }
+ for(q = paramList.begin(); q != paramList.end(); ++q)
+ {
+ if((*q)->isOutParam())
+ {
+ writeDecl(C, fixKwd((*q)->name()), (*q)->type());
+ }
+ }
+
+ C << nl << opName << "CB->ice_response(";
+ if(ret)
+ {
+ C << result;
+ }
+ for(q = paramList.begin(); q != paramList.end(); ++q)
+ {
+ if((*q)->isOutParam())
+ {
+ if(ret || q != paramList.begin())
+ {
+ C << ", ";
+ }
+ C << fixKwd((*q)->name());
+ }
+ }
+ C << ");";
+
+ C << eb;
+ }
+ else
+ {
+ H << sp << nl << "virtual " << retS << ' ' << fixKwd(opName) << '(';
+ H.useCurrentPosAsIndent();
+ ParamDeclList paramList = op->parameters();
+ ParamDeclList::const_iterator q;
+ for(q = paramList.begin(); q != paramList.end(); ++q)
+ {
+ if(q != paramList.begin())
+ {
+ H << ',' << nl;
+ }
+#if defined(__SUNPRO_CC) && (__SUNPRO_CC==0x550)
+ //
+ // Work around for Sun CC 5.5 bug #4853566
+ //
+ string typeString;
+ if((*q)->isOutParam())
+ {
+ typeString = outputTypeToString((*q)->type());
+ }
+ else
+ {
+ typeString = inputTypeToString((*q)->type());
+ }
+#else
+ string typeString = (*q)->isOutParam() ?
+ outputTypeToString((*q)->type()) : inputTypeToString((*q)->type());
+#endif
+ H << typeString;
+ }
+ if(!p->isLocal())
+ {
+ if(!paramList.empty())
+ {
+ H << ',' << nl;
+ }
+ H << "const Ice::Current&";
+ }
+ H.restoreIndent();
+
+ bool nonmutating = op->mode() == Operation::Nonmutating;
+
+ H << ")" << (nonmutating ? " const" : "") << ';';
+
+ C << sp << nl << retS << nl;
+ C << scope.substr(2) << name << "I::" << fixKwd(opName) << '(';
+ C.useCurrentPosAsIndent();
+ for(q = paramList.begin(); q != paramList.end(); ++q)
+ {
+ if(q != paramList.begin())
+ {
+ C << ',' << nl;
+ }
+#if defined(__SUNPRO_CC) && (__SUNPRO_CC==0x550)
+ //
+ // Work around for Sun CC 5.5 bug #4853566
+ //
+ string typeString;
+ if((*q)->isOutParam())
+ {
+ typeString = outputTypeToString((*q)->type());
+ }
+ else
+ {
+ typeString = inputTypeToString((*q)->type());
+ }
+#else
+ string typeString = (*q)->isOutParam() ?
+ outputTypeToString((*q)->type()) : inputTypeToString((*q)->type());
+#endif
+ C << typeString << ' ' << fixKwd((*q)->name());
+ }
+ if(!p->isLocal())
+ {
+ if(!paramList.empty())
+ {
+ C << ',' << nl;
+ }
+ C << "const Ice::Current& current";
+ }
+ C.restoreIndent();
+ C << ')';
+ C << (nonmutating ? " const" : "");
+ C << sb;
+
+ if(ret)
+ {
+ writeReturn(C, ret);
+ }
+
+ C << eb;
+ }
+ }
+
+ H << eb << ';';
+
+ return true;
+}
+
+Slice::Gen::AsyncVisitor::AsyncVisitor(Output& h, Output& c, const string& dllExport) :
+ H(h), C(c), _dllExport(dllExport)
+{
+}
+
+bool
+Slice::Gen::AsyncVisitor::visitModuleStart(const ModulePtr& p)
+{
+ if(!p->hasNonLocalClassDecls() || (!p->hasContentsWithMetaData("ami") && !p->hasContentsWithMetaData("amd")))
+ {
+ return false;
+ }
+
+ string name = fixKwd(p->name());
+
+ H << sp << nl << "namespace " << name << nl << '{';
+
+ return true;
+}
+
+void
+Slice::Gen::AsyncVisitor::visitModuleEnd(const ModulePtr& p)
+{
+ H << sp << nl << '}';
+}
+
+void
+Slice::Gen::AsyncVisitor::visitOperation(const OperationPtr& p)
+{
+ ContainerPtr container = p->container();
+ ClassDefPtr cl = ClassDefPtr::dynamicCast(container);
+
+ if(cl->isLocal() ||
+ (!cl->hasMetaData("ami") && !p->hasMetaData("ami") && !cl->hasMetaData("amd") && !p->hasMetaData("amd")))
+ {
+ return;
+ }
+
+ string name = p->name();
+
+ string className = cl->name();
+ string classNameAMI = "AMI_" + className;
+ string classNameAMD = "AMD_" + className;
+ string classScope = fixKwd(cl->scope());
+ string classScopedAMI = classScope + classNameAMI;
+ string classScopedAMD = classScope + classNameAMD;
+ string proxyName = classScope + className + "Prx";
+
+ vector<string> params;
+ vector<string> paramsDecl;
+ vector<string> args;
+
+ vector<string> paramsInvoke;
+ vector<string> paramsDeclInvoke;
+
+ paramsInvoke.push_back("const " + proxyName + "&");
+ paramsDeclInvoke.push_back("const " + proxyName + "& __prx");
+
+ TypePtr ret = p->returnType();
+ string retS = inputTypeToString(ret);
+
+ if(ret)
+ {
+ params.push_back(retS);
+ paramsDecl.push_back(retS + " __ret");
+ args.push_back("__ret");
+ }
+
+ TypeStringList inParams;
+ TypeStringList outParams;
+ ParamDeclList paramList = p->parameters();
+ for(ParamDeclList::const_iterator q = paramList.begin(); q != paramList.end(); ++q)
+ {
+ string paramName = fixKwd((*q)->name());
+ TypePtr type = (*q)->type();
+ string typeString = inputTypeToString(type);
+
+ if((*q)->isOutParam())
+ {
+ params.push_back(typeString);
+ paramsDecl.push_back(typeString + ' ' + paramName);
+ args.push_back(paramName);
+
+ outParams.push_back(make_pair(type, paramName));
+ }
+ else
+ {
+ paramsInvoke.push_back(typeString);
+ paramsDeclInvoke.push_back(typeString + ' ' + paramName);
+
+ inParams.push_back(make_pair(type, paramName));
+ }
+ }
+
+ paramsInvoke.push_back("const ::Ice::Context&");
+ paramsDeclInvoke.push_back("const ::Ice::Context& __ctx");
+
+ if(cl->hasMetaData("ami") || p->hasMetaData("ami"))
+ {
+ H << sp << nl << "class " << _dllExport << classNameAMI << '_' << name
+ << " : public ::IceInternal::OutgoingAsync";
+ 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 << "void __invoke" << spar << paramsInvoke << epar << ';';
+ H << sp;
+ H.dec();
+ H << nl << "protected:";
+ H.inc();
+ H << sp;
+ H << nl << "virtual void __response(bool);";
+ H << eb << ';';
+ H << sp << nl << "typedef ::IceUtil::Handle< " << classScopedAMI << '_' << name << "> " << classNameAMI
+ << '_' << name << "Ptr;";
+
+ C << sp << nl << "void" << nl << classScopedAMI.substr(2) << '_' << name << "::__invoke" << spar
+ << paramsDeclInvoke << epar;
+ C << sb;
+ C << nl << "try";
+ C << sb;
+ C << nl << "static const ::std::string __operation(\"" << name << "\");";
+ C << nl << "__prepare(__prx, __operation, static_cast< ::Ice::OperationMode>(" << p->mode() << "), __ctx);";
+ writeMarshalCode(C, inParams, 0);
+ if(p->sendsClasses())
+ {
+ C << nl << "__os->writePendingObjects();";
+ }
+ C << nl << "__os->endWriteEncaps();";
+ C << eb;
+ C << nl << "catch(const ::Ice::LocalException& __ex)";
+ C << sb;
+ C << nl << "__finished(__ex);";
+ C << nl << "return;";
+ C << eb;
+ C << nl << "__send();";
+ C << eb;
+
+ C << sp << nl << "void" << nl << classScopedAMI.substr(2) << '_' << name << "::__response(bool __ok)";
+ C << sb;
+ writeAllocateCode(C, outParams, ret);
+ C << nl << "try";
+ C << sb;
+ C << nl << "if(!__ok)";
+ C << sb;
+ C << nl << "__is->throwException();";
+ C << eb;
+ writeUnmarshalCode(C, outParams, ret);
+ if(p->returnsClasses())
+ {
+ C << nl << "__is->readPendingObjects();";
+ }
+ C << eb;
+ C << nl << "catch(const ::Ice::LocalException& __ex)";
+ C << sb;
+ C << nl << "__finished(__ex);";
+ C << nl << "return;";
+ 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 << "ice_exception(__ex);";
+ C << nl << "return;";
+ C << eb;
+ }
+ C << nl << "catch(const ::Ice::UserException&)";
+ C << sb;
+ C << nl << "ice_exception(::Ice::UnknownUserException(__FILE__, __LINE__));";
+ C << nl << "return;";
+ C << eb;
+ C << nl << "ice_response" << spar << args << epar << ';';
+ C << eb;
+ }
+
+ if(cl->hasMetaData("amd") || p->hasMetaData("amd"))
+ {
+ H << sp << nl << "class " << _dllExport << classNameAMD << '_' << name
+ << " : virtual public ::IceUtil::Shared";
+ 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 << nl << "virtual void ice_exception(const ::std::exception&) = 0;";
+ H << nl << "virtual void ice_exception() = 0;";
+ H << eb << ';';
+ H << sp << nl << "typedef ::IceUtil::Handle< " << classScopedAMD << '_' << name << "> "
+ << classNameAMD << '_' << name << "Ptr;";
+ }
+}
+
+Slice::Gen::AsyncImplVisitor::AsyncImplVisitor(Output& h, Output& c, const string& dllExport) :
+ H(h), C(c), _dllExport(dllExport)
+{
+}
+
+bool
+Slice::Gen::AsyncImplVisitor::visitUnitStart(const UnitPtr& p)
+{
+ if(!p->hasNonLocalClassDecls() || !p->hasContentsWithMetaData("amd"))
+ {
+ return false;
+ }
+
+ H << sp << nl << "namespace IceAsync" << nl << '{';
+
+ return true;
+}
+
+void
+Slice::Gen::AsyncImplVisitor::visitUnitEnd(const UnitPtr& p)
+{
+ H << sp << nl << '}';
+}
+
+bool
+Slice::Gen::AsyncImplVisitor::visitModuleStart(const ModulePtr& p)
+{
+ if(!p->hasNonLocalClassDecls() || !p->hasContentsWithMetaData("amd"))
+ {
+ return false;
+ }
+
+ string name = fixKwd(p->name());
+
+ H << sp << nl << "namespace " << name << nl << '{';
+
+ return true;
+}
+
+void
+Slice::Gen::AsyncImplVisitor::visitModuleEnd(const ModulePtr& p)
+{
+ H << sp << nl << '}';
+}
+
+void
+Slice::Gen::AsyncImplVisitor::visitOperation(const OperationPtr& p)
+{
+ ContainerPtr container = p->container();
+ ClassDefPtr cl = ClassDefPtr::dynamicCast(container);
+
+ if(cl->isLocal() || (!cl->hasMetaData("amd") && !p->hasMetaData("amd")))
+ {
+ return;
+ }
+
+ string name = p->name();
+
+ string classNameAMD = "AMD_" + cl->name();
+ string classScope = fixKwd(cl->scope());
+ string classScopedAMD = classScope + classNameAMD;
+
+ string params;
+ string paramsDecl;
+ string args;
+
+ ExceptionList throws = p->throws();
+ throws.sort();
+ throws.unique();
+
+ //
+ // Arrange exceptions into most-derived to least-derived order. If we don't
+ // do this, a base exception handler can appear before a derived exception
+ // handler, causing compiler warnings and resulting in the base exception
+ // being marshaled instead of the derived exception.
+ //
+#if defined(__SUNPRO_CC)
+ throws.sort(derivedToBaseCompare);
+#else
+ throws.sort(Slice::DerivedToBaseCompare());
+#endif
+
+ TypePtr ret = p->returnType();
+ string retS = inputTypeToString(ret);
+
+ if(ret)
+ {
+ params += retS;
+ paramsDecl += retS;
+ paramsDecl += ' ';
+ paramsDecl += "__ret";
+ args += "__ret";
+ }
+
+ TypeStringList outParams;
+ ParamDeclList paramList = p->parameters();
+ for(ParamDeclList::const_iterator q = paramList.begin(); q != paramList.end(); ++q)
+ {
+ if((*q)->isOutParam())
+ {
+ string paramName = fixKwd((*q)->name());
+ TypePtr type = (*q)->type();
+ string typeString = inputTypeToString(type);
+
+ if(ret || !outParams.empty())
+ {
+ params += ", ";
+ paramsDecl += ", ";
+ args += ", ";
+ }
+
+ params += typeString;
+ paramsDecl += typeString;
+ paramsDecl += ' ';
+ paramsDecl += paramName;
+ args += paramName;
+
+ outParams.push_back(make_pair(type, paramName));
+ }
+ }
+
+ H << sp << nl << "class " << _dllExport << classNameAMD << '_' << name
+ << " : public " << classScopedAMD << '_' << name << ", public ::IceInternal::IncomingAsync";
+ H << sb;
+ H.dec();
+ H << nl << "public:";
+ H.inc();
+
+ H << sp;
+ H << nl << classNameAMD << '_' << name << "(::IceInternal::Incoming&);";
+
+ H << sp;
+ H << nl << "virtual void ice_response(" << params << ");";
+ H << nl << "virtual void ice_exception(const ::Ice::Exception&);";
+ H << nl << "virtual void ice_exception(const ::std::exception&);";
+ H << nl << "virtual void ice_exception();";
+ H << eb << ';';
+
+ C << sp << nl << "IceAsync" << classScopedAMD << '_' << name << "::" << classNameAMD << '_' << name
+ << "(::IceInternal::Incoming& in) :";
+ C.inc();
+ C << nl << "IncomingAsync(in)";
+ C.dec();
+ C << sb;
+ C << eb;
+
+ C << sp << nl << "void" << nl << "IceAsync" << classScopedAMD << '_' << name << "::ice_response("
+ << paramsDecl << ')';
+ C << sb;
+ if(ret || !outParams.empty())
+ {
+ C << nl << "try";
+ C << sb;
+ C << nl << "::IceInternal::BasicStream* __os = this->__os();";
+ writeMarshalCode(C, outParams, ret);
+ if(p->returnsClasses())
+ {
+ C << nl << "__os->writePendingObjects();";
+ }
+ C << eb;
+ C << nl << "catch(const ::Ice::Exception& __ex)";
+ C << sb;
+ C << nl << "__exception(__ex);";
+ C << nl << "return;";
+ C << eb;
+ }
+ C << nl << "__response(true);";
+ C << eb;
+
+ C << sp << nl << "void" << nl << "IceAsync" << classScopedAMD << '_' << name
+ << "::ice_exception(const ::Ice::Exception& ex)";
+ C << sb;
+ if(throws.empty())
+ {
+ C << nl << "__exception(ex);";
+ }
+ else
+ {
+ C << nl << "try";
+ C << sb;
+ C << nl << "ex.ice_throw();";
+ C << eb;
+ ExceptionList::const_iterator r;
+ for(r = throws.begin(); r != throws.end(); ++r)
+ {
+ C << nl << "catch(const " << fixKwd((*r)->scoped()) << "& __ex)";
+ C << sb;
+ C << nl << "__os()->write(__ex);";
+ if((*r)->usesClasses())
+ {
+ C << nl << "__os()->writePendingObjects();";
+ }
+ C << nl << "__response(false);";
+ C << eb;
+ }
+ C << nl << "catch(const ::Ice::Exception& __ex)";
+ C << sb;
+ C << nl << "__exception(__ex);";
+ C << eb;
+ }
+ C << eb;
+
+ C << sp << nl << "void" << nl << "IceAsync" << classScopedAMD << '_' << name
+ << "::ice_exception(const ::std::exception& ex)";
+ C << sb;
+ C << nl << "__exception(ex);";
+ C << eb;
+
+ C << sp << nl << "void" << nl << "IceAsync" << classScopedAMD << '_' << name
+ << "::ice_exception()";
+ C << sb;
+ C << nl << "__exception();";
+ C << eb;
+}
+
+void
+Slice::Gen::validateMetaData(const UnitPtr& unit)
+{
+ MetaDataVisitor visitor;
+ unit->visit(&visitor, false);
+}
+
+bool
+Slice::Gen::MetaDataVisitor::visitModuleStart(const ModulePtr& p)
+{
+ validate(p);
+ return true;
+}
+
+void
+Slice::Gen::MetaDataVisitor::visitModuleEnd(const ModulePtr&)
+{
+}
+
+void
+Slice::Gen::MetaDataVisitor::visitClassDecl(const ClassDeclPtr& p)
+{
+ validate(p);
+}
+
+bool
+Slice::Gen::MetaDataVisitor::visitClassDefStart(const ClassDefPtr& p)
+{
+ validate(p);
+ return true;
+}
+
+void
+Slice::Gen::MetaDataVisitor::visitClassDefEnd(const ClassDefPtr&)
+{
+}
+
+bool
+Slice::Gen::MetaDataVisitor::visitExceptionStart(const ExceptionPtr& p)
+{
+ validate(p);
+ return true;
+}
+
+void
+Slice::Gen::MetaDataVisitor::visitExceptionEnd(const ExceptionPtr&)
+{
+}
+
+bool
+Slice::Gen::MetaDataVisitor::visitStructStart(const StructPtr& p)
+{
+ validate(p);
+ return true;
+}
+
+void
+Slice::Gen::MetaDataVisitor::visitStructEnd(const StructPtr&)
+{
+}
+
+void
+Slice::Gen::MetaDataVisitor::visitOperation(const OperationPtr& p)
+{
+ validate(p);
+}
+
+void
+Slice::Gen::MetaDataVisitor::visitParamDecl(const ParamDeclPtr& p)
+{
+ validate(p);
+}
+
+void
+Slice::Gen::MetaDataVisitor::visitDataMember(const DataMemberPtr& p)
+{
+ validate(p);
+}
+
+void
+Slice::Gen::MetaDataVisitor::visitSequence(const SequencePtr& p)
+{
+ validate(p);
+}
+
+void
+Slice::Gen::MetaDataVisitor::visitDictionary(const DictionaryPtr& p)
+{
+ validate(p);
+}
+
+void
+Slice::Gen::MetaDataVisitor::visitEnum(const EnumPtr& p)
+{
+ validate(p);
+}
+
+void
+Slice::Gen::MetaDataVisitor::visitConst(const ConstPtr& p)
+{
+ validate(p);
+}
+
+void
+Slice::Gen::MetaDataVisitor::validate(const ContainedPtr& cont)
+{
+ DefinitionContextPtr dc = cont->definitionContext();
+ assert(dc);
+ StringList globalMetaData = dc->getMetaData();
+ string file = dc->filename();
+
+ StringList localMetaData = cont->getMetaData();
+
+ StringList::const_iterator p;
+ static const string prefix = "cpp:";
+
+ for(p = globalMetaData.begin(); p != globalMetaData.end(); ++p)
+ {
+ string s = *p;
+ if(_history.count(s) == 0)
+ {
+ if(s.find(prefix) == 0)
+ {
+ cout << file << ": warning: ignoring invalid global metadata `" << s << "'" << endl;
+ }
+ _history.insert(s);
+ }
+ }
+
+ for(p = localMetaData.begin(); p != localMetaData.end(); ++p)
+ {
+ string s = *p;
+ if(_history.count(s) == 0)
+ {
+ if(s.find(prefix) == 0)
+ {
+ if(SequencePtr::dynamicCast(cont))
+ {
+ if(s.substr(prefix.size()) == "collection")
+ {
+ continue;
+ }
+ }
+ if(StructPtr::dynamicCast(cont))
+ {
+ if(s.substr(prefix.size()) == "class")
+ {
+ continue;
+ }
+ }
+ cout << file << ": warning: ignoring invalid metadata `" << s << "'" << endl;
+ }
+ _history.insert(s);
+ }
+ }
+}
diff --git a/cpp/src/slice2cppe/Gen.h b/cpp/src/slice2cppe/Gen.h
new file mode 100644
index 00000000000..f32715b3fb1
--- /dev/null
+++ b/cpp/src/slice2cppe/Gen.h
@@ -0,0 +1,383 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2005 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#ifndef GEN_H
+#define GEN_H
+
+#include <Slice/Parser.h>
+#include <IceUtil/OutputUtil.h>
+
+namespace Slice
+{
+
+class Gen : public ::IceUtil::noncopyable
+{
+public:
+
+ Gen(const std::string&,
+ const std::string&,
+ const std::string&,
+ const std::string&,
+ const std::string&,
+ const std::vector<std::string>&,
+ const std::string&,
+ const std::string&,
+ bool,
+ bool,
+ bool);
+ ~Gen();
+
+ bool operator!() const; // Returns true if there was a constructor error
+
+ void generate(const UnitPtr&);
+
+private:
+
+ ::IceUtil::Output H;
+ ::IceUtil::Output C;
+
+ ::IceUtil::Output implH;
+ ::IceUtil::Output implC;
+
+ std::string _base;
+ std::string _headerExtension;
+ std::string _sourceExtension;
+ std::string _include;
+ std::vector<std::string> _includePaths;
+ std::string _dllExport;
+ bool _impl;
+ bool _checksum;
+ bool _stream;
+
+ class TypesVisitor : public ::IceUtil::noncopyable, public ParserVisitor
+ {
+ public:
+
+ TypesVisitor(::IceUtil::Output&, ::IceUtil::Output&, const std::string&, bool);
+
+ virtual bool visitModuleStart(const ModulePtr&);
+ virtual void visitModuleEnd(const ModulePtr&);
+ virtual bool visitClassDefStart(const ClassDefPtr&);
+ virtual bool visitExceptionStart(const ExceptionPtr&);
+ virtual void visitExceptionEnd(const ExceptionPtr&);
+ virtual bool visitStructStart(const StructPtr&);
+ virtual void visitStructEnd(const StructPtr&);
+ virtual void visitSequence(const SequencePtr&);
+ virtual void visitDictionary(const DictionaryPtr&);
+ virtual void visitEnum(const EnumPtr&);
+ virtual void visitConst(const ConstPtr&);
+ virtual void visitDataMember(const DataMemberPtr&);
+
+ private:
+
+ void emitExceptionBase(const ExceptionPtr&, const std::string&);
+
+ ::IceUtil::Output& H;
+ ::IceUtil::Output& C;
+
+ std::string _dllExport;
+ bool _stream;
+ };
+
+ class ProxyDeclVisitor : public ::IceUtil::noncopyable, public ParserVisitor
+ {
+ public:
+
+ ProxyDeclVisitor(::IceUtil::Output&, ::IceUtil::Output&, const std::string&);
+
+ virtual bool visitUnitStart(const UnitPtr&);
+ virtual void visitUnitEnd(const UnitPtr&);
+ virtual bool visitModuleStart(const ModulePtr&);
+ virtual void visitModuleEnd(const ModulePtr&);
+ virtual void visitClassDecl(const ClassDeclPtr&);
+
+ private:
+
+ ::IceUtil::Output& H;
+ ::IceUtil::Output& C;
+
+ std::string _dllExport;
+ };
+
+ class ProxyVisitor : public ::IceUtil::noncopyable, public ParserVisitor
+ {
+ public:
+
+ ProxyVisitor(::IceUtil::Output&, ::IceUtil::Output&, const std::string&);
+
+ virtual bool visitUnitStart(const UnitPtr&);
+ virtual void visitUnitEnd(const UnitPtr&);
+ virtual bool visitModuleStart(const ModulePtr&);
+ virtual void visitModuleEnd(const ModulePtr&);
+ virtual bool visitClassDefStart(const ClassDefPtr&);
+ virtual void visitClassDefEnd(const ClassDefPtr&);
+ virtual void visitOperation(const OperationPtr&);
+
+ private:
+
+ ::IceUtil::Output& H;
+ ::IceUtil::Output& C;
+
+ std::string _dllExport;
+ };
+
+ class DelegateVisitor : public ::IceUtil::noncopyable, public ParserVisitor
+ {
+ public:
+
+ DelegateVisitor(::IceUtil::Output&, ::IceUtil::Output&, const std::string&);
+
+ virtual bool visitUnitStart(const UnitPtr&);
+ virtual void visitUnitEnd(const UnitPtr&);
+ virtual bool visitModuleStart(const ModulePtr&);
+ virtual void visitModuleEnd(const ModulePtr&);
+ virtual bool visitClassDefStart(const ClassDefPtr&);
+ virtual void visitClassDefEnd(const ClassDefPtr&);
+ virtual void visitOperation(const OperationPtr&);
+
+ private:
+
+ ::IceUtil::Output& H;
+ ::IceUtil::Output& C;
+
+ std::string _dllExport;
+ };
+
+ class DelegateMVisitor : public ::IceUtil::noncopyable, public ParserVisitor
+ {
+ public:
+
+ DelegateMVisitor(::IceUtil::Output&, ::IceUtil::Output&, const std::string&);
+
+ virtual bool visitUnitStart(const UnitPtr&);
+ virtual void visitUnitEnd(const UnitPtr&);
+ virtual bool visitModuleStart(const ModulePtr&);
+ virtual void visitModuleEnd(const ModulePtr&);
+ virtual bool visitClassDefStart(const ClassDefPtr&);
+ virtual void visitClassDefEnd(const ClassDefPtr&);
+ virtual void visitOperation(const OperationPtr&);
+
+ private:
+
+ ::IceUtil::Output& H;
+ ::IceUtil::Output& C;
+
+ std::string _dllExport;
+ };
+
+ class DelegateDVisitor : public ::IceUtil::noncopyable, public ParserVisitor
+ {
+ public:
+
+ DelegateDVisitor(::IceUtil::Output&, ::IceUtil::Output&, const std::string&);
+
+ virtual bool visitUnitStart(const UnitPtr&);
+ virtual void visitUnitEnd(const UnitPtr&);
+ virtual bool visitModuleStart(const ModulePtr&);
+ virtual void visitModuleEnd(const ModulePtr&);
+ virtual bool visitClassDefStart(const ClassDefPtr&);
+ virtual void visitClassDefEnd(const ClassDefPtr&);
+ virtual void visitOperation(const OperationPtr&);
+
+ private:
+
+ ::IceUtil::Output& H;
+ ::IceUtil::Output& C;
+
+ std::string _dllExport;
+ };
+
+ class ObjectDeclVisitor : public ::IceUtil::noncopyable, public ParserVisitor
+ {
+ public:
+
+ ObjectDeclVisitor(::IceUtil::Output&, ::IceUtil::Output&, const std::string&);
+
+ virtual bool visitModuleStart(const ModulePtr&);
+ virtual void visitModuleEnd(const ModulePtr&);
+ virtual void visitClassDecl(const ClassDeclPtr&);
+
+ private:
+
+ ::IceUtil::Output& H;
+ ::IceUtil::Output& C;
+
+ std::string _dllExport;
+ };
+
+ class ObjectVisitor : public ::IceUtil::noncopyable, public ParserVisitor
+ {
+ public:
+
+ ObjectVisitor(::IceUtil::Output&, ::IceUtil::Output&, const std::string&, bool);
+
+ virtual bool visitModuleStart(const ModulePtr&);
+ virtual void visitModuleEnd(const ModulePtr&);
+ virtual bool visitClassDefStart(const ClassDefPtr&);
+ virtual void visitClassDefEnd(const ClassDefPtr&);
+ virtual bool visitExceptionStart(const ExceptionPtr&);
+ virtual bool visitStructStart(const StructPtr&);
+ virtual void visitOperation(const OperationPtr&);
+ virtual void visitDataMember(const DataMemberPtr&);
+
+ private:
+
+ void emitGCFunctions(const ClassDefPtr&);
+ void emitGCInsertCode(const TypePtr&, const std::string&, const std::string&, int);
+ void emitGCClearCode(const TypePtr&, const std::string&, const std::string&, int);
+
+ ::IceUtil::Output& H;
+ ::IceUtil::Output& C;
+
+ std::string _dllExport;
+ bool _stream;
+ };
+
+ class IceInternalVisitor : public ::IceUtil::noncopyable, public ParserVisitor
+ {
+ public:
+
+ IceInternalVisitor(::IceUtil::Output&, ::IceUtil::Output&, const std::string&);
+
+ virtual bool visitUnitStart(const UnitPtr&);
+ virtual void visitUnitEnd(const UnitPtr&);
+ virtual void visitClassDecl(const ClassDeclPtr&);
+ virtual bool visitClassDefStart(const ClassDefPtr&);
+
+ private:
+
+ ::IceUtil::Output& H;
+ ::IceUtil::Output& C;
+
+ std::string _dllExport;
+ };
+
+ class HandleVisitor : public ::IceUtil::noncopyable, public ParserVisitor
+ {
+ public:
+
+ HandleVisitor(::IceUtil::Output&, ::IceUtil::Output&, const std::string&, bool);
+
+ virtual bool visitModuleStart(const ModulePtr&);
+ virtual void visitModuleEnd(const ModulePtr&);
+ virtual void visitClassDecl(const ClassDeclPtr&);
+ virtual bool visitClassDefStart(const ClassDefPtr&);
+
+ private:
+
+ ::IceUtil::Output& H;
+ ::IceUtil::Output& C;
+
+ std::string _dllExport;
+ bool _stream;
+ };
+
+ class ImplVisitor : public ::IceUtil::noncopyable, public ParserVisitor
+ {
+ public:
+
+ ImplVisitor(::IceUtil::Output&, ::IceUtil::Output&, const std::string&);
+
+ virtual bool visitModuleStart(const ModulePtr&);
+ virtual void visitModuleEnd(const ModulePtr&);
+ virtual bool visitClassDefStart(const ClassDefPtr&);
+
+ private:
+
+ ::IceUtil::Output& H;
+ ::IceUtil::Output& C;
+
+ std::string _dllExport;
+
+ //
+ // Generate code to emit a local variable declaration and initialize it
+ // if necessary.
+ //
+ void writeDecl(::IceUtil::Output&, const std::string&, const TypePtr&);
+
+ //
+ // Generate code to return a dummy value
+ //
+ void writeReturn(::IceUtil::Output&, const TypePtr&);
+ };
+
+ class AsyncVisitor : public ::IceUtil::noncopyable, public ParserVisitor
+ {
+ public:
+
+ AsyncVisitor(::IceUtil::Output&, ::IceUtil::Output&, const std::string&);
+
+ virtual bool visitModuleStart(const ModulePtr&);
+ virtual void visitModuleEnd(const ModulePtr&);
+ virtual void visitOperation(const OperationPtr&);
+
+ private:
+
+ ::IceUtil::Output& H;
+ ::IceUtil::Output& C;
+
+ std::string _dllExport;
+ };
+
+ class AsyncImplVisitor : public ::IceUtil::noncopyable, public ParserVisitor
+ {
+ public:
+
+ AsyncImplVisitor(::IceUtil::Output&, ::IceUtil::Output&, const std::string&);
+
+ virtual bool visitUnitStart(const UnitPtr&);
+ virtual void visitUnitEnd(const UnitPtr&);
+ virtual bool visitModuleStart(const ModulePtr&);
+ virtual void visitModuleEnd(const ModulePtr&);
+ virtual void visitOperation(const OperationPtr&);
+
+ private:
+
+ ::IceUtil::Output& H;
+ ::IceUtil::Output& C;
+
+ std::string _dllExport;
+ };
+
+private:
+
+ class MetaDataVisitor : public ParserVisitor
+ {
+ public:
+
+ virtual bool visitModuleStart(const ModulePtr&);
+ virtual void visitModuleEnd(const ModulePtr&);
+ virtual void visitClassDecl(const ClassDeclPtr&);
+ virtual bool visitClassDefStart(const ClassDefPtr&);
+ virtual void visitClassDefEnd(const ClassDefPtr&);
+ virtual bool visitExceptionStart(const ExceptionPtr&);
+ virtual void visitExceptionEnd(const ExceptionPtr&);
+ virtual bool visitStructStart(const StructPtr&);
+ virtual void visitStructEnd(const StructPtr&);
+ virtual void visitOperation(const OperationPtr&);
+ virtual void visitParamDecl(const ParamDeclPtr&);
+ virtual void visitDataMember(const DataMemberPtr&);
+ virtual void visitSequence(const SequencePtr&);
+ virtual void visitDictionary(const DictionaryPtr&);
+ virtual void visitEnum(const EnumPtr&);
+ virtual void visitConst(const ConstPtr&);
+
+ private:
+
+ void validate(const ContainedPtr&);
+
+ StringSet _history;
+ };
+
+ static void validateMetaData(const UnitPtr&);
+};
+
+}
+
+#endif
diff --git a/cpp/src/slice2cppe/Main.cpp b/cpp/src/slice2cppe/Main.cpp
new file mode 100644
index 00000000000..d60fc9032ef
--- /dev/null
+++ b/cpp/src/slice2cppe/Main.cpp
@@ -0,0 +1,205 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2005 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#include <IceUtil/Options.h>
+#include <Slice/Preprocessor.h>
+#include <Gen.h>
+
+using namespace std;
+using namespace Slice;
+
+void
+usage(const char* n)
+{
+ cerr << "Usage: " << n << " [options] slice-files...\n";
+ cerr <<
+ "Options:\n"
+ "-h, --help Show this message.\n"
+ "-v, --version Display the Ice version.\n"
+ "--header-ext EXT Use EXT instead of the default `h' extension.\n"
+ "--source-ext EXT Use EXT instead of the default `cpp' extension.\n"
+ "-DNAME Define NAME as 1.\n"
+ "-DNAME=DEF Define NAME as DEF.\n"
+ "-UNAME Remove any definition for NAME.\n"
+ "-IDIR Put DIR in the include file search path.\n"
+ "--include-dir DIR Use DIR as the header include directory in source files.\n"
+ "--output-dir DIR Create files in the directory DIR.\n"
+ "--dll-export SYMBOL Use SYMBOL for DLL exports.\n"
+ "--impl Generate sample implementations.\n"
+ "--depend Generate Makefile dependencies.\n"
+ "-d, --debug Print debug messages.\n"
+ "--ice Permit `Ice' prefix (for building Ice source code only)\n"
+ "--checksum Generate checksums for Slice definitions.\n"
+ "--stream Generate marshaling support for public stream API.\n"
+ ;
+ // Note: --case-sensitive is intentionally not shown here!
+}
+
+int
+main(int argc, char* argv[])
+{
+ string cppArgs;
+ vector<string> includePaths;
+ string include;
+ string output;
+ string dllExport;
+ bool impl;
+ bool depend;
+ bool debug;
+ bool ice;
+ bool checksum;
+ bool stream;
+ bool caseSensitive;
+
+ IceUtil::Options opts;
+ opts.addOpt("h", "help");
+ opts.addOpt("v", "version");
+ opts.addOpt("", "header-ext", IceUtil::Options::NeedArg, "h");
+ opts.addOpt("", "source-ext", IceUtil::Options::NeedArg, "cpp");
+ opts.addOpt("D", "", IceUtil::Options::NeedArg, "", IceUtil::Options::Repeat);
+ opts.addOpt("U", "", IceUtil::Options::NeedArg, "", IceUtil::Options::Repeat);
+ opts.addOpt("I", "", IceUtil::Options::NeedArg, "", IceUtil::Options::Repeat);
+ opts.addOpt("", "include-dir", IceUtil::Options::NeedArg);
+ opts.addOpt("", "output-dir", IceUtil::Options::NeedArg);
+ opts.addOpt("", "dll-export", IceUtil::Options::NeedArg);
+ opts.addOpt("", "impl");
+ opts.addOpt("", "depend");
+ opts.addOpt("d", "debug");
+ opts.addOpt("", "ice");
+ opts.addOpt("", "checksum");
+ opts.addOpt("", "stream");
+ opts.addOpt("", "case-sensitive");
+
+ vector<string> args;
+ try
+ {
+ args = opts.parse(argc, argv);
+ }
+ catch(const IceUtil::Options::BadOpt& e)
+ {
+ cerr << argv[0] << ": " << e.reason << endl;
+ usage(argv[0]);
+ return EXIT_FAILURE;
+ }
+
+ if(opts.isSet("h") || opts.isSet("help"))
+ {
+ usage(argv[0]);
+ return EXIT_SUCCESS;
+ }
+ if(opts.isSet("v") || opts.isSet("version"))
+ {
+ cout << ICE_STRING_VERSION << endl;
+ return EXIT_SUCCESS;
+ }
+
+ string headerExtension = opts.optArg("header-ext");
+ string sourceExtension = opts.optArg("source-ext");
+
+ if(opts.isSet("D"))
+ {
+ vector<string> optargs = opts.argVec("D");
+ for(vector<string>::const_iterator i = optargs.begin(); i != optargs.end(); ++i)
+ {
+ cppArgs += " -D" + *i;
+ }
+ }
+ if(opts.isSet("U"))
+ {
+ vector<string> optargs = opts.argVec("U");
+ for(vector<string>::const_iterator i = optargs.begin(); i != optargs.end(); ++i)
+ {
+ cppArgs += " -U" + *i;
+ }
+ }
+ if(opts.isSet("I"))
+ {
+ includePaths = opts.argVec("I");
+ for(vector<string>::const_iterator i = includePaths.begin(); i != includePaths.end(); ++i)
+ {
+ cppArgs += " -I" + *i;
+ }
+ }
+ if(opts.isSet("include-dir"))
+ {
+ include = opts.optArg("include-dir");
+ }
+ if(opts.isSet("output-dir"))
+ {
+ output = opts.optArg("output-dir");
+ }
+ if(opts.isSet("dll-export"))
+ {
+ dllExport = opts.optArg("dll-export");
+ }
+ impl = opts.isSet("impl");
+ depend = opts.isSet("depend");
+ debug = opts.isSet("d") || opts.isSet("debug");
+ ice = opts.isSet("ice");
+ checksum = opts.isSet("checksum");
+ stream = opts.isSet("stream");
+ caseSensitive = opts.isSet("case-sensitive");
+
+ if(args.empty())
+ {
+ cerr << argv[0] << ": no input file" << endl;
+ usage(argv[0]);
+ return EXIT_FAILURE;
+ }
+
+ int status = EXIT_SUCCESS;
+
+ for(vector<string>::const_iterator i = args.begin(); i != args.end(); ++i)
+ {
+ if(depend)
+ {
+ Preprocessor icecpp(argv[0], *i, cppArgs);
+ icecpp.printMakefileDependencies(Preprocessor::CPlusPlus);
+ }
+ else
+ {
+ Preprocessor icecpp(argv[0], *i, cppArgs);
+ FILE* cppHandle = icecpp.preprocess(false);
+
+ if(cppHandle == 0)
+ {
+ return EXIT_FAILURE;
+ }
+
+ UnitPtr u = Unit::createUnit(false, false, ice, caseSensitive);
+ int parseStatus = u->parse(cppHandle, debug, false);
+
+ if(!icecpp.close())
+ {
+ u->destroy();
+ return EXIT_FAILURE;
+ }
+
+ if(parseStatus == EXIT_FAILURE)
+ {
+ status = EXIT_FAILURE;
+ }
+ else
+ {
+ Gen gen(argv[0], icecpp.getBaseName(), headerExtension, sourceExtension, include,
+ includePaths, dllExport, output, impl, checksum, stream);
+ if(!gen)
+ {
+ u->destroy();
+ return EXIT_FAILURE;
+ }
+ gen.generate(u);
+ }
+
+ u->destroy();
+ }
+ }
+
+ return status;
+}
diff --git a/cpp/src/slice2cppe/Makefile b/cpp/src/slice2cppe/Makefile
new file mode 100644
index 00000000000..f21c48b538b
--- /dev/null
+++ b/cpp/src/slice2cppe/Makefile
@@ -0,0 +1,32 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2005 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice is licensed to you under the terms described in the
+# ICE_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+top_srcdir = ../..
+
+NAME = $(top_srcdir)/bin/slice2cppe
+
+TARGETS = $(NAME)
+
+OBJS = Gen.o \
+ Main.o
+
+SRCS = $(OBJS:.o=.cpp)
+
+include $(top_srcdir)/config/Make.rules
+
+CPPFLAGS := -I. $(CPPFLAGS)
+
+$(NAME): $(OBJS)
+ rm -f $@
+ $(CXX) $(LDFLAGS) -o $@ $(OBJS) -lSlice $(BASELIBS)
+
+install:: all
+ $(INSTALL_PROGRAM) $(NAME) $(install_bindir)
+
+include .depend
diff --git a/cpp/src/slice2cppe/slice2cppe.dsp b/cpp/src/slice2cppe/slice2cppe.dsp
new file mode 100644
index 00000000000..8e909c1b8b8
--- /dev/null
+++ b/cpp/src/slice2cppe/slice2cppe.dsp
@@ -0,0 +1,126 @@
+# Microsoft Developer Studio Project File - Name="slice2cppe" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=slice2cppe - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "slice2cppe.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "slice2cppe.mak" CFG="slice2cppe - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "slice2cppe - Win32 Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "slice2cppe - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "slice2cppe - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /MD /W3 /WX /GR /GX /O2 /I "." /I "../../include" /D "NDEBUG" /D "_CONSOLE" /FD /c
+# SUBTRACT CPP /Fr /YX
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 setargv.obj /nologo /subsystem:console /incremental:yes /machine:I386
+# SUBTRACT LINK32 /debug /nodefaultlib
+# Begin Special Build Tool
+OutDir=.\Release
+TargetName=slice2cppe
+SOURCE="$(InputPath)"
+PostBuild_Cmds=copy $(OutDir)\$(TargetName).exe ..\..\bin
+# End Special Build Tool
+
+!ELSEIF "$(CFG)" == "slice2cppe - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
+# ADD CPP /nologo /MDd /W3 /WX /Gm /GR /GX /Zi /Od /I "." /I "../../include" /D "_DEBUG" /D "_CONSOLE" /FD /GZ /c
+# SUBTRACT CPP /Fr /YX
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 setargv.obj /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# SUBTRACT LINK32 /incremental:no /nodefaultlib
+# Begin Special Build Tool
+OutDir=.\Debug
+TargetName=slice2cppe
+SOURCE="$(InputPath)"
+PostBuild_Cmds=copy $(OutDir)\$(TargetName).exe ..\..\bin
+# End Special Build Tool
+
+!ENDIF
+
+# Begin Target
+
+# Name "slice2cppe - Win32 Release"
+# Name "slice2cppe - Win32 Debug"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=.\Gen.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\Main.cpp
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# Begin Source File
+
+SOURCE=.\Gen.h
+# End Source File
+# End Group
+# Begin Group "Resource Files"
+
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+# End Group
+# End Target
+# End Project
diff --git a/cpp/src/slice2javae/.depend b/cpp/src/slice2javae/.depend
new file mode 100644
index 00000000000..f8bf3e4fd9f
--- /dev/null
+++ b/cpp/src/slice2javae/.depend
@@ -0,0 +1,2 @@
+Gen.o: Gen.cpp Gen.h ../../include/Slice/Parser.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/IceUtil/Handle.h ../../include/IceUtil/Exception.h ../../include/IceUtil/InputUtil.h ../../include/Slice/JavaUtil.h ../../include/IceUtil/OutputUtil.h ../../include/Slice/Checksum.h ../../include/IceUtil/Functional.h ../../include/IceUtil/Algorithm.h ../../include/IceUtil/Iterator.h
+Main.o: Main.cpp ../../include/IceUtil/Options.h ../../include/IceUtil/Config.h ../../include/IceUtil/RecMutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/Exception.h ../../include/Slice/Preprocessor.h Gen.h ../../include/Slice/Parser.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Handle.h ../../include/IceUtil/InputUtil.h ../../include/Slice/JavaUtil.h ../../include/IceUtil/OutputUtil.h ../../include/Slice/Checksum.h
diff --git a/cpp/src/slice2javae/Gen.cpp b/cpp/src/slice2javae/Gen.cpp
new file mode 100644
index 00000000000..e92cadc18cc
--- /dev/null
+++ b/cpp/src/slice2javae/Gen.cpp
@@ -0,0 +1,5008 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2005 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#include <Gen.h>
+#include <Slice/Checksum.h>
+#include <IceUtil/Functional.h>
+#include <IceUtil/Algorithm.h>
+#include <IceUtil/Iterator.h>
+
+#include <limits>
+
+using namespace std;
+using namespace Slice;
+
+//
+// Don't use "using namespace IceUtil", or stupid VC++ 6.0 complains
+// about ambigious symbols for constructs like
+// "IceUtil::constMemFun(&Slice::Exception::isLocal)".
+//
+using IceUtil::Output;
+using IceUtil::nl;
+using IceUtil::sp;
+using IceUtil::sb;
+using IceUtil::eb;
+using IceUtil::spar;
+using IceUtil::epar;
+
+static string
+sliceModeToIceMode(const OperationPtr& op)
+{
+ string mode;
+ switch(op->mode())
+ {
+ case Operation::Normal:
+ {
+ mode = "Ice.OperationMode.Normal";
+ break;
+ }
+ case Operation::Nonmutating:
+ {
+ mode = "Ice.OperationMode.Nonmutating";
+ break;
+ }
+ case Operation::Idempotent:
+ {
+ mode = "Ice.OperationMode.Idempotent";
+ break;
+ }
+ default:
+ {
+ assert(false);
+ break;
+ }
+ }
+ return mode;
+}
+
+Slice::JavaVisitor::JavaVisitor(const string& dir) :
+ JavaGenerator(dir)
+{
+}
+
+Slice::JavaVisitor::~JavaVisitor()
+{
+}
+
+vector<string>
+Slice::JavaVisitor::getParams(const OperationPtr& op, const string& package)
+{
+ vector<string> params;
+
+ ParamDeclList paramList = op->parameters();
+ for(ParamDeclList::const_iterator q = paramList.begin(); q != paramList.end(); ++q)
+ {
+ StringList metaData = (*q)->getMetaData();
+ string typeString = typeToString((*q)->type(), (*q)->isOutParam() ? TypeModeOut : TypeModeIn, package,
+ metaData);
+ params.push_back(typeString + ' ' + fixKwd((*q)->name()));
+ }
+
+ return params;
+}
+
+vector<string>
+Slice::JavaVisitor::getParamsAsync(const OperationPtr& op, const string& package, bool amd)
+{
+ vector<string> params;
+
+ string name = op->name();
+ ContainerPtr container = op->container();
+ ClassDefPtr cl = ClassDefPtr::dynamicCast(container);
+ string classNameAsync = getAbsolute(cl, package, amd ? "AMD_" : "AMI_", '_' + name);
+ params.push_back(classNameAsync + " __cb");
+
+ ParamDeclList paramList = op->parameters();
+ for(ParamDeclList::const_iterator q = paramList.begin(); q != paramList.end(); ++q)
+ {
+ if(!(*q)->isOutParam())
+ {
+ StringList metaData = (*q)->getMetaData();
+ string typeString = typeToString((*q)->type(), TypeModeIn, package, metaData);
+ params.push_back(typeString + ' ' + fixKwd((*q)->name()));
+ }
+ }
+
+ return params;
+}
+
+vector<string>
+Slice::JavaVisitor::getParamsAsyncCB(const OperationPtr& op, const string& package)
+{
+ vector<string> params;
+
+ TypePtr ret = op->returnType();
+ if(ret)
+ {
+ string retS = typeToString(ret, TypeModeIn, package, op->getMetaData());
+ params.push_back(retS + " __ret");
+ }
+
+ ParamDeclList paramList = op->parameters();
+ for(ParamDeclList::const_iterator q = paramList.begin(); q != paramList.end(); ++q)
+ {
+ if((*q)->isOutParam())
+ {
+ string typeString = typeToString((*q)->type(), TypeModeIn, package, (*q)->getMetaData());
+ params.push_back(typeString + ' ' + fixKwd((*q)->name()));
+ }
+ }
+
+ return params;
+}
+
+vector<string>
+Slice::JavaVisitor::getArgs(const OperationPtr& op)
+{
+ vector<string> args;
+
+ ParamDeclList paramList = op->parameters();
+ for(ParamDeclList::const_iterator q = paramList.begin(); q != paramList.end(); ++q)
+ {
+ args.push_back(fixKwd((*q)->name()));
+ }
+
+ return args;
+}
+
+vector<string>
+Slice::JavaVisitor::getArgsAsync(const OperationPtr& op)
+{
+ vector<string> args;
+
+ args.push_back("__cb");
+
+ ParamDeclList paramList = op->parameters();
+ for(ParamDeclList::const_iterator q = paramList.begin(); q != paramList.end(); ++q)
+ {
+ if(!(*q)->isOutParam())
+ {
+ args.push_back(fixKwd((*q)->name()));
+ }
+ }
+
+ return args;
+}
+
+vector<string>
+Slice::JavaVisitor::getArgsAsyncCB(const OperationPtr& op)
+{
+ vector<string> args;
+
+ TypePtr ret = op->returnType();
+ if(ret)
+ {
+ BuiltinPtr builtin = BuiltinPtr::dynamicCast(ret);
+ if((builtin && builtin->kind() == Builtin::KindObject) || ClassDeclPtr::dynamicCast(ret))
+ {
+ args.push_back("__ret.value");
+ }
+ else
+ {
+ args.push_back("__ret");
+ }
+ }
+
+ ParamDeclList paramList = op->parameters();
+ for(ParamDeclList::const_iterator q = paramList.begin(); q != paramList.end(); ++q)
+ {
+ if((*q)->isOutParam())
+ {
+ BuiltinPtr builtin = BuiltinPtr::dynamicCast((*q)->type());
+ if((builtin && builtin->kind() == Builtin::KindObject) || ClassDeclPtr::dynamicCast((*q)->type()))
+ {
+ args.push_back(fixKwd((*q)->name()) + ".value");
+ }
+ else
+ {
+ args.push_back(fixKwd((*q)->name()));
+ }
+ }
+ }
+
+ return args;
+}
+
+void
+Slice::JavaVisitor::writeThrowsClause(const string& package, const ExceptionList& throws)
+{
+ Output& out = output();
+ if(throws.size() > 0)
+ {
+ out.inc();
+ out << nl << "throws ";
+ out.useCurrentPosAsIndent();
+ ExceptionList::const_iterator r;
+ int count = 0;
+ for(r = throws.begin(); r != throws.end(); ++r)
+ {
+ if(count > 0)
+ {
+ out << "," << nl;
+ }
+ out << getAbsolute(*r, package);
+ count++;
+ }
+ out.restoreIndent();
+ out.dec();
+ }
+}
+
+void
+Slice::JavaVisitor::writeDelegateThrowsClause(const string& package, const ExceptionList& throws)
+{
+ Output& out = output();
+ out.inc();
+ out << nl << "throws ";
+ out.useCurrentPosAsIndent();
+ out << "IceInternal.NonRepeatable";
+
+ ExceptionList::const_iterator r;
+ for(r = throws.begin(); r != throws.end(); ++r)
+ {
+ out << "," << nl;
+ out << getAbsolute(*r, package);
+ }
+ out.restoreIndent();
+ out.dec();
+}
+
+void
+Slice::JavaVisitor::writeHashCode(Output& out, const TypePtr& type, const string& name, int& iter,
+ const StringList& metaData)
+{
+ BuiltinPtr builtin = BuiltinPtr::dynamicCast(type);
+ if(builtin)
+ {
+ switch(builtin->kind())
+ {
+ case Builtin::KindByte:
+ case Builtin::KindShort:
+ case Builtin::KindLong:
+ {
+ out << nl << "__h = 5 * __h + (int)" << name << ';';
+ break;
+ }
+ case Builtin::KindBool:
+ {
+ out << nl << "__h = 5 * __h + (" << name << " ? 1 : 0);";
+ break;
+ }
+ case Builtin::KindInt:
+ {
+ out << nl << "__h = 5 * __h + " << name << ';';
+ break;
+ }
+ case Builtin::KindFloat:
+ {
+ out << nl << "__h = 5 * __h + java.lang.Float.floatToIntBits(" << name << ");";
+ break;
+ }
+ case Builtin::KindDouble:
+ {
+ out << nl << "__h = 5 * __h + (int)java.lang.Double.doubleToLongBits(" << name << ");";
+ break;
+ }
+ case Builtin::KindString:
+ {
+ out << nl << "if(" << name << " != null)";
+ out << sb;
+ out << nl << "__h = 5 * __h + " << name << ".hashCode();";
+ out << eb;
+ break;
+ }
+ case Builtin::KindObject:
+ case Builtin::KindObjectProxy:
+ case Builtin::KindLocalObject:
+ {
+ out << nl << "if(" << name << " != null)";
+ out << sb;
+ out << nl << "__h = 5 * __h + " << name << ".hashCode();";
+ out << eb;
+ break;
+ }
+ }
+ return;
+ }
+
+ ProxyPtr prx = ProxyPtr::dynamicCast(type);
+ ClassDeclPtr cl = ClassDeclPtr::dynamicCast(type);
+ DictionaryPtr dict = DictionaryPtr::dynamicCast(type);
+ if(prx || cl || dict)
+ {
+ out << nl << "if(" << name << " != null)";
+ out << sb;
+ out << nl << "__h = 5 * __h + " << name << ".hashCode();";
+ out << eb;
+ return;
+ }
+
+ SequencePtr seq = SequencePtr::dynamicCast(type);
+ if(seq)
+ {
+ string listType = findMetaData(metaData);
+ if(listType.empty())
+ {
+ StringList l = seq->getMetaData();
+ listType = findMetaData(l);
+ }
+
+ out << nl << "if(" << name << " != null)";
+ out << sb;
+ if(!listType.empty())
+ {
+ out << nl << "__h = 5 * __h + " << name << ".hashCode();";
+ }
+ else
+ {
+ out << nl << "for(int __i" << iter << " = 0; __i" << iter << " < " << name << ".length; __i" << iter
+ << "++)";
+ out << sb;
+ ostringstream elem;
+ elem << name << "[__i" << iter << ']';
+ iter++;
+ writeHashCode(out, seq->type(), elem.str(), iter);
+ out << eb;
+ }
+ out << eb;
+ return;
+ }
+
+ ConstructedPtr constructed = ConstructedPtr::dynamicCast(type);
+ assert(constructed);
+ out << nl << "__h = 5 * __h + " << name << ".hashCode();";
+}
+
+void
+Slice::JavaVisitor::writeDispatch(Output& out, const ClassDefPtr& p)
+{
+ string name = fixKwd(p->name());
+ string package = getPackage(p);
+ string scoped = p->scoped();
+ ClassList bases = p->bases();
+
+ ClassList allBases = p->allBases();
+ StringList ids;
+ transform(allBases.begin(), allBases.end(), back_inserter(ids), ::IceUtil::constMemFun(&Contained::scoped));
+ StringList other;
+ other.push_back(scoped);
+ other.push_back("::Ice::Object");
+ other.sort();
+ ids.merge(other);
+ ids.unique();
+ StringList::const_iterator firstIter = ids.begin();
+ StringList::const_iterator scopedIter = find(ids.begin(), ids.end(), scoped);
+ assert(scopedIter != ids.end());
+ StringList::difference_type scopedPos = ice_distance(firstIter, scopedIter);
+
+ out << sp << nl << "public static final String[] __ids =";
+ out << sb;
+
+ {
+ StringList::const_iterator q = ids.begin();
+ while(q != ids.end())
+ {
+ out << nl << '"' << *q << '"';
+ if(++q != ids.end())
+ {
+ out << ',';
+ }
+ }
+ }
+ out << eb << ';';
+
+ out << sp << nl << "public boolean" << nl << "ice_isA(String s)";
+ out << sb;
+ out << nl << "return java.util.Arrays.binarySearch(__ids, s) >= 0;";
+ out << eb;
+
+ out << sp << nl << "public boolean" << nl << "ice_isA(String s, Ice.Current __current)";
+ out << sb;
+ out << nl << "return java.util.Arrays.binarySearch(__ids, s) >= 0;";
+ out << eb;
+
+ out << sp << nl << "public String[]" << nl << "ice_ids()";
+ out << sb;
+ out << nl << "return __ids;";
+ out << eb;
+
+ out << sp << nl << "public String[]" << nl << "ice_ids(Ice.Current __current)";
+ out << sb;
+ out << nl << "return __ids;";
+ out << eb;
+
+ out << sp << nl << "public String" << nl << "ice_id()";
+ out << sb;
+ out << nl << "return __ids[" << scopedPos << "];";
+ out << eb;
+
+ out << sp << nl << "public String" << nl << "ice_id(Ice.Current __current)";
+ out << sb;
+ out << nl << "return __ids[" << scopedPos << "];";
+ out << eb;
+
+ out << sp << nl << "public static String" << nl << "ice_staticId()";
+ out << sb;
+ out << nl << "return __ids[" << scopedPos << "];";
+ out << eb;
+
+ OperationList ops = p->allOperations();
+ OperationList::const_iterator r;
+
+ //
+ // Write the "no Current" implementation of each operation.
+ //
+ for(r = ops.begin(); r != ops.end(); ++r)
+ {
+ OperationPtr op = *r;
+ string opName = op->name();
+
+ ContainerPtr container = op->container();
+ ClassDefPtr cl = ClassDefPtr::dynamicCast(container);
+ assert(cl);
+
+ bool amd = cl->hasMetaData("amd") || op->hasMetaData("amd");
+
+ vector<string> params;
+ vector<string> args;
+ TypePtr ret;
+
+ if(amd)
+ {
+ opName += "_async";
+ params = getParamsAsync(op, package, true);
+ args = getArgsAsync(op);
+ }
+ else
+ {
+ opName = fixKwd(opName);
+ ret = op->returnType();
+ params = getParams(op, package);
+ args = getArgs(op);
+ }
+
+ ExceptionList throws = op->throws();
+ throws.sort();
+ throws.unique();
+
+ //
+ // Only generate a "no current" version of the operation if it hasn't been done in a base
+ // class already, because the "no current" version is final.
+ //
+ bool generateOperation = cl == p; // Generate if the operation is defined in this class.
+ if(!generateOperation)
+ {
+ //
+ // The operation is not defined in this class.
+ //
+ ClassList bases = p->bases();
+ if(!bases.empty())
+ {
+ //
+ // Check if the operation is already implemented by a base class.
+ //
+ bool implementedByBase = false;
+ if(!bases.front()->isInterface())
+ {
+ OperationList baseOps = bases.front()->allOperations();
+ OperationList::const_iterator i;
+ for(i = baseOps.begin(); i != baseOps.end(); ++i)
+ {
+ if((*i)->name() == op->name())
+ {
+ implementedByBase = true;
+ break;
+ }
+ }
+ if(i == baseOps.end())
+ {
+ generateOperation = true;
+ }
+ }
+ if(!generateOperation && !implementedByBase)
+ {
+ //
+ // No base class defines the operation. Check if one of the
+ // interfaces defines it, in which case this class must provide it.
+ //
+ if(bases.front()->isInterface() || bases.size() > 1)
+ {
+ generateOperation = true;
+ }
+ }
+ }
+ }
+ if(generateOperation)
+ {
+ out << sp << nl << "public final " << typeToString(ret, TypeModeReturn, package, op->getMetaData())
+ << nl << opName << spar << params << epar;
+ writeThrowsClause(package, throws);
+ out << sb << nl;
+ if(ret)
+ {
+ out << nl << "return ";
+ }
+ out << opName << spar << args << "null" << epar << ';';
+ out << eb;
+ }
+ }
+
+ //
+ // Dispatch operations. We only generate methods for operations
+ // defined in this ClassDef, because we reuse existing methods
+ // for inherited operations.
+ //
+ ops = p->operations();
+ for(r = ops.begin(); r != ops.end(); ++r)
+ {
+ OperationPtr op = *r;
+ StringList opMetaData = op->getMetaData();
+ ContainerPtr container = op->container();
+ ClassDefPtr cl = ClassDefPtr::dynamicCast(container);
+ assert(cl);
+
+ string opName = op->name();
+ out << sp << nl << "public static IceInternal.DispatchStatus" << nl << "___" << opName << '(' << name
+ << " __obj, IceInternal.Incoming __in, Ice.Current __current)";
+ out << sb;
+
+ bool amd = cl->hasMetaData("amd") || op->hasMetaData("amd");
+ if(!amd)
+ {
+ TypePtr ret = op->returnType();
+
+ ParamDeclList inParams;
+ ParamDeclList outParams;
+ ParamDeclList paramList = op->parameters();
+ ParamDeclList::const_iterator pli;
+ for(pli = paramList.begin(); pli != paramList.end(); ++pli)
+ {
+ if((*pli)->isOutParam())
+ {
+ outParams.push_back(*pli);
+ }
+ else
+ {
+ inParams.push_back(*pli);
+ }
+ }
+
+ ExceptionList throws = op->throws();
+ throws.sort();
+ throws.unique();
+
+ //
+ // Arrange exceptions into most-derived to least-derived order. If we don't
+ // do this, a base exception handler can appear before a derived exception
+ // handler, causing compiler warnings and resulting in the base exception
+ // being marshaled instead of the derived exception.
+ //
+#if defined(__SUNPRO_CC)
+ throws.sort(Slice::derivedToBaseCompare);
+#else
+ throws.sort(Slice::DerivedToBaseCompare());
+#endif
+
+ int iter;
+
+ if(!inParams.empty())
+ {
+ out << nl << "IceInternal.BasicStream __is = __in.is();";
+ }
+ if(!outParams.empty() || ret || !throws.empty())
+ {
+ out << nl << "IceInternal.BasicStream __os = __in.os();";
+ }
+
+ //
+ // Unmarshal 'in' parameters.
+ //
+ iter = 0;
+ for(pli = inParams.begin(); pli != inParams.end(); ++pli)
+ {
+ StringList metaData = (*pli)->getMetaData();
+ TypePtr paramType = (*pli)->type();
+ string paramName = fixKwd((*pli)->name());
+ string typeS = typeToString(paramType, TypeModeIn, package, metaData);
+ BuiltinPtr builtin = BuiltinPtr::dynamicCast(paramType);
+ if((builtin && builtin->kind() == Builtin::KindObject) || ClassDeclPtr::dynamicCast(paramType))
+ {
+ out << nl << typeS << "Holder " << paramName << " = new " << typeS << "Holder();";
+ writeMarshalUnmarshalCode(out, package, paramType, paramName, false, iter, true,
+ metaData, string());
+ }
+ else
+ {
+ out << nl << typeS << ' ' << paramName << ';';
+ writeMarshalUnmarshalCode(out, package, paramType, paramName, false, iter, false, metaData);
+ }
+ }
+ if(op->sendsClasses())
+ {
+ out << nl << "__is.readPendingObjects();";
+ }
+
+ //
+ // Create holders for 'out' parameters.
+ //
+ for(pli = outParams.begin(); pli != outParams.end(); ++pli)
+ {
+ string typeS = typeToString((*pli)->type(), TypeModeOut, package, (*pli)->getMetaData());
+ out << nl << typeS << ' ' << fixKwd((*pli)->name()) << " = new " << typeS << "();";
+ }
+
+ //
+ // Call on the servant.
+ //
+ if(!throws.empty())
+ {
+ out << nl << "try";
+ out << sb;
+ }
+ out << nl;
+ if(ret)
+ {
+ string retS = typeToString(ret, TypeModeReturn, package, opMetaData);
+ out << retS << " __ret = ";
+ }
+ out << "__obj." << fixKwd(opName) << '(';
+ for(pli = inParams.begin(); pli != inParams.end(); ++pli)
+ {
+ TypePtr paramType = (*pli)->type();
+ out << fixKwd((*pli)->name());
+ BuiltinPtr builtin = BuiltinPtr::dynamicCast(paramType);
+ if((builtin && builtin->kind() == Builtin::KindObject) || ClassDeclPtr::dynamicCast(paramType))
+ {
+ out << ".value";
+ }
+ out << ", ";
+ }
+ for(pli = outParams.begin(); pli != outParams.end(); ++pli)
+ {
+ out << fixKwd((*pli)->name()) << ", ";
+ }
+ out << "__current);";
+
+ //
+ // Marshal 'out' parameters and return value.
+ //
+ for(pli = outParams.begin(); pli != outParams.end(); ++pli)
+ {
+ writeMarshalUnmarshalCode(out, package, (*pli)->type(), fixKwd((*pli)->name()), true, iter, true,
+ (*pli)->getMetaData());
+ }
+ if(ret)
+ {
+ writeMarshalUnmarshalCode(out, package, ret, "__ret", true, iter, false, opMetaData);
+ }
+ if(op->returnsClasses())
+ {
+ out << nl << "__os.writePendingObjects();";
+ }
+ out << nl << "return IceInternal.DispatchStatus.DispatchOK;";
+
+ //
+ // Handle user exceptions.
+ //
+ if(!throws.empty())
+ {
+ out << eb;
+ ExceptionList::const_iterator t;
+ for(t = throws.begin(); t != throws.end(); ++t)
+ {
+ string exS = getAbsolute(*t, package);
+ out << nl << "catch(" << exS << " ex)";
+ out << sb;
+ out << nl << "__os.writeUserException(ex);";
+ out << nl << "return IceInternal.DispatchStatus.DispatchUserException;";
+ out << eb;
+ }
+ }
+
+ out << eb;
+ }
+ else
+ {
+ ParamDeclList inParams;
+ ParamDeclList paramList = op->parameters();
+ ParamDeclList::const_iterator pli;
+ for(pli = paramList.begin(); pli != paramList.end(); ++pli)
+ {
+ if(!(*pli)->isOutParam())
+ {
+ inParams.push_back(*pli);
+ }
+ }
+
+ int iter;
+
+ if(!inParams.empty())
+ {
+ out << nl << "IceInternal.BasicStream __is = __in.is();";
+ }
+
+ //
+ // Unmarshal 'in' parameters.
+ //
+ iter = 0;
+ for(pli = inParams.begin(); pli != inParams.end(); ++pli)
+ {
+ StringList metaData = (*pli)->getMetaData();
+ TypePtr paramType = (*pli)->type();
+ string paramName = fixKwd((*pli)->name());
+ string typeS = typeToString(paramType, TypeModeIn, package, metaData);
+ BuiltinPtr builtin = BuiltinPtr::dynamicCast(paramType);
+ if((builtin && builtin->kind() == Builtin::KindObject) || ClassDeclPtr::dynamicCast(paramType))
+ {
+ out << nl << typeS << "Holder " << paramName << " = new " << typeS << "Holder();";
+ writeMarshalUnmarshalCode(out, package, paramType, paramName, false, iter, true, metaData,
+ string());
+ }
+ else
+ {
+ out << nl << typeS << ' ' << paramName << ';';
+ writeMarshalUnmarshalCode(out, package, paramType, paramName, false, iter, false, metaData);
+ }
+ }
+ if(op->sendsClasses())
+ {
+ out << nl << "__is.readPendingObjects();";
+ }
+
+ //
+ // Call on the servant.
+ //
+ string classNameAMD = "AMD_" + p->name();
+ out << nl << classNameAMD << '_' << opName << " __cb = new _" << classNameAMD << '_' << opName
+ << "(__in);";
+ out << nl << "try";
+ out << sb;
+ out << nl << "__obj." << (amd ? opName + "_async" : fixKwd(opName)) << (amd ? "(__cb, " : "(");
+ for(pli = inParams.begin(); pli != inParams.end(); ++pli)
+ {
+ TypePtr paramType = (*pli)->type();
+ out << fixKwd((*pli)->name());
+ BuiltinPtr builtin = BuiltinPtr::dynamicCast(paramType);
+ if((builtin && builtin->kind() == Builtin::KindObject) || ClassDeclPtr::dynamicCast(paramType))
+ {
+ out << ".value";
+ }
+ out << ", ";
+ }
+ out << "__current);";
+ out << eb;
+ out << nl << "catch(java.lang.Exception ex)";
+ out << sb;
+ out << nl << "__cb.ice_exception(ex);";
+ out << eb;
+ out << nl << "return IceInternal.DispatchStatus.DispatchAsync;";
+
+ out << eb;
+ }
+ }
+
+ OperationList allOps = p->allOperations();
+ if(!allOps.empty())
+ {
+ StringList allOpNames;
+ transform(allOps.begin(), allOps.end(), back_inserter(allOpNames), ::IceUtil::constMemFun(&Contained::name));
+ allOpNames.push_back("ice_id");
+ allOpNames.push_back("ice_ids");
+ allOpNames.push_back("ice_isA");
+ allOpNames.push_back("ice_ping");
+ allOpNames.sort();
+ allOpNames.unique();
+
+ StringList::const_iterator q;
+
+ out << sp << nl << "private final static String[] __all =";
+ out << sb;
+ q = allOpNames.begin();
+ while(q != allOpNames.end())
+ {
+ out << nl << '"' << *q << '"';
+ if(++q != allOpNames.end())
+ {
+ out << ',';
+ }
+ }
+ out << eb << ';';
+
+ out << sp << nl << "public IceInternal.DispatchStatus" << nl
+ << "__dispatch(IceInternal.Incoming in, Ice.Current __current)";
+ out << sb;
+ out << nl << "int pos = java.util.Arrays.binarySearch(__all, __current.operation);";
+ out << nl << "if(pos < 0)";
+ out << sb;
+ out << nl << "return IceInternal.DispatchStatus.DispatchOperationNotExist;";
+ out << eb;
+ out << sp << nl << "switch(pos)";
+ out << sb;
+ int i = 0;
+ for(q = allOpNames.begin(); q != allOpNames.end(); ++q)
+ {
+ string opName = *q;
+
+ out << nl << "case " << i++ << ':';
+ out << sb;
+ if(opName == "ice_id")
+ {
+ out << nl << "return ___ice_id(this, in, __current);";
+ }
+ else if(opName == "ice_ids")
+ {
+ out << nl << "return ___ice_ids(this, in, __current);";
+ }
+ else if(opName == "ice_isA")
+ {
+ out << nl << "return ___ice_isA(this, in, __current);";
+ }
+ else if(opName == "ice_ping")
+ {
+ out << nl << "return ___ice_ping(this, in, __current);";
+ }
+ else
+ {
+ //
+ // There's probably a better way to do this.
+ //
+ for(OperationList::const_iterator t = allOps.begin(); t != allOps.end(); ++t)
+ {
+ if((*t)->name() == (*q))
+ {
+ ContainerPtr container = (*t)->container();
+ ClassDefPtr cl = ClassDefPtr::dynamicCast(container);
+ assert(cl);
+ if(cl->scoped() == p->scoped())
+ {
+ out << nl << "return ___" << opName << "(this, in, __current);";
+ }
+ else
+ {
+ string base;
+ if(cl->isInterface())
+ {
+ base = getAbsolute(cl, package, "_", "Disp");
+ }
+ else
+ {
+ base = getAbsolute(cl, package);
+ }
+ out << nl << "return " << base << ".___" << opName << "(this, in, __current);";
+ }
+ break;
+ }
+ }
+ }
+ out << eb;
+ }
+ out << eb;
+ out << sp << nl << "assert(false);";
+ out << nl << "return IceInternal.DispatchStatus.DispatchOperationNotExist;";
+ out << eb;
+ }
+}
+
+Slice::Gen::Gen(const string& name, const string& base, const vector<string>& includePaths, const string& dir) :
+ _base(base),
+ _includePaths(includePaths),
+ _dir(dir)
+{
+}
+
+Slice::Gen::~Gen()
+{
+}
+
+bool
+Slice::Gen::operator!() const
+{
+ return false;
+}
+
+void
+Slice::Gen::generate(const UnitPtr& p, bool stream)
+{
+ JavaGenerator::validateMetaData(p);
+
+ OpsVisitor opsVisitor(_dir);
+ p->visit(&opsVisitor, false);
+
+ PackageVisitor packageVisitor(_dir);
+ p->visit(&packageVisitor, false);
+
+ TypesVisitor typesVisitor(_dir, stream);
+ p->visit(&typesVisitor, false);
+
+ HolderVisitor holderVisitor(_dir, stream);
+ p->visit(&holderVisitor, false);
+
+ HelperVisitor helperVisitor(_dir, stream);
+ p->visit(&helperVisitor, false);
+
+ ProxyVisitor proxyVisitor(_dir);
+ p->visit(&proxyVisitor, false);
+
+ DelegateVisitor delegateVisitor(_dir);
+ p->visit(&delegateVisitor, false);
+
+ DelegateMVisitor delegateMVisitor(_dir);
+ p->visit(&delegateMVisitor, false);
+
+ DelegateDVisitor delegateDVisitor(_dir);
+ p->visit(&delegateDVisitor, false);
+
+ DispatcherVisitor dispatcherVisitor(_dir);
+ p->visit(&dispatcherVisitor, false);
+
+ AsyncVisitor asyncVisitor(_dir);
+ p->visit(&asyncVisitor, false);
+}
+
+void
+Slice::Gen::generateTie(const UnitPtr& p)
+{
+ TieVisitor tieVisitor(_dir);
+ p->visit(&tieVisitor, false);
+}
+
+void
+Slice::Gen::generateImpl(const UnitPtr& p)
+{
+ ImplVisitor implVisitor(_dir);
+ p->visit(&implVisitor, false);
+}
+
+void
+Slice::Gen::generateImplTie(const UnitPtr& p)
+{
+ ImplTieVisitor implTieVisitor(_dir);
+ p->visit(&implTieVisitor, false);
+}
+
+void
+Slice::Gen::writeChecksumClass(const string& checksumClass, const string& dir, const ChecksumMap& m)
+{
+ //
+ // Attempt to open the source file for the checksum class.
+ //
+ JavaOutput out;
+ if(!out.openClass(checksumClass, dir))
+ {
+ cerr << "can't open class `" << checksumClass << "' for writing: " << strerror(errno) << endl;
+ return;
+ }
+
+ //
+ // Get the class name.
+ //
+ string className;
+ string::size_type pos = checksumClass.rfind('.');
+ if(pos == string::npos)
+ {
+ className = checksumClass;
+ }
+ else
+ {
+ className = checksumClass.substr(pos + 1);
+ }
+
+ //
+ // Emit the class.
+ //
+ out << sp << nl << "public class " << className;
+ out << sb;
+
+ //
+ // Use a static initializer to populate the checksum map.
+ //
+ out << sp << nl << "public static java.util.Map checksums;";
+ out << sp << nl << "static";
+ out << sb;
+ out << nl << "java.util.Map map = new java.util.HashMap();";
+ for(ChecksumMap::const_iterator p = m.begin(); p != m.end(); ++p)
+ {
+ out << nl << "map.put(\"" << p->first << "\", \"";
+ ostringstream str;
+ str.flags(ios_base::hex);
+ str.fill('0');
+ for(vector<unsigned char>::const_iterator q = p->second.begin(); q != p->second.end(); ++q)
+ {
+ str << (int)(*q);
+ }
+ out << str.str() << "\");";
+ }
+ out << nl << "checksums = java.util.Collections.unmodifiableMap(map);";
+
+ out << eb;
+ out << eb;
+ out << nl;
+}
+
+Slice::Gen::OpsVisitor::OpsVisitor(const string& dir) :
+ JavaVisitor(dir)
+{
+}
+
+bool
+Slice::Gen::OpsVisitor::visitClassDefStart(const ClassDefPtr& p)
+{
+ //
+ // Don't generate an Operations interface for non-abstract classes
+ //
+ if(!p->isAbstract())
+ {
+ return false;
+ }
+
+ if(!p->isLocal())
+ {
+ writeOperations(p, false);
+ }
+ writeOperations(p, true);
+
+ return false;
+}
+
+void
+Slice::Gen::OpsVisitor::writeOperations(const ClassDefPtr& p, bool noCurrent)
+{
+ string name = p->name();
+ ClassList bases = p->bases();
+ string package = getPackage(p);
+ string opIntfName = "Operations";
+ if(noCurrent || p->isLocal())
+ {
+ opIntfName += "NC";
+ }
+ string absolute = getAbsolute(p, "", "_", opIntfName);
+
+ if(!open(absolute))
+ {
+ return;
+ }
+
+ Output& out = output();
+
+ //
+ // Generate the operations interface
+ //
+ out << sp << nl << "public interface " << '_' << name << opIntfName;
+ if((bases.size() == 1 && bases.front()->isAbstract()) || bases.size() > 1)
+ {
+ out << " extends ";
+ out.useCurrentPosAsIndent();
+ ClassList::const_iterator q = bases.begin();
+ bool first = true;
+ while(q != bases.end())
+ {
+ if((*q)->isAbstract())
+ {
+ if(!first)
+ {
+ out << ',' << nl;
+ }
+ else
+ {
+ first = false;
+ }
+ out << getAbsolute(*q, package, "_", opIntfName);
+ }
+ ++q;
+ }
+ out.restoreIndent();
+ }
+ out << sb;
+
+ OperationList ops = p->operations();
+ OperationList::const_iterator r;
+ for(r = ops.begin(); r != ops.end(); ++r)
+ {
+ OperationPtr op = *r;
+ ContainerPtr container = op->container();
+ ClassDefPtr cl = ClassDefPtr::dynamicCast(container);
+ string name = op->name();
+
+ TypePtr ret;
+ vector<string> params;
+
+ bool amd = !p->isLocal() && (cl->hasMetaData("amd") || op->hasMetaData("amd"));
+
+ if(amd)
+ {
+ params = getParamsAsync(op, package, true);
+ }
+ else
+ {
+ params = getParams(op, package);
+ ret = op->returnType();
+ }
+
+ string retS = typeToString(ret, TypeModeReturn, package, op->getMetaData());
+
+ ExceptionList throws = op->throws();
+ throws.sort();
+ throws.unique();
+ out << sp << nl << retS << ' ' << (amd ? name + "_async" : fixKwd(name)) << spar << params;
+ if(!noCurrent && !p->isLocal())
+ {
+ out << "Ice.Current __current";
+ }
+ out << epar;
+ writeThrowsClause(package, throws);
+ out << ';';
+ }
+
+ out << eb;
+
+ close();
+}
+
+Slice::Gen::TieVisitor::TieVisitor(const string& dir) :
+ JavaVisitor(dir)
+{
+}
+
+bool
+Slice::Gen::TieVisitor::visitClassDefStart(const ClassDefPtr& p)
+{
+ string name = p->name();
+ ClassList bases = p->bases();
+ string package = getPackage(p);
+ string absolute = getAbsolute(p, "", "_", "Tie");
+ string opIntfName = "Operations";
+ if(p->isLocal())
+ {
+ opIntfName += "NC";
+ }
+
+ //
+ // Don't generate a TIE class for a non-abstract class
+ //
+ if(!p->isAbstract())
+ {
+ return false;
+ }
+
+ if(!open(absolute))
+ {
+ return false;
+ }
+
+ Output& out = output();
+
+ //
+ // Generate the TIE class
+ //
+ out << sp << nl << "public class " << '_' << name << "Tie";
+ if(p->isInterface())
+ {
+ if(p->isLocal())
+ {
+ out << " implements " << fixKwd(name) << ", Ice.TieBase";
+ }
+ else
+ {
+ out << " extends " << '_' << name << "Disp implements Ice.TieBase";
+ }
+ }
+ else
+ {
+ out << " extends " << fixKwd(name) << " implements Ice.TieBase";
+ }
+
+ out << sb;
+
+ out << sp << nl << "public" << nl << '_' << name << "Tie()";
+ out << sb;
+ out << eb;
+
+ out << sp << nl << "public" << nl << '_' << name << "Tie(" << '_' << name << opIntfName
+ << " delegate)";
+ out << sb;
+ out << nl << "_ice_delegate = delegate;";
+ out << eb;
+
+ out << sp << nl << "public java.lang.Object" << nl << "ice_delegate()";
+ out << sb;
+ out << nl << "return _ice_delegate;";
+ out << eb;
+
+ out << sp << nl << "public void" << nl << "ice_delegate(java.lang.Object delegate)";
+ out << sb;
+ out << nl << "_ice_delegate = (_" << name << opIntfName << ")delegate;";
+ out << eb;
+
+ out << sp << nl << "public boolean" << nl << "equals(java.lang.Object rhs)";
+ out << sb;
+ out << nl << "if(this == rhs)";
+ out << sb;
+ out << nl << "return true;";
+ out << eb;
+ out << nl << "if(!(rhs instanceof " << '_' << name << "Tie))";
+ out << sb;
+ out << nl << "return false;";
+ out << eb;
+ out << sp << nl << "return _ice_delegate.equals(((" << '_' << name << "Tie)rhs)._ice_delegate);";
+ out << eb;
+
+ out << sp << nl << "public int" << nl << "hashCode()";
+ out << sb;
+ out << nl << "return _ice_delegate.hashCode();";
+ out << eb;
+
+ if(p->isLocal())
+ {
+ out << sp << nl << "public int" << nl << "ice_hash()";
+ out << sb;
+ out << nl << "return hashCode();";
+ out << eb;
+
+ out << sp << nl << "public java.lang.Object" << nl << "clone()";
+ out.inc();
+ out << nl << "throws java.lang.CloneNotSupportedException";
+ out.dec();
+ out << sb;
+ out << nl << "return super.clone();";
+ out << eb;
+ }
+
+ OperationList ops = p->allOperations();
+ OperationList::const_iterator r;
+ for(r = ops.begin(); r != ops.end(); ++r)
+ {
+ ContainerPtr container = (*r)->container();
+ ClassDefPtr cl = ClassDefPtr::dynamicCast(container);
+ bool hasAMD = cl->hasMetaData("amd") || (*r)->hasMetaData("amd");
+#if defined(__SUNPRO_CC) && (__SUNPRO_CC==0x550)
+ //
+ // Work around for Sun CC 5.5 bug #4853566
+ //
+ string opName;
+ if(hasAMD)
+ {
+ opName = (*r)->name() + "_async";
+ }
+ else
+ {
+ opName = fixKwd((*r)->name());
+ }
+#else
+ string opName = hasAMD ? (*r)->name() + "_async" : fixKwd((*r)->name());
+#endif
+ TypePtr ret = (*r)->returnType();
+ string retS = typeToString(ret, TypeModeReturn, package, (*r)->getMetaData());
+
+ vector<string> params;
+ vector<string> args;
+ if(hasAMD)
+ {
+ params = getParamsAsync((*r), package, true);
+ args = getArgsAsync(*r);
+ }
+ else
+ {
+ params = getParams((*r), package);
+ args = getArgs(*r);
+ }
+
+ out << sp;
+ out << nl << "public " << (hasAMD ? "void" : retS) << nl << opName << spar << params;
+ if(!p->isLocal())
+ {
+ out << "Ice.Current __current";
+ }
+ out << epar;
+
+ ExceptionList throws = (*r)->throws();
+ throws.sort();
+ throws.unique();
+ writeThrowsClause(package, throws);
+ out << sb;
+ out << nl;
+ if(ret && !hasAMD)
+ {
+ out << "return ";
+ }
+ out << "_ice_delegate." << opName << spar << args;
+ if(!p->isLocal())
+ {
+ out << "__current";
+ }
+ out << epar << ';';
+ out << eb;
+ }
+
+ out << sp << nl << "private " << '_' << name << opIntfName << " _ice_delegate;";
+ out << eb;
+ close();
+
+ return false;
+}
+
+Slice::Gen::PackageVisitor::PackageVisitor(const string& dir) :
+ JavaVisitor(dir)
+{
+}
+
+bool
+Slice::Gen::PackageVisitor::visitModuleStart(const ModulePtr& p)
+{
+ DefinitionContextPtr dc = p->definitionContext();
+ assert(dc);
+ StringList globalMetaData = dc->getMetaData();
+
+ static const string packagePrefix = "java:package:";
+
+ for(StringList::const_iterator q = globalMetaData.begin(); q != globalMetaData.end(); ++q)
+ {
+ string s = *q;
+ if(s.find(packagePrefix) == 0)
+ {
+ string markerClass = s.substr(packagePrefix.size()) + "." + fixKwd(p->name()) + "._Marker";
+
+ if(!open(markerClass))
+ {
+ cerr << "can't open class `" << markerClass << "' for writing: " << strerror(errno) << endl;
+ return false;
+ }
+
+ Output& out = output();
+ out << sp << nl << "interface _Marker";
+ out << sb;
+ out << eb;
+
+ close();
+ }
+ }
+
+ return false;
+}
+
+Slice::Gen::TypesVisitor::TypesVisitor(const string& dir, bool stream) :
+ JavaVisitor(dir), _stream(stream)
+{
+}
+
+bool
+Slice::Gen::TypesVisitor::visitClassDefStart(const ClassDefPtr& p)
+{
+ string name = p->name();
+ ClassList bases = p->bases();
+ string package = getPackage(p);
+ string absolute = getAbsolute(p);
+
+ if(!open(absolute))
+ {
+ return false;
+ }
+
+ Output& out = output();
+
+ //
+ // Slice interfaces map to Java interfaces.
+ //
+ if(p->isInterface())
+ {
+ out << sp << nl << "public interface " << fixKwd(name) << " extends ";
+ out.useCurrentPosAsIndent();
+ if(p->isLocal())
+ {
+ out << "Ice.LocalObject";
+ }
+ else
+ {
+ out << "Ice.Object";
+ }
+ out << "," << nl << '_' << name;
+ if(!p->isLocal())
+ {
+ out << "Operations, _" << name << "OperationsNC";
+ }
+ else
+ {
+ out << "OperationsNC";
+ }
+ if(!bases.empty())
+ {
+ ClassList::const_iterator q = bases.begin();
+ while(q != bases.end())
+ {
+ out << ',' << nl << getAbsolute(*q, package);
+ q++;
+ }
+ }
+ out.restoreIndent();
+ }
+ else
+ {
+ out << sp << nl << "public ";
+ if(p->isAbstract())
+ {
+ out << "abstract ";
+ }
+ out << "class " << fixKwd(name);
+ out.useCurrentPosAsIndent();
+ if(bases.empty() || bases.front()->isInterface())
+ {
+ if(p->isLocal())
+ {
+ out << " extends Ice.LocalObjectImpl";
+ }
+ else
+ {
+ out << " extends Ice.ObjectImpl";
+ }
+ }
+ else
+ {
+ out << " extends ";
+ ClassDefPtr base = bases.front();
+ out << getAbsolute(base, package);
+ bases.pop_front();
+ }
+
+ //
+ // Implement interfaces
+ //
+ StringList implements;
+ if(p->isAbstract())
+ {
+ if(!p->isLocal())
+ {
+ implements.push_back("_" + name + "Operations");
+ }
+ implements.push_back("_" + name + "OperationsNC");
+ }
+ if(!bases.empty())
+ {
+ ClassList::const_iterator q = bases.begin();
+ while(q != bases.end())
+ {
+ implements.push_back(getAbsolute(*q, package));
+ q++;
+ }
+ }
+
+ if(!implements.empty())
+ {
+ out << nl << " implements ";
+ out.useCurrentPosAsIndent();
+
+ StringList::const_iterator q = implements.begin();
+ while(q != implements.end())
+ {
+ if(q != implements.begin())
+ {
+ out << ',' << nl;
+ }
+ out << *q;
+ q++;
+ }
+
+ out.restoreIndent();
+ }
+
+ out.restoreIndent();
+ }
+
+ out << sb;
+
+ //
+ // Default factory for non-abstract classes.
+ //
+ if(!p->isAbstract() && !p->isLocal())
+ {
+ out << sp;
+ out << nl << "private static class __F extends Ice.LocalObjectImpl implements Ice.ObjectFactory";
+ out << sb;
+ out << nl << "public Ice.Object" << nl << "create(String type)";
+ out << sb;
+ out << nl << "assert(type.equals(ice_staticId()));";
+ out << nl << "return new " << fixKwd(name) << "();";
+ out << eb;
+ out << sp << nl << "public void" << nl << "destroy()";
+ out << sb;
+ out << eb;
+ out << eb;
+ out << nl << "private static Ice.ObjectFactory _factory = new __F();";
+ out << sp;
+ out << nl << "public static Ice.ObjectFactory" << nl << "ice_factory()";
+ out << sb;
+ out << nl << "return _factory;";
+ out << eb;
+ }
+
+ //
+ // Marshalling & dispatch support.
+ //
+ if(!p->isInterface() && !p->isLocal())
+ {
+ writeDispatch(out, p);
+
+ DataMemberList members = p->dataMembers();
+ DataMemberList::const_iterator d;
+ int iter;
+
+ out << sp << nl << "public void" << nl << "__write(IceInternal.BasicStream __os)";
+ out << sb;
+ out << nl << "__os.writeTypeId(ice_staticId());";
+ out << nl << "__os.startWriteSlice();";
+ iter = 0;
+ for(d = members.begin(); d != members.end(); ++d)
+ {
+ StringList metaData = (*d)->getMetaData();
+ writeMarshalUnmarshalCode(out, package, (*d)->type(), fixKwd((*d)->name()), true, iter, false, metaData);
+ }
+ out << nl << "__os.endWriteSlice();";
+ out << nl << "super.__write(__os);";
+ out << eb;
+
+ DataMemberList allClassMembers = p->allClassDataMembers();
+ if(allClassMembers.size() != 0)
+ {
+ out << sp << nl << "private class Patcher implements IceInternal.Patcher";
+ if(_stream)
+ {
+ out << ", Ice.ReadObjectCallback";
+ }
+ out << sb;
+ if(allClassMembers.size() > 1)
+ {
+ out << sp << nl << "Patcher(int member)";
+ out << sb;
+ out << nl << "__member = member;";
+ out << eb;
+ }
+
+ out << sp << nl << "public void" << nl << "patch(Ice.Object v)";
+ out << sb;
+ if(allClassMembers.size() > 1)
+ {
+ out << nl << "switch(__member)";
+ out << sb;
+ }
+ int memberCount = 0;
+ for(d = allClassMembers.begin(); d != allClassMembers.end(); ++d)
+ {
+ if(allClassMembers.size() > 1)
+ {
+ out.dec();
+ out << nl << "case " << memberCount << ":";
+ out.inc();
+ }
+ if(allClassMembers.size() > 1)
+ {
+ out << nl << "__typeId = \"" << (*d)->type()->typeId() << "\";";
+ }
+ string memberName = fixKwd((*d)->name());
+ string memberType = typeToString((*d)->type(), TypeModeMember, package);
+ out << nl << memberName << " = (" << memberType << ")v;";
+ if(allClassMembers.size() > 1)
+ {
+ out << nl << "break;";
+ }
+ memberCount++;
+ }
+ if(allClassMembers.size() > 1)
+ {
+ out << eb;
+ }
+ out << eb;
+
+ out << sp << nl << "public String" << nl << "type()";
+ out << sb;
+ if(allClassMembers.size() > 1)
+ {
+ out << nl << "return __typeId;";
+ }
+ else
+ {
+ out << nl << "return \"" << (*allClassMembers.begin())->type()->typeId() << "\";";
+ }
+ out << eb;
+
+ if(_stream)
+ {
+ out << sp << nl << "public void" << nl << "invoke(Ice.Object v)";
+ out << sb;
+ out << nl << "patch(v);";
+ out << eb;
+ }
+
+ if(allClassMembers.size() > 1)
+ {
+ out << sp << nl << "private int __member;";
+ out << nl << "private String __typeId;";
+ }
+ out << eb;
+ }
+
+ out << sp << nl << "public void" << nl << "__read(IceInternal.BasicStream __is, boolean __rid)";
+ out << sb;
+ out << nl << "if(__rid)";
+ out << sb;
+ out << nl << "String myId = __is.readTypeId();";
+ out << eb;
+ out << nl << "__is.startReadSlice();";
+ iter = 0;
+ DataMemberList classMembers = p->classDataMembers();
+ long classMemberCount = allClassMembers.size() - classMembers.size();
+ for(d = members.begin(); d != members.end(); ++d)
+ {
+ StringList metaData = (*d)->getMetaData();
+ ostringstream patchParams;
+ BuiltinPtr builtin = BuiltinPtr::dynamicCast((*d)->type());
+ if((builtin && builtin->kind() == Builtin::KindObject) || ClassDeclPtr::dynamicCast((*d)->type()))
+ {
+ if(classMembers.size() > 1 || allClassMembers.size() > 1)
+ {
+ patchParams << "new Patcher(" << classMemberCount++ << ')';
+ }
+ }
+ writeMarshalUnmarshalCode(out, package, (*d)->type(), fixKwd((*d)->name()), false, iter, false, metaData,
+ patchParams.str());
+ }
+ out << nl << "__is.endReadSlice();";
+ out << nl << "super.__read(__is, true);";
+ out << eb;
+
+ if(_stream)
+ {
+ out << sp << nl << "public void" << nl << "__write(Ice.OutputStream __out)";
+ out << sb;
+ out << nl << "__out.writeTypeId(ice_staticId());";
+ out << nl << "__out.startSlice();";
+ iter = 0;
+ for(d = members.begin(); d != members.end(); ++d)
+ {
+ StringList metaData = (*d)->getMetaData();
+ writeStreamMarshalUnmarshalCode(out, package, (*d)->type(), fixKwd((*d)->name()), true, iter, false,
+ metaData);
+ }
+ out << nl << "__out.endSlice();";
+ out << nl << "super.__write(__out);";
+ out << eb;
+
+ out << sp << nl << "public void" << nl << "__read(Ice.InputStream __in, boolean __rid)";
+ out << sb;
+ out << nl << "if(__rid)";
+ out << sb;
+ out << nl << "String myId = __in.readTypeId();";
+ out << eb;
+ out << nl << "__in.startSlice();";
+ iter = 0;
+ for(d = members.begin(); d != members.end(); ++d)
+ {
+ StringList metaData = (*d)->getMetaData();
+ ostringstream patchParams;
+ BuiltinPtr builtin = BuiltinPtr::dynamicCast((*d)->type());
+ if((builtin && builtin->kind() == Builtin::KindObject) || ClassDeclPtr::dynamicCast((*d)->type()))
+ {
+ if(classMembers.size() > 1 || allClassMembers.size() > 1)
+ {
+ patchParams << "new Patcher(" << classMemberCount++ << ')';
+ }
+ }
+ writeStreamMarshalUnmarshalCode(out, package, (*d)->type(), fixKwd((*d)->name()), false, iter, false,
+ metaData, patchParams.str());
+ }
+ out << nl << "__in.endSlice();";
+ out << nl << "super.__read(__in, true);";
+ out << eb;
+ }
+ else
+ {
+ //
+ // Emit placeholder functions to catch errors.
+ //
+ string scoped = p->scoped();
+ out << sp << nl << "public void" << nl << "__write(Ice.OutputStream __out)";
+ out << sb;
+ out << nl << "Ice.MarshalException ex = new Ice.MarshalException();";
+ out << nl << "ex.reason = \"type " << scoped.substr(2) << " was not generated with stream support\";";
+ out << nl << "throw ex;";
+ out << eb;
+
+ out << sp << nl << "public void" << nl << "__read(Ice.InputStream __in, boolean __rid)";
+ out << sb;
+ out << nl << "Ice.MarshalException ex = new Ice.MarshalException();";
+ out << nl << "ex.reason = \"type " << scoped.substr(2) << " was not generated with stream support\";";
+ out << nl << "throw ex;";
+ out << eb;
+ }
+ }
+
+ return true;
+}
+
+void
+Slice::Gen::TypesVisitor::visitClassDefEnd(const ClassDefPtr& p)
+{
+ Output& out = output();
+ out << eb;
+ close();
+}
+
+bool
+Slice::Gen::TypesVisitor::visitExceptionStart(const ExceptionPtr& p)
+{
+ string name = fixKwd(p->name());
+ string scoped = p->scoped();
+ ExceptionPtr base = p->base();
+ string package = getPackage(p);
+ string absolute = getAbsolute(p);
+
+ if(!open(absolute))
+ {
+ return false;
+ }
+
+ Output& out = output();
+
+ out << sp << nl << "public class " << name << " extends ";
+
+ if(!base)
+ {
+ if(p->isLocal())
+ {
+ out << "Ice.LocalException";
+ }
+ else
+ {
+ out << "Ice.UserException";
+ }
+ }
+ else
+ {
+ out << getAbsolute(base, package);
+ }
+ out << sb;
+
+ out << sp << nl << "public String" << nl << "ice_name()";
+ out << sb;
+ out << nl << "return \"" << scoped.substr(2) << "\";";
+ out << eb;
+
+ return true;
+}
+
+void
+Slice::Gen::TypesVisitor::visitExceptionEnd(const ExceptionPtr& p)
+{
+ Output& out = output();
+
+ if(!p->isLocal())
+ {
+ string name = fixKwd(p->name());
+ string scoped = p->scoped();
+ string package = getPackage(p);
+ ExceptionPtr base = p->base();
+
+ DataMemberList members = p->dataMembers();
+ DataMemberList::const_iterator d;
+ int iter;
+
+ out << sp << nl << "public void" << nl << "__write(IceInternal.BasicStream __os)";
+ out << sb;
+ out << nl << "__os.writeString(\"" << scoped << "\");";
+ out << nl << "__os.startWriteSlice();";
+ iter = 0;
+ for(d = members.begin(); d != members.end(); ++d)
+ {
+ StringList metaData = (*d)->getMetaData();
+ writeMarshalUnmarshalCode(out, package, (*d)->type(), fixKwd((*d)->name()), true, iter, false, metaData);
+ }
+ out << nl << "__os.endWriteSlice();";
+ if(base)
+ {
+ out << nl << "super.__write(__os);";
+ }
+ out << eb;
+
+ DataMemberList allClassMembers = p->allClassDataMembers();
+ if(allClassMembers.size() != 0)
+ {
+ out << sp << nl << "private class Patcher implements IceInternal.Patcher";
+ if(_stream)
+ {
+ out << ", Ice.ReadObjectCallback";
+ }
+ out << sb;
+ if(allClassMembers.size() > 1)
+ {
+ out << sp << nl << "Patcher(int member)";
+ out << sb;
+ out << nl << "__member = member;";
+ out << eb;
+ }
+
+ out << sp << nl << "public void" << nl << "patch(Ice.Object v)";
+ out << sb;
+ if(allClassMembers.size() > 1)
+ {
+ out << nl << "switch(__member)";
+ out << sb;
+ }
+ int memberCount = 0;
+ for(d = allClassMembers.begin(); d != allClassMembers.end(); ++d)
+ {
+ if(allClassMembers.size() > 1)
+ {
+ out.dec();
+ out << nl << "case " << memberCount << ":";
+ out.inc();
+ }
+ if(allClassMembers.size() > 1)
+ {
+ out << nl << "__typeId = \"" << (*d)->type()->typeId() << "\";";
+ }
+ string memberName = fixKwd((*d)->name());
+ string memberType = typeToString((*d)->type(), TypeModeMember, package);
+ out << nl << memberName << " = (" << memberType << ")v;";
+ if(allClassMembers.size() > 1)
+ {
+ out << nl << "break;";
+ }
+ memberCount++;
+ }
+ if(allClassMembers.size() > 1)
+ {
+ out << eb;
+ }
+ out << eb;
+
+ out << sp << nl << "public String" << nl << "type()";
+ out << sb;
+ if(allClassMembers.size() > 1)
+ {
+ out << nl << "return __typeId;";
+ }
+ else
+ {
+ out << nl << "return \"" << (*allClassMembers.begin())->type()->typeId() << "\";";
+ }
+ out << eb;
+
+ if(_stream)
+ {
+ out << sp << nl << "public void" << nl << "invoke(Ice.Object v)";
+ out << sb;
+ out << nl << "patch(v);";
+ out << eb;
+ }
+
+ if(allClassMembers.size() > 1)
+ {
+ out << sp << nl << "private int __member;";
+ out << nl << "private String __typeId;";
+ }
+ out << eb;
+ }
+ out << sp << nl << "public void" << nl << "__read(IceInternal.BasicStream __is, boolean __rid)";
+ out << sb;
+ out << nl << "if(__rid)";
+ out << sb;
+ out << nl << "String myId = __is.readString();";
+ out << eb;
+ out << nl << "__is.startReadSlice();";
+ iter = 0;
+ DataMemberList classMembers = p->classDataMembers();
+ long classMemberCount = allClassMembers.size() - classMembers.size();
+ for(d = members.begin(); d != members.end(); ++d)
+ {
+ ostringstream patchParams;
+ BuiltinPtr builtin = BuiltinPtr::dynamicCast((*d)->type());
+ if((builtin && builtin->kind() == Builtin::KindObject) || ClassDeclPtr::dynamicCast((*d)->type()))
+ {
+ if(classMembers.size() > 1 || allClassMembers.size() > 1)
+ {
+ patchParams << "new Patcher(" << classMemberCount++ << ')';
+ }
+ }
+ StringList metaData = (*d)->getMetaData();
+ writeMarshalUnmarshalCode(out, package, (*d)->type(), fixKwd((*d)->name()), false, iter, false, metaData,
+ patchParams.str());
+ }
+ out << nl << "__is.endReadSlice();";
+ if(base)
+ {
+ out << nl << "super.__read(__is, true);";
+ }
+ out << eb;
+
+ if(_stream)
+ {
+ out << sp << nl << "public void" << nl << "__write(Ice.OutputStream __out)";
+ out << sb;
+ out << nl << "__out.writeString(\"" << scoped << "\");";
+ out << nl << "__out.startSlice();";
+ iter = 0;
+ for(d = members.begin(); d != members.end(); ++d)
+ {
+ StringList metaData = (*d)->getMetaData();
+ writeStreamMarshalUnmarshalCode(out, package, (*d)->type(), fixKwd((*d)->name()), true, iter, false,
+ metaData);
+ }
+ out << nl << "__out.endSlice();";
+ if(base)
+ {
+ out << nl << "super.__write(__out);";
+ }
+ out << eb;
+
+ out << sp << nl << "public void" << nl << "__read(Ice.InputStream __in, boolean __rid)";
+ out << sb;
+ out << nl << "if(__rid)";
+ out << sb;
+ out << nl << "String myId = __in.readString();";
+ out << eb;
+ out << nl << "__in.startSlice();";
+ iter = 0;
+ for(d = members.begin(); d != members.end(); ++d)
+ {
+ ostringstream patchParams;
+ BuiltinPtr builtin = BuiltinPtr::dynamicCast((*d)->type());
+ if((builtin && builtin->kind() == Builtin::KindObject) || ClassDeclPtr::dynamicCast((*d)->type()))
+ {
+ if(classMembers.size() > 1 || allClassMembers.size() > 1)
+ {
+ patchParams << "new Patcher(" << classMemberCount++ << ')';
+ }
+ }
+ StringList metaData = (*d)->getMetaData();
+ writeStreamMarshalUnmarshalCode(out, package, (*d)->type(), fixKwd((*d)->name()), false, iter, false,
+ metaData, patchParams.str());
+ }
+ out << nl << "__in.endSlice();";
+ if(base)
+ {
+ out << nl << "super.__read(__in, true);";
+ }
+ out << eb;
+ }
+ else
+ {
+ //
+ // Emit placeholder functions to catch errors.
+ //
+ string scoped = p->scoped();
+ out << sp << nl << "public void" << nl << "__write(Ice.OutputStream __out)";
+ out << sb;
+ out << nl << "Ice.MarshalException ex = new Ice.MarshalException();";
+ out << nl << "ex.reason = \"exception " << scoped.substr(2) << " was not generated with stream support\";";
+ out << nl << "throw ex;";
+ out << eb;
+
+ out << sp << nl << "public void" << nl << "__read(Ice.InputStream __in, boolean __rid)";
+ out << sb;
+ out << nl << "Ice.MarshalException ex = new Ice.MarshalException();";
+ out << nl << "ex.reason = \"exception " << scoped.substr(2) << " was not generated with stream support\";";
+ out << nl << "throw ex;";
+ out << eb;
+ }
+
+ if(p->usesClasses())
+ {
+ if(!base || base && !base->usesClasses())
+ {
+ out << sp << nl << "public boolean" << nl << "__usesClasses()";
+ out << sb;
+ out << nl << "return true;";
+ out << eb;
+ }
+ }
+ }
+
+ out << eb;
+ close();
+}
+
+bool
+Slice::Gen::TypesVisitor::visitStructStart(const StructPtr& p)
+{
+ string name = fixKwd(p->name());
+ string absolute = getAbsolute(p);
+
+ if(!open(absolute))
+ {
+ return false;
+ }
+
+ Output& out = output();
+
+ out << sp << nl << "public final class " << name << " implements java.lang.Cloneable";
+ out << sb;
+
+ return true;
+}
+
+void
+Slice::Gen::TypesVisitor::visitStructEnd(const StructPtr& p)
+{
+ string package = getPackage(p);
+
+ Output& out = output();
+
+ DataMemberList members = p->dataMembers();
+ DataMemberList::const_iterator d;
+ int iter;
+
+ string typeS = typeToString(p, TypeModeIn, package);
+
+ out << sp << nl << "public boolean" << nl << "equals(java.lang.Object rhs)";
+ out << sb;
+ out << nl << typeS << " _r = null;";
+ out << nl << "try";
+ out << sb;
+ out << nl << "_r = (" << typeS << ")rhs;";
+ out << eb;
+ out << nl << "catch(ClassCastException ex)";
+ out << sb;
+ out << eb;
+ out << sp << nl << "if(_r != null)";
+ out << sb;
+ for(d = members.begin(); d != members.end(); ++d)
+ {
+ string memberName = fixKwd((*d)->name());
+ BuiltinPtr b = BuiltinPtr::dynamicCast((*d)->type());
+ if(b)
+ {
+ switch(b->kind())
+ {
+ case Builtin::KindByte:
+ case Builtin::KindBool:
+ case Builtin::KindShort:
+ case Builtin::KindInt:
+ case Builtin::KindLong:
+ case Builtin::KindFloat:
+ case Builtin::KindDouble:
+ {
+ out << nl << "if(" << memberName << " != _r." << memberName << ')';
+ out << sb;
+ out << nl << "return false;";
+ out << eb;
+ break;
+ }
+
+ case Builtin::KindString:
+ case Builtin::KindObject:
+ case Builtin::KindObjectProxy:
+ case Builtin::KindLocalObject:
+ {
+ out << nl << "if(" << memberName << " != _r." << memberName << " && " << memberName
+ << " != null && !" << memberName << ".equals(_r." << memberName << "))";
+ out << sb;
+ out << nl << "return false;";
+ out << eb;
+ break;
+ }
+ }
+ }
+ else
+ {
+ //
+ // We treat sequences differently because the native equals() method for
+ // a Java array does not perform a deep comparison. If the mapped type
+ // is not overridden via metadata, we use the helper method
+ // java.util.Arrays.equals() to compare native arrays.
+ //
+ // For all other types, we can use the native equals() method.
+ //
+ SequencePtr seq = SequencePtr::dynamicCast((*d)->type());
+ if(seq)
+ {
+ StringList metaData = (*d)->getMetaData();
+ string listType = findMetaData(metaData);
+ if(listType.empty())
+ {
+ StringList l = seq->getMetaData();
+ listType = findMetaData(l);
+ }
+ if(!listType.empty())
+ {
+ out << nl << "if(" << memberName << " != _r." << memberName << " && " << memberName
+ << " != null && !" << memberName << ".equals(_r." << memberName << "))";
+ out << sb;
+ out << nl << "return false;";
+ out << eb;
+ }
+ else
+ {
+ out << nl << "if(!java.util.Arrays.equals(" << memberName << ", _r." << memberName << "))";
+ out << sb;
+ out << nl << "return false;";
+ out << eb;
+ }
+ }
+ else
+ {
+ out << nl << "if(" << memberName << " != _r." << memberName << " && " << memberName
+ << " != null && !" << memberName << ".equals(_r." << memberName << "))";
+ out << sb;
+ out << nl << "return false;";
+ out << eb;
+ }
+ }
+ }
+ out << sp << nl << "return true;";
+ out << eb;
+ out << sp << nl << "return false;";
+ out << eb;
+
+ out << sp << nl << "public int" << nl << "hashCode()";
+ out << sb;
+ out << nl << "int __h = 0;";
+ iter = 0;
+ for(d = members.begin(); d != members.end(); ++d)
+ {
+ string memberName = fixKwd((*d)->name());
+ StringList metaData = (*d)->getMetaData();
+ writeHashCode(out, (*d)->type(), memberName, iter, metaData);
+ }
+ out << nl << "return __h;";
+ out << eb;
+
+ out << sp << nl << "public java.lang.Object" << nl << "clone()";
+ out.inc();
+ out << nl << "throws java.lang.CloneNotSupportedException";
+ out.dec();
+ out << sb;
+ out << nl << "return super.clone();";
+ out << eb;
+
+ if(!p->isLocal())
+ {
+ out << sp << nl << "public void" << nl << "__write(IceInternal.BasicStream __os)";
+ out << sb;
+ iter = 0;
+ for(d = members.begin(); d != members.end(); ++d)
+ {
+ StringList metaData = (*d)->getMetaData();
+ writeMarshalUnmarshalCode(out, package, (*d)->type(), fixKwd((*d)->name()), true, iter, false, metaData);
+ }
+ out << eb;
+
+ DataMemberList classMembers = p->classDataMembers();
+
+ if(classMembers.size() != 0)
+ {
+ out << sp << nl << "private class Patcher implements IceInternal.Patcher";
+ if(_stream)
+ {
+ out << ", Ice.ReadObjectCallback";
+ }
+ out << sb;
+ if(classMembers.size() > 1)
+ {
+ out << sp << nl << "Patcher(int member)";
+ out << sb;
+ out << nl << "__member = member;";
+ out << eb;
+ }
+
+ out << sp << nl << "public void" << nl << "patch(Ice.Object v)";
+ out << sb;
+ if(classMembers.size() > 1)
+ {
+ out << nl << "switch(__member)";
+ out << sb;
+ }
+ int memberCount = 0;
+ for(d = classMembers.begin(); d != classMembers.end(); ++d)
+ {
+ if(classMembers.size() > 1)
+ {
+ out.dec();
+ out << nl << "case " << memberCount << ":";
+ out.inc();
+ }
+ if(classMembers.size() > 1)
+ {
+ out << nl << "__typeId = \"" << (*d)->type()->typeId() << "\";";
+ }
+ string memberName = fixKwd((*d)->name());
+ string memberType = typeToString((*d)->type(), TypeModeMember, package);
+ out << nl << memberName << " = (" << memberType << ")v;";
+ if(classMembers.size() > 1)
+ {
+ out << nl << "break;";
+ }
+ memberCount++;
+ }
+ if(classMembers.size() > 1)
+ {
+ out << eb;
+ }
+ out << eb;
+
+ out << sp << nl << "public String" << nl << "type()";
+ out << sb;
+ if(classMembers.size() > 1)
+ {
+ out << nl << "return __typeId;";
+ }
+ else
+ {
+ out << nl << "return \"" << (*classMembers.begin())->type()->typeId() << "\";";
+ }
+ out << eb;
+
+ if(_stream)
+ {
+ out << sp << nl << "public void" << nl << "invoke(Ice.Object v)";
+ out << sb;
+ out << nl << "patch(v);";
+ out << eb;
+ }
+
+ if(classMembers.size() > 1)
+ {
+ out << sp << nl << "private int __member;";
+ out << nl << "private String __typeId;";
+ }
+ out << eb;
+ }
+
+ out << sp << nl << "public void" << nl << "__read(IceInternal.BasicStream __is)";
+ out << sb;
+ iter = 0;
+ int classMemberCount = 0;
+ for(d = members.begin(); d != members.end(); ++d)
+ {
+ ostringstream patchParams;
+ BuiltinPtr builtin = BuiltinPtr::dynamicCast((*d)->type());
+ if((builtin && builtin->kind() == Builtin::KindObject) || ClassDeclPtr::dynamicCast((*d)->type()))
+ {
+ if(classMembers.size() > 1)
+ {
+ patchParams << "new Patcher(" << classMemberCount++ << ')';
+ }
+ }
+ StringList metaData = (*d)->getMetaData();
+ writeMarshalUnmarshalCode(out, package, (*d)->type(), fixKwd((*d)->name()), false, iter, false, metaData,
+ patchParams.str());
+ }
+ out << eb;
+
+ if(_stream)
+ {
+ out << sp << nl << "public void" << nl << "__write(Ice.OutputStream __out)";
+ out << sb;
+ iter = 0;
+ for(d = members.begin(); d != members.end(); ++d)
+ {
+ StringList metaData = (*d)->getMetaData();
+ writeStreamMarshalUnmarshalCode(out, package, (*d)->type(), fixKwd((*d)->name()), true, iter, false,
+ metaData);
+ }
+ out << eb;
+
+ out << sp << nl << "public void" << nl << "__read(Ice.InputStream __in)";
+ out << sb;
+ iter = 0;
+ classMemberCount = 0;
+ for(d = members.begin(); d != members.end(); ++d)
+ {
+ ostringstream patchParams;
+ BuiltinPtr builtin = BuiltinPtr::dynamicCast((*d)->type());
+ if((builtin && builtin->kind() == Builtin::KindObject) || ClassDeclPtr::dynamicCast((*d)->type()))
+ {
+ if(classMembers.size() > 1)
+ {
+ patchParams << "new Patcher(" << classMemberCount++ << ')';
+ }
+ }
+ StringList metaData = (*d)->getMetaData();
+ writeStreamMarshalUnmarshalCode(out, package, (*d)->type(), fixKwd((*d)->name()), false, iter, false,
+ metaData, patchParams.str());
+ }
+ out << eb;
+ }
+ }
+
+ out << eb;
+ close();
+}
+
+void
+Slice::Gen::TypesVisitor::visitDataMember(const DataMemberPtr& p)
+{
+ string name = fixKwd(p->name());
+ ContainerPtr container = p->container();
+ ContainedPtr contained = ContainedPtr::dynamicCast(container);
+ StringList metaData = p->getMetaData();
+ string s = typeToString(p->type(), TypeModeMember, getPackage(contained), metaData);
+ Output& out = output();
+ out << sp << nl << "public " << s << ' ' << name << ';';
+}
+
+void
+Slice::Gen::TypesVisitor::visitEnum(const EnumPtr& p)
+{
+ string name = fixKwd(p->name());
+ string absolute = getAbsolute(p);
+ EnumeratorList enumerators = p->getEnumerators();
+ EnumeratorList::const_iterator en;
+ size_t sz = enumerators.size();
+
+ if(!open(absolute))
+ {
+ return;
+ }
+
+ Output& out = output();
+
+ out << sp << nl << "public final class " << name;
+ out << sb;
+ out << nl << "private static " << name << "[] __values = new " << name << "[" << sz << "];";
+ out << nl << "private int __value;";
+ out << sp;
+ int n;
+ for(en = enumerators.begin(), n = 0; en != enumerators.end(); ++en, ++n)
+ {
+ string member = fixKwd((*en)->name());
+ out << nl << "public static final int _" << member << " = " << n << ';';
+ out << nl << "public static final " << name << ' ' << fixKwd(member)
+ << " = new " << name << "(_" << member << ");";
+ }
+
+ out << sp << nl << "public static " << name << nl << "convert(int val)";
+ out << sb;
+ out << nl << "assert val < " << sz << ';';
+ out << nl << "return __values[val];";
+ out << eb;
+
+ out << sp << nl << "public int" << nl << "value()";
+ out << sb;
+ out << nl << "return __value;";
+ out << eb;
+
+ out << sp << nl << "public String" << nl << "toString()";
+ out << sb;
+ out << nl << "return __T[__value];";
+ out << eb;
+
+ out << sp << nl << "private" << nl << name << "(int val)";
+ out << sb;
+ out << nl << "__value = val;";
+ out << nl << "__values[val] = this;";
+ out << eb;
+
+ if(!p->isLocal())
+ {
+ out << sp << nl << "public void" << nl << "__write(IceInternal.BasicStream __os)";
+ out << sb;
+ if(sz <= 0x7f)
+ {
+ out << nl << "__os.writeByte((byte)__value);";
+ }
+ else if(sz <= 0x7fff)
+ {
+ out << nl << "__os.writeShort((short)__value);";
+ }
+ else
+ {
+ out << nl << "__os.writeInt(__value);";
+ }
+ out << eb;
+
+ out << sp << nl << "public static " << name << nl << "__read(IceInternal.BasicStream __is)";
+ out << sb;
+ if(sz <= 0x7f)
+ {
+ out << nl << "int __v = __is.readByte();";
+ }
+ else if(sz <= 0x7fff)
+ {
+ out << nl << "int __v = __is.readShort();";
+ }
+ else
+ {
+ out << nl << "int __v = __is.readInt();";
+ }
+ out << nl << "if(__v < 0 || __v >= " << sz << ')';
+ out << sb;
+ out << nl << "throw new Ice.MarshalException();";
+ out << eb;
+ out << nl << "return " << name << ".convert(__v);";
+ out << eb;
+
+ if(_stream)
+ {
+ out << sp << nl << "public void" << nl << "__write(Ice.OutputStream __out)";
+ out << sb;
+ if(sz <= 0x7f)
+ {
+ out << nl << "__out.writeByte((byte)__value);";
+ }
+ else if(sz <= 0x7fff)
+ {
+ out << nl << "__out.writeShort((short)__value);";
+ }
+ else
+ {
+ out << nl << "__out.writeInt(__value);";
+ }
+ out << eb;
+
+ out << sp << nl << "public static " << name << nl << "__read(Ice.InputStream __in)";
+ out << sb;
+ if(sz <= 0x7f)
+ {
+ out << nl << "int __v = __in.readByte();";
+ }
+ else if(sz <= 0x7fff)
+ {
+ out << nl << "int __v = __in.readShort();";
+ }
+ else
+ {
+ out << nl << "int __v = __in.readInt();";
+ }
+ out << nl << "if(__v < 0 || __v >= " << sz << ')';
+ out << sb;
+ out << nl << "throw new Ice.MarshalException();";
+ out << eb;
+ out << nl << "return " << name << ".convert(__v);";
+ out << eb;
+ }
+ }
+
+ out << sp << nl << "final static private String[] __T =";
+ out << sb;
+ en = enumerators.begin();
+ while(en != enumerators.end())
+ {
+ out << nl << "\"" << (*en)->name() << "\"";
+ if(++en != enumerators.end())
+ {
+ out << ',';
+ }
+ }
+ out << eb << ';';
+
+ out << eb;
+ close();
+}
+
+void
+Slice::Gen::TypesVisitor::visitConst(const ConstPtr& p)
+{
+ string name = fixKwd(p->name());
+ string package = getPackage(p);
+ string absolute = getAbsolute(p);
+ TypePtr type = p->type();
+
+ if(!open(absolute))
+ {
+ return;
+ }
+ Output& out = output();
+ out << sp << nl << "public interface " << name;
+ out << sb;
+ out << nl << typeToString(type, TypeModeIn, package) << " value = ";
+
+ BuiltinPtr bp;
+ EnumPtr ep;
+ if(bp = BuiltinPtr::dynamicCast(type))
+ {
+ switch(bp->kind())
+ {
+ case Builtin::KindString:
+ {
+ out << "\"";
+
+ ios_base::fmtflags originalFlags = out.flags();
+ streamsize originalWidth = out.width();
+ ostream::char_type originalFill = out.fill();
+
+ const string val = p->value();
+ for(string::const_iterator c = val.begin(); c != val.end(); ++c)
+ {
+ if(isascii(*c) && isprint(*c))
+ {
+ switch(*c)
+ {
+ case '\\':
+ case '"':
+ {
+ out << "\\";
+ break;
+ }
+ }
+ out << *c;
+ }
+ else
+ {
+ switch(*c)
+ {
+ case '\r':
+ {
+ out << "\\r";
+ break;
+ }
+ case '\n':
+ {
+ out << "\\n";
+ break;
+ }
+ default:
+ {
+ unsigned char uc = *c;
+ out << "\\u";
+ out.flags(ios_base::hex);
+ out.width(4);
+ out.fill('0');
+ out << static_cast<unsigned>(uc);
+ break;
+ }
+ }
+ }
+ }
+
+ out.fill(originalFill);
+ out.width(originalWidth);
+ out.flags(originalFlags);
+
+ out << "\"";
+ break;
+ }
+ case Builtin::KindByte:
+ {
+ int i = atoi(p->value().c_str());
+ if(i > 127)
+ {
+ i -= 256;
+ }
+ out << i; // Slice byte runs from 0-255, Java byte runs from -128 - 127.
+ break;
+ }
+ case Builtin::KindLong:
+ {
+ out << p->value() << "L"; // Need to append "L" modifier for long constants.
+ break;
+ }
+ case Builtin::KindBool:
+ case Builtin::KindShort:
+ case Builtin::KindInt:
+ case Builtin::KindFloat:
+ case Builtin::KindDouble:
+ case Builtin::KindObject:
+ case Builtin::KindObjectProxy:
+ case Builtin::KindLocalObject:
+ {
+ out << p->value();
+ break;
+ }
+ }
+
+ }
+ else if(ep = EnumPtr::dynamicCast(type))
+ {
+ string val = p->value();
+ string::size_type pos = val.rfind(':');
+ if(pos != string::npos)
+ {
+ val.erase(0, pos + 1);
+ }
+ out << getAbsolute(ep, package) << '.' << fixKwd(val);
+ }
+ else
+ {
+ out << p->value();
+ }
+ out << ';' << eb;
+ close();
+}
+
+Slice::Gen::HolderVisitor::HolderVisitor(const string& dir, bool stream) :
+ JavaVisitor(dir), _stream(stream)
+{
+}
+
+bool
+Slice::Gen::HolderVisitor::visitClassDefStart(const ClassDefPtr& p)
+{
+ ClassDeclPtr decl = p->declaration();
+ writeHolder(decl);
+
+ if(!p->isLocal())
+ {
+ string name = p->name();
+ string absolute = getAbsolute(p, "", "", "PrxHolder");
+
+ if(open(absolute))
+ {
+ Output& out = output();
+ out << sp << nl << "public final class " << name << "PrxHolder";
+ out << sb;
+ out << sp << nl << "public" << nl << name << "PrxHolder()";
+ out << sb;
+ out << eb;
+ out << sp << nl << "public" << nl << name << "PrxHolder(" << name << "Prx value)";
+ out << sb;
+ out << nl << "this.value = value;";
+ out << eb;
+ out << sp << nl << "public " << name << "Prx value;";
+ out << eb;
+ close();
+ }
+ }
+
+ return false;
+}
+
+bool
+Slice::Gen::HolderVisitor::visitStructStart(const StructPtr& p)
+{
+ writeHolder(p);
+ return false;
+}
+
+void
+Slice::Gen::HolderVisitor::visitSequence(const SequencePtr& p)
+{
+ writeHolder(p);
+}
+
+void
+Slice::Gen::HolderVisitor::visitDictionary(const DictionaryPtr& p)
+{
+ writeHolder(p);
+}
+
+void
+Slice::Gen::HolderVisitor::visitEnum(const EnumPtr& p)
+{
+ writeHolder(p);
+}
+
+void
+Slice::Gen::HolderVisitor::writeHolder(const TypePtr& p)
+{
+ ContainedPtr contained = ContainedPtr::dynamicCast(p);
+ assert(contained);
+ string name = contained->name();
+ string absolute = getAbsolute(contained, "", "", "Holder");
+
+ if(open(absolute))
+ {
+ Output& out = output();
+ string typeS = typeToString(p, TypeModeIn, getPackage(contained));
+ out << sp << nl << "public final class " << name << "Holder";
+ out << sb;
+ out << sp << nl << "public" << nl << name << "Holder()";
+ out << sb;
+ out << eb;
+ out << sp << nl << "public" << nl << name << "Holder(" << typeS << " value)";
+ out << sb;
+ out << nl << "this.value = value;";
+ out << eb;
+ if(!p->isLocal())
+ {
+ BuiltinPtr builtin = BuiltinPtr::dynamicCast(p);
+ if((builtin && builtin->kind() == Builtin::KindObject) || ClassDeclPtr::dynamicCast(p))
+ {
+ out << sp << nl << "public class Patcher implements IceInternal.Patcher";
+ if(_stream)
+ {
+ out << ", Ice.ReadObjectCallback";
+ }
+ out << sb;
+ out << nl << "public void";
+ out << nl << "patch(Ice.Object v)";
+ out << sb;
+ out << nl << "value = (" << typeS << ")v;";
+ out << eb;
+
+ out << sp << nl << "public String" << nl << "type()";
+ out << sb;
+ out << nl << "return \"" << p->typeId() << "\";";
+ out << eb;
+
+ if(_stream)
+ {
+ out << sp << nl << "public void" << nl << "invoke(Ice.Object v)";
+ out << sb;
+ out << nl << "patch(v);";
+ out << eb;
+ }
+ out << eb;
+
+ out << sp << nl << "public Patcher";
+ out << nl << "getPatcher()";
+ out << sb;
+ out << nl << "return new Patcher();";
+ out << eb;
+ }
+ }
+ out << sp << nl << "public " << typeS << " value;";
+ out << eb;
+ close();
+ }
+}
+
+Slice::Gen::HelperVisitor::HelperVisitor(const string& dir, bool stream) :
+ JavaVisitor(dir), _stream(stream)
+{
+}
+
+bool
+Slice::Gen::HelperVisitor::visitClassDefStart(const ClassDefPtr& p)
+{
+ if(p->isLocal())
+ {
+ return false;
+ }
+
+ //
+ // Proxy helper
+ //
+ string name = p->name();
+ string scoped = p->scoped();
+ ClassList bases = p->bases();
+ string package = getPackage(p);
+ string absolute = getAbsolute(p);
+
+ if(!open(getAbsolute(p, "", "", "PrxHelper")))
+ {
+ return false;
+ }
+
+ Output& out = output();
+
+ //
+ // A proxy helper class serves two purposes: it implements the
+ // proxy interface, and provides static helper methods for use
+ // by applications (e.g., checkedCast, etc.)
+ //
+ out << sp << nl << "public final class " << name << "PrxHelper extends Ice.ObjectPrxHelperBase implements " << name
+ << "Prx";
+
+ out << sb;
+
+ OperationList ops = p->allOperations();
+
+ OperationList::const_iterator r;
+ for(r = ops.begin(); r != ops.end(); ++r)
+ {
+ OperationPtr op = *r;
+ ContainerPtr container = op->container();
+ ClassDefPtr cl = ClassDefPtr::dynamicCast(container);
+ string opName = fixKwd(op->name());
+ TypePtr ret = op->returnType();
+ string retS = typeToString(ret, TypeModeReturn, package, op->getMetaData());
+
+ vector<string> params = getParams(op, package);
+ vector<string> args = getArgs(op);
+
+ ExceptionList throws = op->throws();
+ throws.sort();
+ throws.unique();
+
+ //
+ // Write two versions of the operation - with and without a
+ // context parameter
+ //
+ out << sp;
+ out << nl << "public " << retS << nl << opName << spar << params << epar;
+ writeThrowsClause(package, throws);
+ out << sb;
+ out << nl;
+ if(ret)
+ {
+ out << "return ";
+ }
+ out << opName << spar << args << "__defaultContext()" << epar << ';';
+ out << eb;
+
+ out << sp;
+ out << nl << "public " << retS << nl << opName << spar << params << "java.util.Map __ctx" << epar;
+ writeThrowsClause(package, throws);
+ out << sb;
+ out << nl << "int __cnt = 0;";
+ out << nl << "while(true)";
+ out << sb;
+ out << nl << "try";
+ out << sb;
+ if(op->returnsData())
+ {
+ out << nl << "__checkTwowayOnly(\"" << opName << "\");";
+ }
+ out << nl << "Ice._ObjectDel __delBase = __getDelegate();";
+ out << nl << '_' << name << "Del __del = (_" << name << "Del)__delBase;";
+ out << nl;
+ if(ret)
+ {
+ out << "return ";
+ }
+ out << "__del." << opName << spar << args << "__ctx" << epar << ';';
+ if(!ret)
+ {
+ out << nl << "return;";
+ }
+ out << eb;
+ out << nl << "catch(IceInternal.NonRepeatable __ex)";
+ out << sb;
+ if(op->mode() == Operation::Idempotent || op->mode() == Operation::Nonmutating)
+ {
+ out << nl << "__cnt = __handleException(__ex.get(), __cnt);";
+ }
+ else
+ {
+ out << nl << "__rethrowException(__ex.get());";
+ }
+ out << eb;
+ out << nl << "catch(Ice.LocalException __ex)";
+ out << sb;
+ out << nl << "__cnt = __handleException(__ex, __cnt);";
+ out << eb;
+ out << eb;
+ out << eb;
+
+ if(cl->hasMetaData("ami") || op->hasMetaData("ami"))
+ {
+ vector<string> paramsAMI = getParamsAsync(op, package, false);
+ vector<string> argsAMI = getArgsAsync(op);
+
+ //
+ // Write two versions of the operation - with and without a
+ // context parameter
+ //
+ out << sp;
+ out << nl << "public void" << nl << op->name() << "_async" << spar << paramsAMI << epar;
+ out << sb;
+ out << nl << op->name() << "_async" << spar << argsAMI << "__defaultContext()" << epar << ';';
+ out << eb;
+
+ out << sp;
+ out << nl << "public void" << nl << op->name() << "_async" << spar << paramsAMI << "java.util.Map __ctx"
+ << epar;
+ out << sb;
+ // Async requests may only be sent twoway.
+ out << nl << "__checkTwowayOnly(\"" << p->name() << "\");";
+ out << nl << "__cb.__invoke" << spar << "this" << argsAMI << "__ctx" << epar << ';';
+ out << eb;
+ }
+ }
+
+ out << sp << nl << "public static " << name << "Prx" << nl << "checkedCast(Ice.ObjectPrx b)";
+ out << sb;
+ out << nl << name << "Prx d = null;";
+ out << nl << "if(b != null)";
+ out << sb;
+ out << nl << "try";
+ out << sb;
+ out << nl << "d = (" << name << "Prx)b;";
+ out << eb;
+ out << nl << "catch(ClassCastException ex)";
+ out << sb;
+ out << nl << "if(b.ice_isA(\"" << scoped << "\"))";
+ out << sb;
+ out << nl << name << "PrxHelper h = new " << name << "PrxHelper();";
+ out << nl << "h.__copyFrom(b);";
+ out << nl << "d = h;";
+ out << eb;
+ out << eb;
+ out << eb;
+ out << nl << "return d;";
+ out << eb;
+
+ out << sp << nl << "public static " << name << "Prx" << nl << "checkedCast(Ice.ObjectPrx b, java.util.Map ctx)";
+ out << sb;
+ out << nl << name << "Prx d = null;";
+ out << nl << "if(b != null)";
+ out << sb;
+ out << nl << "try";
+ out << sb;
+ out << nl << "d = (" << name << "Prx)b;";
+ out << eb;
+ out << nl << "catch(ClassCastException ex)";
+ out << sb;
+ out << nl << "if(b.ice_isA(\"" << scoped << "\", ctx))";
+ out << sb;
+ out << nl << name << "PrxHelper h = new " << name << "PrxHelper();";
+ out << nl << "h.__copyFrom(b);";
+ out << nl << "d = h;";
+ out << eb;
+ out << eb;
+ out << eb;
+ out << nl << "return d;";
+ out << eb;
+
+ out << sp << nl << "public static " << name << "Prx" << nl << "checkedCast(Ice.ObjectPrx b, String f)";
+ out << sb;
+ out << nl << name << "Prx d = null;";
+ out << nl << "if(b != null)";
+ out << sb;
+ out << nl << "Ice.ObjectPrx bb = b.ice_newFacet(f);";
+ out << nl << "try";
+ out << sb;
+ out << nl << "if(bb.ice_isA(\"" << scoped << "\"))";
+ out << sb;
+ out << nl << name << "PrxHelper h = new " << name << "PrxHelper();";
+ out << nl << "h.__copyFrom(bb);";
+ out << nl << "d = h;";
+ out << eb;
+ out << eb;
+ out << nl << "catch(Ice.FacetNotExistException ex)";
+ out << sb;
+ out << eb;
+ out << eb;
+ out << nl << "return d;";
+ out << eb;
+
+ out << sp << nl << "public static " << name << "Prx"
+ << nl << "checkedCast(Ice.ObjectPrx b, String f, java.util.Map ctx)";
+ out << sb;
+ out << nl << name << "Prx d = null;";
+ out << nl << "if(b != null)";
+ out << sb;
+ out << nl << "Ice.ObjectPrx bb = b.ice_newFacet(f);";
+ out << nl << "try";
+ out << sb;
+ out << nl << "if(bb.ice_isA(\"" << scoped << "\", ctx))";
+ out << sb;
+ out << nl << name << "PrxHelper h = new " << name << "PrxHelper();";
+ out << nl << "h.__copyFrom(bb);";
+ out << nl << "d = h;";
+ out << eb;
+ out << eb;
+ out << nl << "catch(Ice.FacetNotExistException ex)";
+ out << sb;
+ out << eb;
+ out << eb;
+ out << nl << "return d;";
+ out << eb;
+
+ out << sp << nl << "public static " << name << "Prx" << nl << "uncheckedCast(Ice.ObjectPrx b)";
+ out << sb;
+ out << nl << name << "Prx d = null;";
+ out << nl << "if(b != null)";
+ out << sb;
+ out << nl << name << "PrxHelper h = new " << name << "PrxHelper();";
+ out << nl << "h.__copyFrom(b);";
+ out << nl << "d = h;";
+ out << eb;
+ out << nl << "return d;";
+ out << eb;
+
+ out << sp << nl << "public static " << name << "Prx" << nl << "uncheckedCast(Ice.ObjectPrx b, String f)";
+ out << sb;
+ out << nl << name << "Prx d = null;";
+ out << nl << "if(b != null)";
+ out << sb;
+ out << nl << "Ice.ObjectPrx bb = b.ice_newFacet(f);";
+ out << nl << name << "PrxHelper h = new " << name << "PrxHelper();";
+ out << nl << "h.__copyFrom(bb);";
+ out << nl << "d = h;";
+ out << eb;
+ out << nl << "return d;";
+ out << eb;
+
+ out << sp << nl << "protected Ice._ObjectDelM" << nl << "__createDelegateM()";
+ out << sb;
+ out << nl << "return new _" << name << "DelM();";
+ out << eb;
+
+ out << sp << nl << "protected Ice._ObjectDelD" << nl << "__createDelegateD()";
+ out << sb;
+ out << nl << "return new _" << name << "DelD();";
+ out << eb;
+
+ out << sp << nl << "public static void" << nl << "__write(IceInternal.BasicStream __os, " << name << "Prx v)";
+ out << sb;
+ out << nl << "__os.writeProxy(v);";
+ out << eb;
+
+ out << sp << nl << "public static " << name << "Prx" << nl << "__read(IceInternal.BasicStream __is)";
+ out << sb;
+ out << nl << "Ice.ObjectPrx proxy = __is.readProxy();";
+ out << nl << "if(proxy != null)";
+ out << sb;
+ out << nl << name << "PrxHelper result = new " << name << "PrxHelper();";
+ out << nl << "result.__copyFrom(proxy);";
+ out << nl << "return result;";
+ out << eb;
+ out << nl << "return null;";
+ out << eb;
+
+ if(_stream)
+ {
+ out << sp << nl << "public static void" << nl << "write(Ice.OutputStream __out, " << name << "Prx v)";
+ out << sb;
+ out << nl << "__out.writeProxy(v);";
+ out << eb;
+
+ out << sp << nl << "public static " << name << "Prx" << nl << "read(Ice.InputStream __in)";
+ out << sb;
+ out << nl << "Ice.ObjectPrx proxy = __in.readProxy();";
+ out << nl << "if(proxy != null)";
+ out << sb;
+ out << nl << name << "PrxHelper result = new " << name << "PrxHelper();";
+ out << nl << "result.__copyFrom(proxy);";
+ out << nl << "return result;";
+ out << eb;
+ out << nl << "return null;";
+ out << eb;
+ }
+
+ out << eb;
+ close();
+
+ if(_stream)
+ {
+ //
+ // Class helper.
+ //
+ if(!open(getAbsolute(p, "", "", "Helper")))
+ {
+ return false;
+ }
+
+ Output& out2 = output();
+
+ out2 << sp << nl << "public final class " << name << "Helper";
+ out2 << sb;
+
+ out2 << sp << nl << "public static void" << nl << "write(Ice.OutputStream __out, " << fixKwd(name) << " __v)";
+ out2 << sb;
+ out2 << nl << "__out.writeObject(__v);";
+ out2 << eb;
+
+ out2 << sp << nl << "public static void" << nl << "read(Ice.InputStream __in, " << name << "Holder __h)";
+ out2 << sb;
+ out2 << nl << "__in.readObject(__h.getPatcher());";
+ out2 << eb;
+
+ out2 << eb;
+ close();
+ }
+
+ return false;
+}
+
+bool
+Slice::Gen::HelperVisitor::visitStructStart(const StructPtr& p)
+{
+ if(!p->isLocal() && _stream)
+ {
+ string name = p->name();
+ string fixedName = fixKwd(name);
+
+ if(!open(getAbsolute(p, "", "", "Helper")))
+ {
+ return false;
+ }
+
+ Output& out = output();
+
+ out << sp << nl << "public final class " << name << "Helper";
+ out << sb;
+
+ out << sp << nl << "public static void" << nl << "write(Ice.OutputStream __out, " << fixedName << " __v)";
+ out << sb;
+ out << nl << "__v.__write(__out);";
+ out << eb;
+
+ out << sp << nl << "public static " << fixedName << nl << "read(Ice.InputStream __in)";
+ out << sb;
+ out << nl << fixedName << " __v = new " << fixedName << "();";
+ out << nl << "__v.__read(__in);";
+ out << nl << "return __v;";
+ out << eb;
+
+ out << eb;
+ close();
+ }
+
+ return false;
+}
+
+void
+Slice::Gen::HelperVisitor::visitSequence(const SequencePtr& p)
+{
+ //
+ // Don't generate helper for a sequence of a local type.
+ //
+ if(p->isLocal())
+ {
+ return;
+ }
+
+ string name = p->name();
+ string absolute = getAbsolute(p);
+ string helper = getAbsolute(p, "", "", "Helper");
+ string package = getPackage(p);
+ string typeS = typeToString(p, TypeModeIn, package);
+
+ if(open(helper))
+ {
+ Output& out = output();
+ int iter;
+
+ out << sp << nl << "public final class " << name << "Helper";
+ out << sb;
+
+ out << nl << "public static void" << nl << "write(IceInternal.BasicStream __os, " << typeS << " __v)";
+ out << sb;
+ iter = 0;
+ writeSequenceMarshalUnmarshalCode(out, package, p, "__v", true, iter, false);
+ out << eb;
+
+ out << sp << nl << "public static " << typeS << nl << "read(IceInternal.BasicStream __is)";
+ out << sb;
+ out << nl << typeS << " __v;";
+ iter = 0;
+ writeSequenceMarshalUnmarshalCode(out, package, p, "__v", false, iter, false);
+ out << nl << "return __v;";
+ out << eb;
+
+ if(_stream)
+ {
+ out << sp << nl << "public static void" << nl << "write(Ice.OutputStream __out, " << typeS << " __v)";
+ out << sb;
+ iter = 0;
+ writeStreamSequenceMarshalUnmarshalCode(out, package, p, "__v", true, iter, false);
+ out << eb;
+
+ out << sp << nl << "public static " << typeS << nl << "read(Ice.InputStream __in)";
+ out << sb;
+ out << nl << typeS << " __v;";
+ iter = 0;
+ writeStreamSequenceMarshalUnmarshalCode(out, package, p, "__v", false, iter, false);
+ out << nl << "return __v;";
+ out << eb;
+ }
+
+ out << eb;
+ close();
+ }
+}
+
+void
+Slice::Gen::HelperVisitor::visitDictionary(const DictionaryPtr& p)
+{
+ //
+ // Don't generate helper for a dictionary containing a local type
+ //
+ if(p->isLocal())
+ {
+ return;
+ }
+
+ TypePtr key = p->keyType();
+ TypePtr value = p->valueType();
+
+ string absolute = getAbsolute(p);
+ string helper = getAbsolute(p, "", "", "Helper");
+
+ if(open(helper))
+ {
+ Output& out = output();
+ string name = p->name();
+ string package = getPackage(p);
+ string keyS = typeToString(key, TypeModeIn, package);
+ string valueS = typeToString(value, TypeModeIn, package);
+ StringList metaData = p->getMetaData();
+ string dictType = findMetaData(metaData);
+ int iter;
+ int i;
+
+ out << sp << nl << "public final class " << name << "Helper";
+ out << sb;
+
+ out << nl << "public static void" << nl << "write(IceInternal.BasicStream __os, " << "java.util.Map __v)";
+ out << sb;
+ out << nl << "if(__v == null)";
+ out << sb;
+ out << nl << "__os.writeSize(0);";
+ out << eb;
+ out << nl << "else";
+ out << sb;
+ out << nl << "__os.writeSize(__v.size());";
+ out << nl << "java.util.Iterator __i = __v.entrySet().iterator();";
+ out << nl << "while(__i.hasNext())";
+ out << sb;
+ out << nl << "java.util.Map.Entry __e = (java.util.Map.Entry)" << "__i.next();";
+ iter = 0;
+ for(i = 0; i < 2; i++)
+ {
+ string val;
+ string arg;
+ TypePtr type;
+ if(i == 0)
+ {
+ arg = "__e.getKey()";
+ type = key;
+ }
+ else
+ {
+ arg = "__e.getValue()";
+ type = value;
+ }
+
+ BuiltinPtr b = BuiltinPtr::dynamicCast(type);
+ if(b)
+ {
+ switch(b->kind())
+ {
+ case Builtin::KindByte:
+ {
+ val = "((java.lang.Byte)" + arg + ").byteValue()";
+ break;
+ }
+ case Builtin::KindBool:
+ {
+ val = "((java.lang.Boolean)" + arg + ").booleanValue()";
+ break;
+ }
+ case Builtin::KindShort:
+ {
+ val = "((java.lang.Short)" + arg + ").shortValue()";
+ break;
+ }
+ case Builtin::KindInt:
+ {
+ val = "((java.lang.Integer)" + arg + ").intValue()";
+ break;
+ }
+ case Builtin::KindLong:
+ {
+ val = "((java.lang.Long)" + arg + ").longValue()";
+ break;
+ }
+ case Builtin::KindFloat:
+ {
+ val = "((java.lang.Float)" + arg + ").floatValue()";
+ break;
+ }
+ case Builtin::KindDouble:
+ {
+ val = "((java.lang.Double)" + arg + ").doubleValue()";
+ break;
+ }
+ case Builtin::KindString:
+ case Builtin::KindObject:
+ case Builtin::KindObjectProxy:
+ {
+ break;
+ }
+ case Builtin::KindLocalObject:
+ {
+ assert(false);
+ break;
+ }
+ }
+ }
+
+ if(val.empty())
+ {
+ val = "((" + typeToString(type, TypeModeIn, package) + ')' + arg + ')';
+ }
+ writeMarshalUnmarshalCode(out, package, type, val, true, iter, false);
+ }
+ out << eb;
+ out << eb;
+ out << eb;
+
+ BuiltinPtr builtin = BuiltinPtr::dynamicCast(value);
+ if((builtin && builtin->kind() == Builtin::KindObject) || ClassDeclPtr::dynamicCast(value))
+ {
+ //
+ // The dictionary uses class values.
+ //
+ out << sp << nl << "private static class Patcher implements IceInternal.Patcher";
+ if(_stream)
+ {
+ out << ", Ice.ReadObjectCallback";
+ }
+ out << sb;
+ string keyTypeS = keyS;
+ BuiltinPtr b = BuiltinPtr::dynamicCast(key);
+ if(b)
+ {
+ switch(b->kind())
+ {
+ case Builtin::KindByte:
+ {
+ keyTypeS = "java.lang.Byte";
+ break;
+ }
+ case Builtin::KindBool:
+ {
+ keyTypeS = "java.lang.Boolean";
+ break;
+ }
+ case Builtin::KindShort:
+ {
+ keyTypeS = "java.lang.Short";
+ break;
+ }
+ case Builtin::KindInt:
+ {
+ keyTypeS = "java.lang.Integer";
+ break;
+ }
+ case Builtin::KindLong:
+ {
+ keyTypeS = "java.lang.Long";
+ break;
+ }
+ case Builtin::KindFloat:
+ {
+ keyTypeS = "java.lang.Float";
+ break;
+ }
+ case Builtin::KindDouble:
+ {
+ keyTypeS = "java.lang.Double";
+ break;
+ }
+ default:
+ {
+ break; // Do nothing
+ }
+ }
+ }
+ out << sp << nl << "Patcher(java.util.Map m, " << keyTypeS << " key)";
+ out << sb;
+ out << nl << "__m = m;";
+ out << nl << "__key = key;";
+ out << eb;
+
+ out << sp << nl << "public void" << nl << "patch(Ice.Object v)";
+ out << sb;
+ out << nl << valueS << " _v = (" << valueS << ")v;";
+ out << nl << "__m.put(__key, v);";
+ out << eb;
+
+ out << sp << nl << "public String" << nl << "type()";
+ out << sb;
+ out << nl << "return \"" << value->typeId() << "\";";
+ out << eb;
+
+ if(_stream)
+ {
+ out << sp << nl << "public void" << nl << "invoke(Ice.Object v)";
+ out << sb;
+ out << nl << "patch(v);";
+ out << eb;
+ }
+
+ out << sp << nl << "private java.util.Map __m;";
+ out << nl << "private " << keyTypeS << " __key;";
+ out << eb;
+ }
+
+ out << sp << nl << "public static " << (dictType.empty() ? "java.util.Map" : dictType);
+ out << nl << "read(IceInternal.BasicStream __is)";
+ out << sb;
+ out << nl << "int __sz = __is.readSize();";
+ out << nl << (dictType.empty() ? "java.util.Map" : dictType) << " __r = new "
+ << (dictType.empty() ? "java.util.HashMap(__sz)" : dictType + "()") << ';';
+ out << nl << "for(int __i = 0; __i < __sz; __i++)";
+ out << sb;
+ iter = 0;
+ for(i = 0; i < 2; i++)
+ {
+ string arg;
+ TypePtr type;
+ if(i == 0)
+ {
+ arg = "__key";
+ type = key;
+ }
+ else
+ {
+ arg = "__value";
+ type = value;
+ }
+
+ BuiltinPtr b = BuiltinPtr::dynamicCast(type);
+ if(b)
+ {
+ switch(b->kind())
+ {
+ case Builtin::KindByte:
+ {
+ out << nl << "java.lang.Byte " << arg << " = new java.lang.Byte(__is.readByte());";
+ break;
+ }
+ case Builtin::KindBool:
+ {
+ out << nl << "java.lang.Boolean " << arg << " = new java.lang.Boolean(__is.readBool());";
+ break;
+ }
+ case Builtin::KindShort:
+ {
+ out << nl << "java.lang.Short " << arg << " = new java.lang.Short(__is.readShort());";
+ break;
+ }
+ case Builtin::KindInt:
+ {
+ out << nl << "java.lang.Integer " << arg << " = new java.lang.Integer(__is.readInt());";
+ break;
+ }
+ case Builtin::KindLong:
+ {
+ out << nl << "java.lang.Long " << arg << " = new java.lang.Long(__is.readLong());";
+ break;
+ }
+ case Builtin::KindFloat:
+ {
+ out << nl << "java.lang.Float " << arg << " = new java.lang.Float(__is.readFloat());";
+ break;
+ }
+ case Builtin::KindDouble:
+ {
+ out << nl << "java.lang.Double " << arg << " = new java.lang.Double(__is.readDouble());";
+ break;
+ }
+ case Builtin::KindString:
+ {
+ out << nl << "java.lang.String " << arg << " = __is.readString();";
+ break;
+ }
+ case Builtin::KindObject:
+ {
+ out << nl << "__is.readObject(new Patcher(__r, __key));";
+ break;
+ }
+ case Builtin::KindObjectProxy:
+ {
+ out << nl << "Ice.ObjectPrx " << arg << " = __is.readProxy();";
+ break;
+ }
+ case Builtin::KindLocalObject:
+ {
+ assert(false);
+ break;
+ }
+ }
+ }
+ else
+ {
+ string s = typeToString(type, TypeModeIn, package);
+ BuiltinPtr builtin2 = BuiltinPtr::dynamicCast(type);
+ if((builtin2 && builtin2->kind() == Builtin::KindObject) || ClassDeclPtr::dynamicCast(type))
+ {
+ writeMarshalUnmarshalCode(out, package, type, arg, false, iter, false, StringList(),
+ "new Patcher(__r, __key)");
+ }
+ else
+ {
+ out << nl << s << ' ' << arg << ';';
+ writeMarshalUnmarshalCode(out, package, type, arg, false, iter, false);
+ }
+ }
+ }
+ if(!(builtin && builtin->kind() == Builtin::KindObject) && !ClassDeclPtr::dynamicCast(value))
+ {
+ out << nl << "__r.put(__key, __value);";
+ }
+ out << eb;
+ out << nl << "return __r;";
+ out << eb;
+
+ if(_stream)
+ {
+ out << sp << nl << "public static void" << nl << "write(Ice.OutputStream __out, " << "java.util.Map __v)";
+ out << sb;
+ out << nl << "if(__v == null)";
+ out << sb;
+ out << nl << "__out.writeSize(0);";
+ out << eb;
+ out << nl << "else";
+ out << sb;
+ out << nl << "__out.writeSize(__v.size());";
+ out << nl << "java.util.Iterator __i = __v.entrySet().iterator();";
+ out << nl << "while(__i.hasNext())";
+ out << sb;
+ out << nl << "java.util.Map.Entry __e = (java.util.Map.Entry)" << "__i.next();";
+ iter = 0;
+ for(i = 0; i < 2; i++)
+ {
+ string val;
+ string arg;
+ TypePtr type;
+ if(i == 0)
+ {
+ arg = "__e.getKey()";
+ type = key;
+ }
+ else
+ {
+ arg = "__e.getValue()";
+ type = value;
+ }
+
+ BuiltinPtr b = BuiltinPtr::dynamicCast(type);
+ if(b)
+ {
+ switch(b->kind())
+ {
+ case Builtin::KindByte:
+ {
+ val = "((java.lang.Byte)" + arg + ").byteValue()";
+ break;
+ }
+ case Builtin::KindBool:
+ {
+ val = "((java.lang.Boolean)" + arg + ").booleanValue()";
+ break;
+ }
+ case Builtin::KindShort:
+ {
+ val = "((java.lang.Short)" + arg + ").shortValue()";
+ break;
+ }
+ case Builtin::KindInt:
+ {
+ val = "((java.lang.Integer)" + arg + ").intValue()";
+ break;
+ }
+ case Builtin::KindLong:
+ {
+ val = "((java.lang.Long)" + arg + ").longValue()";
+ break;
+ }
+ case Builtin::KindFloat:
+ {
+ val = "((java.lang.Float)" + arg + ").floatValue()";
+ break;
+ }
+ case Builtin::KindDouble:
+ {
+ val = "((java.lang.Double)" + arg + ").doubleValue()";
+ break;
+ }
+ case Builtin::KindString:
+ case Builtin::KindObject:
+ case Builtin::KindObjectProxy:
+ {
+ break;
+ }
+ case Builtin::KindLocalObject:
+ {
+ assert(false);
+ break;
+ }
+ }
+ }
+
+ if(val.empty())
+ {
+ val = "((" + typeToString(type, TypeModeIn, package) + ')' + arg + ')';
+ }
+ writeStreamMarshalUnmarshalCode(out, package, type, val, true, iter, false);
+ }
+ out << eb;
+ out << eb;
+ out << eb;
+
+ out << sp << nl << "public static " << (dictType.empty() ? "java.util.Map" : dictType)
+ << nl << "read(Ice.InputStream __in)";
+ out << sb;
+ out << nl << "int __sz = __in.readSize();";
+ out << nl << (dictType.empty() ? "java.util.Map" : dictType) << " __r = new "
+ << (dictType.empty() ? "java.util.HashMap(__sz)" : dictType + "()") << ';';
+ out << nl << "for(int __i = 0; __i < __sz; __i++)";
+ out << sb;
+ iter = 0;
+ for(i = 0; i < 2; i++)
+ {
+ string arg;
+ TypePtr type;
+ if(i == 0)
+ {
+ arg = "__key";
+ type = key;
+ }
+ else
+ {
+ arg = "__value";
+ type = value;
+ }
+
+ BuiltinPtr b = BuiltinPtr::dynamicCast(type);
+ if(b)
+ {
+ switch(b->kind())
+ {
+ case Builtin::KindByte:
+ {
+ out << nl << "java.lang.Byte " << arg << " = new java.lang.Byte(__in.readByte());";
+ break;
+ }
+ case Builtin::KindBool:
+ {
+ out << nl << "java.lang.Boolean " << arg << " = new java.lang.Boolean(__in.readBool());";
+ break;
+ }
+ case Builtin::KindShort:
+ {
+ out << nl << "java.lang.Short " << arg << " = new java.lang.Short(__in.readShort());";
+ break;
+ }
+ case Builtin::KindInt:
+ {
+ out << nl << "java.lang.Integer " << arg << " = new java.lang.Integer(__in.readInt());";
+ break;
+ }
+ case Builtin::KindLong:
+ {
+ out << nl << "java.lang.Long " << arg << " = new java.lang.Long(__in.readLong());";
+ break;
+ }
+ case Builtin::KindFloat:
+ {
+ out << nl << "java.lang.Float " << arg << " = new java.lang.Float(__in.readFloat());";
+ break;
+ }
+ case Builtin::KindDouble:
+ {
+ out << nl << "java.lang.Double " << arg << " = new java.lang.Double(__in.readDouble());";
+ break;
+ }
+ case Builtin::KindString:
+ {
+ out << nl << "java.lang.String " << arg << " = __in.readString();";
+ break;
+ }
+ case Builtin::KindObject:
+ {
+ out << nl << "__in.readObject(new Patcher(__r, __key));";
+ break;
+ }
+ case Builtin::KindObjectProxy:
+ {
+ out << nl << "Ice.ObjectPrx " << arg << " = __in.readProxy();";
+ break;
+ }
+ case Builtin::KindLocalObject:
+ {
+ assert(false);
+ break;
+ }
+ }
+ }
+ else
+ {
+ string s = typeToString(type, TypeModeIn, package);
+ BuiltinPtr builtin2 = BuiltinPtr::dynamicCast(type);
+ if((builtin2 && builtin2->kind() == Builtin::KindObject) || ClassDeclPtr::dynamicCast(type))
+ {
+ writeStreamMarshalUnmarshalCode(out, package, type, arg, false, iter, false, StringList(),
+ "new Patcher(__r, __key)");
+ }
+ else
+ {
+ out << nl << s << ' ' << arg << ';';
+ writeStreamMarshalUnmarshalCode(out, package, type, arg, false, iter, false);
+ }
+ }
+ }
+ if(!(builtin && builtin->kind() == Builtin::KindObject) && !ClassDeclPtr::dynamicCast(value))
+ {
+ out << nl << "__r.put(__key, __value);";
+ }
+ out << eb;
+ out << nl << "return __r;";
+ out << eb;
+ }
+
+ out << eb;
+ close();
+ }
+}
+
+void
+Slice::Gen::HelperVisitor::visitEnum(const EnumPtr& p)
+{
+ if(!p->isLocal() && _stream)
+ {
+ string name = p->name();
+ string fixedName = fixKwd(name);
+
+ if(!open(getAbsolute(p, "", "", "Helper")))
+ {
+ return;
+ }
+
+ Output& out = output();
+
+ out << sp << nl << "public final class " << name << "Helper";
+ out << sb;
+
+ out << sp << nl << "public static void" << nl << "write(Ice.OutputStream __out, " << fixedName << " __v)";
+ out << sb;
+ out << nl << "__v.__write(__out);";
+ out << eb;
+
+ out << sp << nl << "public static " << fixedName << nl << "read(Ice.InputStream __in)";
+ out << sb;
+ out << nl << "return " << fixedName << ".__read(__in);";
+ out << eb;
+
+ out << eb;
+ close();
+ }
+}
+
+Slice::Gen::ProxyVisitor::ProxyVisitor(const string& dir) :
+ JavaVisitor(dir)
+{
+}
+
+bool
+Slice::Gen::ProxyVisitor::visitClassDefStart(const ClassDefPtr& p)
+{
+ if(p->isLocal())
+ {
+ return false;
+ }
+
+ string name = p->name();
+ ClassList bases = p->bases();
+ string package = getPackage(p);
+ string absolute = getAbsolute(p, "", "", "Prx");
+
+ if(!open(absolute))
+ {
+ return false;
+ }
+
+ Output& out = output();
+
+ //
+ // Generate a Java interface as the user-visible type
+ //
+ out << sp << nl << "public interface " << name << "Prx extends ";
+ if(bases.empty())
+ {
+ out << "Ice.ObjectPrx";
+ }
+ else
+ {
+ out.useCurrentPosAsIndent();
+ ClassList::const_iterator q = bases.begin();
+ while(q != bases.end())
+ {
+ out << getAbsolute(*q, package, "", "Prx");
+ if(++q != bases.end())
+ {
+ out << ',' << nl;
+ }
+ }
+ out.restoreIndent();
+ }
+
+ out << sb;
+
+ return true;
+}
+
+void
+Slice::Gen::ProxyVisitor::visitClassDefEnd(const ClassDefPtr& p)
+{
+ Output& out = output();
+ out << eb;
+ close();
+}
+
+void
+Slice::Gen::ProxyVisitor::visitOperation(const OperationPtr& p)
+{
+ string name = fixKwd(p->name());
+ ContainerPtr container = p->container();
+ ClassDefPtr cl = ClassDefPtr::dynamicCast(container);
+ string package = getPackage(cl);
+
+ Output& out = output();
+
+ TypePtr ret = p->returnType();
+ string retS = typeToString(ret, TypeModeReturn, package, p->getMetaData());
+ vector<string> params = getParams(p, package);
+ ExceptionList throws = p->throws();
+ throws.sort();
+ throws.unique();
+
+ //
+ // Write two versions of the operation - with and without a
+ // context parameter.
+ //
+ out << sp;
+ out << nl << "public " << retS << ' ' << name << spar << params << epar;
+ writeThrowsClause(package, throws);
+ out << ';';
+ out << nl << "public " << retS << ' ' << name << spar << params << "java.util.Map __ctx" << epar;
+ writeThrowsClause(package, throws);
+ out << ';';
+
+ if(cl->hasMetaData("ami") || p->hasMetaData("ami"))
+ {
+ vector<string> paramsAMI = getParamsAsync(p, package, false);
+
+ //
+ // Write two versions of the operation - with and without a
+ // context parameter.
+ //
+ out << sp;
+ out << nl << "public void " << p->name() << "_async" << spar << paramsAMI << epar << ';';
+ out << nl << "public void " << p->name() << "_async" << spar << paramsAMI << "java.util.Map __ctx"
+ << epar << ';';
+ }
+}
+
+Slice::Gen::DelegateVisitor::DelegateVisitor(const string& dir) :
+ JavaVisitor(dir)
+{
+}
+
+bool
+Slice::Gen::DelegateVisitor::visitClassDefStart(const ClassDefPtr& p)
+{
+ if(p->isLocal())
+ {
+ return false;
+ }
+
+ string name = p->name();
+ ClassList bases = p->bases();
+ string package = getPackage(p);
+ string absolute = getAbsolute(p, "", "_", "Del");
+
+ if(!open(absolute))
+ {
+ return false;
+ }
+
+ Output& out = output();
+
+ out << sp << nl << "public interface _" << name << "Del extends ";
+ if(bases.empty())
+ {
+ out << "Ice._ObjectDel";
+ }
+ else
+ {
+ out.useCurrentPosAsIndent();
+ ClassList::const_iterator q = bases.begin();
+ while(q != bases.end())
+ {
+ out << getAbsolute(*q, package, "_", "Del");
+ if(++q != bases.end())
+ {
+ out << ',' << nl;
+ }
+ }
+ out.restoreIndent();
+ }
+
+ out << sb;
+
+ OperationList ops = p->operations();
+
+ OperationList::const_iterator r;
+ for(r = ops.begin(); r != ops.end(); ++r)
+ {
+ OperationPtr op = *r;
+ string opName = fixKwd(op->name());
+ TypePtr ret = op->returnType();
+ string retS = typeToString(ret, TypeModeReturn, package, op->getMetaData());
+
+ vector<string> params = getParams(op, package);
+
+ ExceptionList throws = op->throws();
+ throws.sort();
+ throws.unique();
+
+ out << sp;
+ out << nl << retS << ' ' << opName << spar << params << "java.util.Map __ctx" << epar;
+ writeDelegateThrowsClause(package, throws);
+ out << ';';
+ }
+
+ out << eb;
+ close();
+
+ return false;
+}
+
+Slice::Gen::DelegateMVisitor::DelegateMVisitor(const string& dir) :
+ JavaVisitor(dir)
+{
+}
+
+bool
+Slice::Gen::DelegateMVisitor::visitClassDefStart(const ClassDefPtr& p)
+{
+ if(p->isLocal())
+ {
+ return false;
+ }
+
+ string name = p->name();
+ ClassList bases = p->bases();
+ string package = getPackage(p);
+ string absolute = getAbsolute(p, "", "_", "DelM");
+
+ if(!open(absolute))
+ {
+ return false;
+ }
+
+ Output& out = output();
+
+ out << sp << nl << "public final class _" << name << "DelM extends Ice._ObjectDelM implements _" << name << "Del";
+ out << sb;
+
+ OperationList ops = p->allOperations();
+
+ OperationList::const_iterator r;
+ for(r = ops.begin(); r != ops.end(); ++r)
+ {
+ OperationPtr op = *r;
+ StringList opMetaData = op->getMetaData();
+ string opName = fixKwd(op->name());
+ TypePtr ret = op->returnType();
+ string retS = typeToString(ret, TypeModeReturn, package, opMetaData);
+ int iter;
+
+ ParamDeclList inParams;
+ ParamDeclList outParams;
+ ParamDeclList paramList = op->parameters();
+ ParamDeclList::const_iterator pli;
+ for(pli = paramList.begin(); pli != paramList.end(); ++pli)
+ {
+ if((*pli)->isOutParam())
+ {
+ outParams.push_back(*pli);
+ }
+ else
+ {
+ inParams.push_back(*pli);
+ }
+ }
+
+ ExceptionList throws = op->throws();
+ throws.sort();
+ throws.unique();
+
+ //
+ // Arrange exceptions into most-derived to least-derived order. If we don't
+ // do this, a base exception handler can appear before a derived exception
+ // handler, causing compiler warnings and resulting in the base exception
+ // being marshaled instead of the derived exception.
+ //
+#if defined(__SUNPRO_CC)
+ throws.sort(Slice::derivedToBaseCompare);
+#else
+ throws.sort(Slice::DerivedToBaseCompare());
+#endif
+
+ vector<string> params = getParams(op, package);
+
+ out << sp;
+ out << nl << "public " << retS << nl << opName << spar << params << "java.util.Map __ctx" << epar;
+ writeDelegateThrowsClause(package, throws);
+ out << sb;
+
+ out << nl << "IceInternal.Outgoing __out = getOutgoing(\"" << op->name() << "\", " << sliceModeToIceMode(op)
+ << ", __ctx);";
+ out << nl << "try";
+ out << sb;
+ if(!inParams.empty())
+ {
+ out << nl << "try";
+ out << sb;
+ out << nl << "IceInternal.BasicStream __os = __out.os();";
+ iter = 0;
+ for(pli = inParams.begin(); pli != inParams.end(); ++pli)
+ {
+ writeMarshalUnmarshalCode(out, package, (*pli)->type(), fixKwd((*pli)->name()), true, iter, false,
+ (*pli)->getMetaData());
+ }
+ if(op->sendsClasses())
+ {
+ out << nl << "__os.writePendingObjects();";
+ }
+ out << eb;
+ out << nl << "catch(Ice.LocalException __ex)";
+ out << sb;
+ out << nl << "__out.abort(__ex);";
+ out << eb;
+ }
+ out << nl << "boolean __ok = __out.invoke();";
+ out << nl << "try";
+ out << sb;
+ out << nl << "IceInternal.BasicStream __is = __out.is();";
+ out << nl << "if(!__ok)";
+ out << sb;
+ out << nl << "try";
+ out << sb;
+ out << nl << "__is.throwException();";
+ out << eb;
+ for(ExceptionList::const_iterator t = throws.begin(); t != throws.end(); ++t)
+ {
+ out << nl << "catch(" << getAbsolute(*t, package) << " __ex)";
+ out << sb;
+ out << nl << "throw __ex;";
+ out << eb;
+ }
+ out << nl << "catch(Ice.UserException __ex)";
+ out << sb;
+ out << nl << "throw new Ice.UnknownUserException();";
+ out << eb;
+ out << eb;
+ for(pli = outParams.begin(); pli != outParams.end(); ++pli)
+ {
+ writeMarshalUnmarshalCode(out, package, (*pli)->type(), fixKwd((*pli)->name()), false, iter, true,
+ (*pli)->getMetaData());
+ }
+ if(ret)
+ {
+ BuiltinPtr builtin = BuiltinPtr::dynamicCast(ret);
+ if((builtin && builtin->kind() == Builtin::KindObject) || ClassDeclPtr::dynamicCast(ret))
+ {
+ out << nl << retS << "Holder __ret = new " << retS << "Holder();";
+ out << nl << "__is.readObject(__ret.getPatcher());";
+ }
+ else
+ {
+ out << nl << retS << " __ret;";
+ writeMarshalUnmarshalCode(out, package, ret, "__ret", false, iter, false, opMetaData);
+ }
+ }
+ if(op->returnsClasses())
+ {
+ out << nl << "__is.readPendingObjects();";
+ }
+ if(ret)
+ {
+ BuiltinPtr builtin = BuiltinPtr::dynamicCast(ret);
+ if((builtin && builtin->kind() == Builtin::KindObject) || ClassDeclPtr::dynamicCast(ret))
+ {
+ out << nl << "return __ret.value;";
+ }
+ else
+ {
+ out << nl << "return __ret;";
+ }
+ }
+ out << eb;
+ out << nl << "catch(Ice.LocalException __ex)";
+ out << sb;
+ out << nl << "throw new IceInternal.NonRepeatable(__ex);";
+ out << eb;
+ out << eb;
+ out << nl << "finally";
+ out << sb;
+ out << nl << "reclaimOutgoing(__out);";
+ out << eb;
+ out << eb;
+ }
+
+ out << eb;
+ close();
+
+ return false;
+}
+
+Slice::Gen::DelegateDVisitor::DelegateDVisitor(const string& dir) :
+ JavaVisitor(dir)
+{
+}
+
+bool
+Slice::Gen::DelegateDVisitor::visitClassDefStart(const ClassDefPtr& p)
+{
+ if(p->isLocal())
+ {
+ return false;
+ }
+
+ string name = p->name();
+ ClassList bases = p->bases();
+ string package = getPackage(p);
+ string absolute = getAbsolute(p, "", "_", "DelD");
+
+ if(!open(absolute))
+ {
+ return false;
+ }
+
+ Output& out = output();
+
+ out << sp << nl << "public final class _" << name << "DelD extends Ice._ObjectDelD implements _" << name << "Del";
+ out << sb;
+
+ OperationList ops = p->allOperations();
+
+ OperationList::const_iterator r;
+ for(r = ops.begin(); r != ops.end(); ++r)
+ {
+ OperationPtr op = *r;
+ ContainerPtr container = op->container();
+ ClassDefPtr cl = ClassDefPtr::dynamicCast(container);
+ string opName = fixKwd(op->name());
+ TypePtr ret = op->returnType();
+ string retS = typeToString(ret, TypeModeReturn, package, op->getMetaData());
+
+ ExceptionList throws = op->throws();
+ throws.sort();
+ throws.unique();
+
+ vector<string> params = getParams(op, package);
+ vector<string> args = getArgs(op);
+
+ out << sp;
+ out << nl << "public " << retS << nl << opName << spar << params << "java.util.Map __ctx" << epar;
+ writeDelegateThrowsClause(package, throws);
+ out << sb;
+ if(cl->hasMetaData("amd") || op->hasMetaData("amd"))
+ {
+ out << nl << "throw new Ice.CollocationOptimizationException();";
+ }
+ else
+ {
+ StringList metaData = op->getMetaData();
+ out << nl << "Ice.Current __current = new Ice.Current();";
+ out << nl << "__initCurrent(__current, \"" << op->name() << "\", " << sliceModeToIceMode(op)
+ << ", __ctx);";
+ out << nl << "while(true)";
+ out << sb;
+ out << nl << "IceInternal.Direct __direct = new IceInternal.Direct(__current);";
+ out << nl << "try";
+ out << sb;
+ out << nl << fixKwd(name) << " __servant = null;";
+ out << nl << "try";
+ out << sb;
+ out << nl << "__servant = (" << fixKwd(name) << ")__direct.servant();";
+ out << eb;
+ out << nl << "catch(ClassCastException __ex)";
+ out << sb;
+ out << nl << "Ice.OperationNotExistException __opEx = new Ice.OperationNotExistException();";
+ out << nl << "__opEx.id = __current.id;";
+ out << nl << "__opEx.facet = __current.facet;";
+ out << nl << "__opEx.operation = __current.operation;";
+ out << nl << "throw __opEx;";
+ out << eb;
+ out << nl << "try";
+ out << sb;
+ out << nl;
+ if(ret)
+ {
+ out << "return ";
+ }
+ out << "__servant." << opName << spar << args << "__current" << epar << ';';
+ if(!ret)
+ {
+ out << nl << "return;";
+ }
+ out << eb;
+ out << nl << "catch(Ice.LocalException __ex)";
+ out << sb;
+ out << nl << "throw new IceInternal.NonRepeatable(__ex);";
+ out << eb;
+ out << eb;
+ out << nl << "finally";
+ out << sb;
+ out << nl << "__direct.destroy();";
+ out << eb;
+ out << eb;
+ }
+ out << eb;
+ }
+
+ out << eb;
+ close();
+
+ return false;
+}
+
+Slice::Gen::DispatcherVisitor::DispatcherVisitor(const string& dir) :
+ JavaVisitor(dir)
+{
+}
+
+bool
+Slice::Gen::DispatcherVisitor::visitClassDefStart(const ClassDefPtr& p)
+{
+ if(p->isLocal() || !p->isInterface())
+ {
+ return false;
+ }
+
+ string name = p->name();
+ ClassList bases = p->bases();
+ string absolute = getAbsolute(p, "", "_", "Disp");
+
+ if(!open(absolute))
+ {
+ return false;
+ }
+
+ Output& out = output();
+
+ out << sp << nl << "public abstract class _" << name << "Disp extends Ice.ObjectImpl implements " << fixKwd(name);
+ out << sb;
+
+ out << sp << nl << "protected void" << nl << "ice_copyStateFrom(Ice.Object __obj)";
+ out.inc();
+ out << nl << "throws java.lang.CloneNotSupportedException";
+ out.dec();
+ out << sb;
+ out << nl << "throw new java.lang.CloneNotSupportedException();";
+ out << eb;
+
+ writeDispatch(out, p);
+
+ out << eb;
+ close();
+
+ return false;
+}
+
+Slice::Gen::BaseImplVisitor::BaseImplVisitor(const string& dir) :
+ JavaVisitor(dir)
+{
+}
+
+void
+Slice::Gen::BaseImplVisitor::writeDecl(Output& out, const string& package, const string& name, const TypePtr& type,
+ const StringList& metaData)
+{
+ out << nl << typeToString(type, TypeModeIn, package, metaData) << ' ' << name;
+
+ BuiltinPtr builtin = BuiltinPtr::dynamicCast(type);
+ if(builtin)
+ {
+ switch(builtin->kind())
+ {
+ case Builtin::KindBool:
+ {
+ out << " = false";
+ break;
+ }
+ case Builtin::KindByte:
+ {
+ out << " = (byte)0";
+ break;
+ }
+ case Builtin::KindShort:
+ {
+ out << " = (short)0";
+ break;
+ }
+ case Builtin::KindInt:
+ case Builtin::KindLong:
+ {
+ out << " = 0";
+ break;
+ }
+ case Builtin::KindFloat:
+ {
+ out << " = (float)0.0";
+ break;
+ }
+ case Builtin::KindDouble:
+ {
+ out << " = 0.0";
+ break;
+ }
+ case Builtin::KindString:
+ {
+ out << " = \"\"";
+ break;
+ }
+ case Builtin::KindObject:
+ case Builtin::KindObjectProxy:
+ case Builtin::KindLocalObject:
+ {
+ out << " = null";
+ break;
+ }
+ }
+ }
+ else
+ {
+ EnumPtr en = EnumPtr::dynamicCast(type);
+ if(en)
+ {
+ EnumeratorList enumerators = en->getEnumerators();
+ out << " = " << getAbsolute(en, package) << '.' << fixKwd(enumerators.front()->name());
+ }
+ else
+ {
+ out << " = null";
+ }
+ }
+
+ out << ';';
+}
+
+void
+Slice::Gen::BaseImplVisitor::writeReturn(Output& out, const TypePtr& type)
+{
+ BuiltinPtr builtin = BuiltinPtr::dynamicCast(type);
+ if(builtin)
+ {
+ switch(builtin->kind())
+ {
+ case Builtin::KindBool:
+ {
+ out << nl << "return false;";
+ break;
+ }
+ case Builtin::KindByte:
+ {
+ out << nl << "return (byte)0;";
+ break;
+ }
+ case Builtin::KindShort:
+ {
+ out << nl << "return (short)0;";
+ break;
+ }
+ case Builtin::KindInt:
+ case Builtin::KindLong:
+ {
+ out << nl << "return 0;";
+ break;
+ }
+ case Builtin::KindFloat:
+ {
+ out << nl << "return (float)0.0;";
+ break;
+ }
+ case Builtin::KindDouble:
+ {
+ out << nl << "return 0.0;";
+ break;
+ }
+ case Builtin::KindString:
+ case Builtin::KindObject:
+ case Builtin::KindObjectProxy:
+ case Builtin::KindLocalObject:
+ {
+ out << nl << "return null;";
+ break;
+ }
+ }
+ return;
+ }
+
+ out << nl << "return null;";
+}
+
+void
+Slice::Gen::BaseImplVisitor::writeOperation(Output& out, const string& package, const OperationPtr& op, bool local)
+{
+ string opName = op->name();
+
+ TypePtr ret = op->returnType();
+ StringList opMetaData = op->getMetaData();
+ string retS = typeToString(ret, TypeModeReturn, package, opMetaData);
+ vector<string> params = getParams(op, package);
+
+ ContainerPtr container = op->container();
+ ClassDefPtr cl = ClassDefPtr::dynamicCast(container);
+
+ if(!local && (cl->hasMetaData("amd") || op->hasMetaData("amd")))
+ {
+ vector<string> paramsAMD = getParamsAsync(op, package, true);
+
+ out << sp << nl << "public void" << nl << opName << "_async" << spar << paramsAMD << "Ice.Current __current"
+ << epar;
+
+ ExceptionList throws = op->throws();
+ throws.sort();
+ throws.unique();
+
+ //
+ // Arrange exceptions into most-derived to least-derived order. If we don't
+ // do this, a base exception handler can appear before a derived exception
+ // handler, causing compiler warnings and resulting in the base exception
+ // being marshaled instead of the derived exception.
+ //
+#if defined(__SUNPRO_CC)
+ throws.sort(Slice::derivedToBaseCompare);
+#else
+ throws.sort(Slice::DerivedToBaseCompare());
+#endif
+ writeThrowsClause(package, throws);
+
+ out << sb;
+
+ string result = "__r";
+ ParamDeclList paramList = op->parameters();
+ ParamDeclList::const_iterator q;
+ for(q = paramList.begin(); q != paramList.end(); ++q)
+ {
+ if((*q)->name() == result)
+ {
+ result = "_" + result;
+ break;
+ }
+ }
+ if(ret)
+ {
+ writeDecl(out, package, result, ret, opMetaData);
+ }
+ for(q = paramList.begin(); q != paramList.end(); ++q)
+ {
+ if((*q)->isOutParam())
+ {
+ writeDecl(out, package, fixKwd((*q)->name()), (*q)->type(), (*q)->getMetaData());
+ }
+ }
+
+ out << nl << "__cb.ice_response(";
+ if(ret)
+ {
+ out << result;
+ }
+ for(q = paramList.begin(); q != paramList.end(); ++q)
+ {
+ if((*q)->isOutParam())
+ {
+ if(ret || q != paramList.begin())
+ {
+ out << ", ";
+ }
+ out << fixKwd((*q)->name());
+ }
+ }
+ out << ");";
+
+ out << eb;
+ }
+ else
+ {
+ out << sp << nl << "public " << retS << nl << fixKwd(opName) << spar << params;
+ if(!local)
+ {
+ out << "Ice.Current __current";
+ }
+ out << epar;
+
+ ExceptionList throws = op->throws();
+ throws.sort();
+ throws.unique();
+
+ writeThrowsClause(package, throws);
+
+ out << sb;
+
+ //
+ // Return value
+ //
+ if(ret)
+ {
+ writeReturn(out, ret);
+ }
+
+ out << eb;
+ }
+}
+
+Slice::Gen::ImplVisitor::ImplVisitor(const string& dir) :
+ BaseImplVisitor(dir)
+{
+}
+
+bool
+Slice::Gen::ImplVisitor::visitClassDefStart(const ClassDefPtr& p)
+{
+ if(!p->isAbstract())
+ {
+ return false;
+ }
+
+ string name = p->name();
+ ClassList bases = p->bases();
+ string package = getPackage(p);
+ string absolute = getAbsolute(p, "", "", "I");
+
+ if(!open(absolute))
+ {
+ return false;
+ }
+
+ Output& out = output();
+
+ out << sp << nl << "public final class " << name << 'I';
+ if(p->isInterface())
+ {
+ if(p->isLocal())
+ {
+ out << " extends Ice.LocalObjectImpl implements " << fixKwd(name);
+ }
+ else
+ {
+ out << " extends _" << name << "Disp";
+ }
+ }
+ else
+ {
+ out << " extends " << fixKwd(name);
+ }
+ out << sb;
+
+ out << nl << "public" << nl << name << "I()";
+ out << sb;
+ out << eb;
+
+ OperationList ops = p->allOperations();
+
+ OperationList::const_iterator r;
+ for(r = ops.begin(); r != ops.end(); ++r)
+ {
+ writeOperation(out, package, *r, p->isLocal());
+ }
+
+ out << eb;
+ close();
+
+ return false;
+}
+
+Slice::Gen::ImplTieVisitor::ImplTieVisitor(const string& dir) :
+ BaseImplVisitor(dir)
+{
+}
+
+bool
+Slice::Gen::ImplTieVisitor::visitClassDefStart(const ClassDefPtr& p)
+{
+ if(!p->isAbstract())
+ {
+ return false;
+ }
+
+ string name = p->name();
+ ClassList bases = p->bases();
+ string package = getPackage(p);
+ string absolute = getAbsolute(p, "", "", "I");
+
+ if(!open(absolute))
+ {
+ return false;
+ }
+
+ Output& out = output();
+
+ //
+ // Use implementation inheritance in the following situations:
+ //
+ // * if a class extends another class
+ // * if a class implements a single interface
+ // * if an interface extends only one interface
+ //
+ bool inheritImpl = (!p->isInterface() && !bases.empty() && !bases.front()->isInterface()) || (bases.size() == 1);
+
+ out << sp << nl << "public class " << name << 'I';
+ if(inheritImpl)
+ {
+ out << " extends ";
+ if(bases.front()->isAbstract())
+ {
+ out << bases.front()->name() << 'I';
+ }
+ else
+ {
+ out << fixKwd(bases.front()->name());
+ }
+ }
+ out << " implements " << '_' << name << "Operations";
+ if(p->isLocal())
+ {
+ out << "NC";
+ }
+ out << sb;
+
+ out << nl << "public" << nl << name << "I()";
+ out << sb;
+ out << eb;
+
+ OperationList ops = p->allOperations();
+ ops.sort();
+
+ OperationList baseOps;
+ if(inheritImpl)
+ {
+ baseOps = bases.front()->allOperations();
+ baseOps.sort();
+ }
+
+ OperationList::const_iterator r;
+ for(r = ops.begin(); r != ops.end(); ++r)
+ {
+ if(inheritImpl && binary_search(baseOps.begin(), baseOps.end(), *r))
+ {
+ out << sp;
+ out << nl << "/*";
+ out << nl << " * Implemented by " << bases.front()->name() << 'I';
+ out << nl << " *";
+ writeOperation(out, package, *r, p->isLocal());
+ out << sp;
+ out << nl << "*/";
+ }
+ else
+ {
+ writeOperation(out, package, *r, p->isLocal());
+ }
+ }
+
+ out << eb;
+ close();
+
+ return false;
+}
+
+Slice::Gen::AsyncVisitor::AsyncVisitor(const string& dir) :
+ JavaVisitor(dir)
+{
+}
+
+void
+Slice::Gen::AsyncVisitor::visitOperation(const OperationPtr& p)
+{
+ ContainerPtr container = p->container();
+ ClassDefPtr cl = ClassDefPtr::dynamicCast(container);
+
+ if(cl->isLocal())
+ {
+ return;
+ }
+
+ string name = p->name();
+ string classPkg = getPackage(cl);
+ StringList opMetaData = p->getMetaData();
+
+ if(cl->hasMetaData("ami") || p->hasMetaData("ami"))
+ {
+ string classNameAMI = "AMI_" + cl->name();
+ string absoluteAMI = getAbsolute(cl, "", "AMI_", "_" + name);
+
+ if(!open(absoluteAMI))
+ {
+ return;
+ }
+
+ Output& out = output();
+
+ TypePtr ret = p->returnType();
+
+ ParamDeclList inParams;
+ ParamDeclList outParams;
+ ParamDeclList paramList = p->parameters();
+ ParamDeclList::const_iterator pli;
+ for(pli = paramList.begin(); pli != paramList.end(); ++pli)
+ {
+ if((*pli)->isOutParam())
+ {
+ outParams.push_back(*pli);
+ }
+ else
+ {
+ inParams.push_back(*pli);
+ }
+ }
+
+ ExceptionList throws = p->throws();
+ throws.sort();
+ throws.unique();
+
+ //
+ // Arrange exceptions into most-derived to least-derived order. If we don't
+ // do this, a base exception handler can appear before a derived exception
+ // handler, causing compiler warnings and resulting in the base exception
+ // being marshaled instead of the derived exception.
+ //
+#if defined(__SUNPRO_CC)
+ throws.sort(Slice::derivedToBaseCompare);
+#else
+ throws.sort(Slice::DerivedToBaseCompare());
+#endif
+
+ int iter;
+
+ vector<string> params = getParamsAsyncCB(p, classPkg);
+ vector<string> args = getArgsAsyncCB(p);
+
+ vector<string> paramsInvoke = getParamsAsync(p, classPkg, false);
+
+ out << sp << nl << "public abstract class " << classNameAMI << '_' << name
+ << " extends IceInternal.OutgoingAsync";
+ out << sb;
+ out << sp;
+ out << nl << "public abstract void ice_response" << spar << params << epar << ';';
+ out << nl << "public abstract void ice_exception(Ice.LocalException ex);";
+ if(!throws.empty())
+ {
+ out << nl << "public abstract void ice_exception(Ice.UserException ex);";
+ }
+
+ out << sp << nl << "public final void" << nl << "__invoke" << spar << "Ice.ObjectPrx __prx"
+ << paramsInvoke << "java.util.Map __ctx" << epar;
+ out << sb;
+ out << nl << "try";
+ out << sb;
+ out << nl << "__prepare(__prx, \"" << p->name() << "\", " << sliceModeToIceMode(p) << ", __ctx);";
+ iter = 0;
+ for(pli = inParams.begin(); pli != inParams.end(); ++pli)
+ {
+ StringList metaData = (*pli)->getMetaData();
+ string typeS = typeToString((*pli)->type(), TypeModeIn, classPkg, metaData);
+ writeMarshalUnmarshalCode(out, classPkg, (*pli)->type(), fixKwd((*pli)->name()), true, iter, false,
+ metaData);
+ }
+ if(p->sendsClasses())
+ {
+ out << nl << "__os.writePendingObjects();";
+ }
+ out << nl << "__os.endWriteEncaps();";
+ out << eb;
+ out << nl << "catch(Ice.LocalException __ex)";
+ out << sb;
+ out << nl << "__finished(__ex);";
+ out << nl << "return;";
+ out << eb;
+ out << nl << "__send();";
+ out << eb;
+
+ out << sp << nl << "protected final void" << nl << "__response(boolean __ok)";
+ out << sb;
+ for(pli = outParams.begin(); pli != outParams.end(); ++pli)
+ {
+ TypePtr paramType = (*pli)->type();
+ string paramName = fixKwd((*pli)->name());
+ string typeS = typeToString(paramType, TypeModeIn, classPkg, (*pli)->getMetaData());
+ BuiltinPtr builtin = BuiltinPtr::dynamicCast(paramType);
+ if((builtin && builtin->kind() == Builtin::KindObject) || ClassDeclPtr::dynamicCast(paramType))
+ {
+ out << nl << typeS << "Holder " << paramName << " = new " << typeS << "Holder();";
+ }
+ else
+ {
+ out << nl << typeS << ' ' << paramName << ';';
+ }
+ }
+ if(ret)
+ {
+ string retS = typeToString(ret, TypeModeIn, classPkg, opMetaData);
+ BuiltinPtr builtin = BuiltinPtr::dynamicCast(ret);
+ if((builtin && builtin->kind() == Builtin::KindObject) || ClassDeclPtr::dynamicCast(ret))
+ {
+ out << nl << retS << "Holder __ret = new " << retS << "Holder();";
+ }
+ else
+ {
+ out << nl << retS << " __ret;";
+ }
+ }
+ out << nl << "try";
+ out << sb;
+ out << nl << "if(!__ok)";
+ out << sb;
+ out << nl << "try";
+ out << sb;
+ out << nl << "__is.throwException();";
+ out << eb;
+ for(ExceptionList::const_iterator r = throws.begin(); r != throws.end(); ++r)
+ {
+ out << nl << "catch(" << getAbsolute(*r, classPkg) << " __ex)";
+ out << sb;
+ out << nl << "throw __ex;";
+ out << eb;
+ }
+ out << nl << "catch(Ice.UserException __ex)";
+ out << sb;
+ out << nl << "throw new Ice.UnknownUserException();";
+ out << eb;
+ out << eb;
+ for(pli = outParams.begin(); pli != outParams.end(); ++pli)
+ {
+ TypePtr paramType = (*pli)->type();
+ string paramName = fixKwd((*pli)->name());
+ BuiltinPtr builtin = BuiltinPtr::dynamicCast(paramType);
+ if((builtin && builtin->kind() == Builtin::KindObject) || ClassDeclPtr::dynamicCast(paramType))
+ {
+ out << nl << "__is.readObject(" << paramName << ".getPatcher());";
+ }
+ else
+ {
+ writeMarshalUnmarshalCode(out, classPkg, paramType, paramName, false, iter, false,
+ (*pli)->getMetaData());
+ }
+ }
+ if(ret)
+ {
+ BuiltinPtr builtin = BuiltinPtr::dynamicCast(ret);
+ if((builtin && builtin->kind() == Builtin::KindObject) || ClassDeclPtr::dynamicCast(ret))
+ {
+ out << nl << "__is.readObject(__ret.getPatcher());";
+ }
+ else
+ {
+ writeMarshalUnmarshalCode(out, classPkg, ret, "__ret", false, iter, false, opMetaData);
+ }
+ }
+ if(p->returnsClasses())
+ {
+ out << nl << "__is.readPendingObjects();";
+ }
+ out << eb;
+ out << nl << "catch(Ice.LocalException __ex)";
+ out << sb;
+ out << nl << "__finished(__ex);";
+ out << nl << "return;";
+ out << eb;
+ if(!throws.empty())
+ {
+ out << nl << "catch(Ice.UserException __ex)";
+ out << sb;
+ out << nl << "ice_exception(__ex);";
+ out << nl << "return;";
+ out << eb;
+ }
+ out << nl << "ice_response" << spar << args << epar << ';';
+ out << eb;
+ out << eb;
+
+ close();
+ }
+
+ if(cl->hasMetaData("amd") || p->hasMetaData("amd"))
+ {
+ string classNameAMD = "AMD_" + cl->name();
+ string absoluteAMD = getAbsolute(cl, "", "AMD_", "_" + name);
+
+ string classNameAMDI = "_AMD_" + cl->name();
+ string absoluteAMDI = getAbsolute(cl, "", "_AMD_", "_" + name);
+
+ vector<string> paramsAMD = getParamsAsyncCB(p, classPkg);
+
+ {
+ if(!open(absoluteAMD))
+ {
+ return;
+ }
+
+ Output& out = output();
+
+ out << sp << nl << "public interface " << classNameAMD << '_' << name;
+ out << sb;
+ out << sp << nl << "void ice_response" << spar << paramsAMD << epar << ';';
+ out << sp << nl << "void ice_exception(java.lang.Exception ex);";
+ out << eb;
+
+ close();
+ }
+
+ {
+ if(!open(absoluteAMDI))
+ {
+ return;
+ }
+
+ Output& out = output();
+
+ TypePtr ret = p->returnType();
+
+ ParamDeclList outParams;
+ ParamDeclList paramList = p->parameters();
+ ParamDeclList::const_iterator pli;
+ for(pli = paramList.begin(); pli != paramList.end(); ++pli)
+ {
+ if((*pli)->isOutParam())
+ {
+ outParams.push_back(*pli);
+ }
+ }
+
+ ExceptionList throws = p->throws();
+ throws.sort();
+ throws.unique();
+
+ //
+ // Arrange exceptions into most-derived to least-derived order. If we don't
+ // do this, a base exception handler can appear before a derived exception
+ // handler, causing compiler warnings and resulting in the base exception
+ // being marshaled instead of the derived exception.
+ //
+#if defined(__SUNPRO_CC)
+ throws.sort(Slice::derivedToBaseCompare);
+#else
+ throws.sort(Slice::DerivedToBaseCompare());
+#endif
+
+ int iter;
+
+ out << sp << nl << "final class " << classNameAMDI << '_' << name
+ << " extends IceInternal.IncomingAsync implements " << classNameAMD << '_' << name;
+ out << sb;
+
+ out << sp << nl << "public" << nl << classNameAMDI << '_' << name << "(IceInternal.Incoming in)";
+ out << sb;
+ out << nl << "super(in);";
+ out << eb;
+
+ out << sp << nl << "public void" << nl << "ice_response" << spar << paramsAMD << epar;
+ out << sb;
+ iter = 0;
+ if(ret || !outParams.empty())
+ {
+ out << nl << "try";
+ out << sb;
+ out << nl << "IceInternal.BasicStream __os = this.__os();";
+ for(pli = outParams.begin(); pli != outParams.end(); ++pli)
+ {
+ StringList metaData = (*pli)->getMetaData();
+ string typeS = typeToString((*pli)->type(), TypeModeIn, classPkg, metaData);
+ writeMarshalUnmarshalCode(out, classPkg, (*pli)->type(), fixKwd((*pli)->name()), true, iter,
+ false, metaData);
+ }
+ if(ret)
+ {
+ string retS = typeToString(ret, TypeModeIn, classPkg, opMetaData);
+ writeMarshalUnmarshalCode(out, classPkg, ret, "__ret", true, iter, false, opMetaData);
+ }
+ if(p->returnsClasses())
+ {
+ out << nl << "__os.writePendingObjects();";
+ }
+ out << eb;
+ out << nl << "catch(Ice.LocalException __ex)";
+ out << sb;
+ out << nl << "ice_exception(__ex);";
+ out << eb;
+ }
+ out << nl << "__response(true);";
+ out << eb;
+
+ out << sp << nl << "public void" << nl << "ice_exception(java.lang.Exception ex)";
+ out << sb;
+ if(throws.empty())
+ {
+ out << nl << "__exception(ex);";
+ }
+ else
+ {
+ out << nl << "try";
+ out << sb;
+ out << nl << "throw ex;";
+ out << eb;
+ ExceptionList::const_iterator r;
+ for(r = throws.begin(); r != throws.end(); ++r)
+ {
+ string exS = getAbsolute(*r, classPkg);
+ out << nl << "catch(" << exS << " __ex)";
+ out << sb;
+ out << nl << "__os().writeUserException(__ex);";
+ out << nl << "__response(false);";
+ out << eb;
+ }
+ out << nl << "catch(java.lang.Exception __ex)";
+ out << sb;
+ out << nl << "__exception(__ex);";
+ out << eb;
+ }
+ out << eb;
+
+ out << eb;
+
+ close();
+ }
+ }
+}
diff --git a/cpp/src/slice2javae/Gen.h b/cpp/src/slice2javae/Gen.h
new file mode 100644
index 00000000000..ff555c28102
--- /dev/null
+++ b/cpp/src/slice2javae/Gen.h
@@ -0,0 +1,281 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2005 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#ifndef GEN_H
+#define GEN_H
+
+#include <Slice/Parser.h>
+#include <Slice/JavaUtil.h>
+#include <Slice/Checksum.h>
+
+namespace Slice
+{
+
+class JavaVisitor : public JavaGenerator, public ParserVisitor
+{
+public:
+
+ virtual ~JavaVisitor();
+
+protected:
+
+ JavaVisitor(const std::string&);
+
+ //
+ // Compose the parameter lists for an operation.
+ //
+ std::vector<std::string> getParams(const OperationPtr&, const std::string&);
+ std::vector<std::string> getParamsAsync(const OperationPtr&, const std::string&, bool);
+ std::vector<std::string> getParamsAsyncCB(const OperationPtr&, const std::string&);
+
+ //
+ // Compose the argument lists for an operation.
+ //
+ std::vector<std::string> getArgs(const OperationPtr&);
+ std::vector<std::string> getArgsAsync(const OperationPtr&);
+ std::vector<std::string> getArgsAsyncCB(const OperationPtr&);
+
+ //
+ // Generate a throws clause containing only non-local exceptions.
+ //
+ void writeThrowsClause(const std::string&, const ExceptionList&);
+
+ //
+ // Generate a throws clause for delegate operations containing only
+ // non-local exceptions.
+ //
+ void writeDelegateThrowsClause(const std::string&, const ExceptionList&);
+
+ //
+ // Generate code to compute a hash code for a type.
+ //
+ void writeHashCode(::IceUtil::Output&, const TypePtr&, const std::string&, int&,
+ const std::list<std::string>& = std::list<std::string>());
+
+ //
+ // Generate dispatch methods for a class or interface.
+ //
+ void writeDispatch(::IceUtil::Output&, const ClassDefPtr&);
+};
+
+class Gen : public ::IceUtil::noncopyable
+{
+public:
+
+ Gen(const std::string&,
+ const std::string&,
+ const std::vector<std::string>&,
+ const std::string&);
+ ~Gen();
+
+ bool operator!() const; // Returns true if there was a constructor error
+
+ void generate(const UnitPtr&, bool);
+ void generateTie(const UnitPtr&);
+ void generateImpl(const UnitPtr&);
+ void generateImplTie(const UnitPtr&);
+
+ static void writeChecksumClass(const std::string&, const std::string&, const ChecksumMap&);
+
+private:
+
+ std::string _base;
+ std::vector<std::string> _includePaths;
+ std::string _dir;
+
+ class OpsVisitor : public JavaVisitor
+ {
+ public:
+
+ OpsVisitor(const std::string&);
+
+ virtual bool visitClassDefStart(const ClassDefPtr&);
+
+ private:
+ void writeOperations(const ClassDefPtr&, bool);
+ };
+
+ class TieVisitor : public JavaVisitor
+ {
+ public:
+
+ TieVisitor(const std::string&);
+
+ virtual bool visitClassDefStart(const ClassDefPtr&);
+ };
+
+ class PackageVisitor : public JavaVisitor
+ {
+ public:
+
+ PackageVisitor(const std::string&);
+
+ virtual bool visitModuleStart(const ModulePtr&);
+ };
+
+ class TypesVisitor : public JavaVisitor
+ {
+ public:
+
+ TypesVisitor(const std::string&, bool);
+
+ virtual bool visitClassDefStart(const ClassDefPtr&);
+ virtual void visitClassDefEnd(const ClassDefPtr&);
+ virtual bool visitExceptionStart(const ExceptionPtr&);
+ virtual void visitExceptionEnd(const ExceptionPtr&);
+ virtual bool visitStructStart(const StructPtr&);
+ virtual void visitStructEnd(const StructPtr&);
+ virtual void visitEnum(const EnumPtr&);
+ virtual void visitConst(const ConstPtr&);
+ virtual void visitDataMember(const DataMemberPtr&);
+
+ private:
+
+ bool _stream;
+ };
+
+ class HolderVisitor : public JavaVisitor
+ {
+ public:
+
+ HolderVisitor(const std::string&, bool);
+
+ virtual bool visitClassDefStart(const ClassDefPtr&);
+ virtual bool visitStructStart(const StructPtr&);
+ virtual void visitSequence(const SequencePtr&);
+ virtual void visitDictionary(const DictionaryPtr&);
+ virtual void visitEnum(const EnumPtr&);
+
+ private:
+
+ void writeHolder(const TypePtr&);
+
+ bool _stream;
+ };
+
+ class HelperVisitor : public JavaVisitor
+ {
+ public:
+
+ HelperVisitor(const std::string&, bool);
+
+ virtual bool visitClassDefStart(const ClassDefPtr&);
+ virtual bool visitStructStart(const StructPtr&);
+ virtual void visitSequence(const SequencePtr&);
+ virtual void visitDictionary(const DictionaryPtr&);
+ virtual void visitEnum(const EnumPtr&);
+
+ private:
+
+ bool _stream;
+ };
+
+ class ProxyVisitor : public JavaVisitor
+ {
+ public:
+
+ ProxyVisitor(const std::string&);
+
+ virtual bool visitClassDefStart(const ClassDefPtr&);
+ virtual void visitClassDefEnd(const ClassDefPtr&);
+ virtual void visitOperation(const OperationPtr&);
+ };
+
+ class DelegateVisitor : public JavaVisitor
+ {
+ public:
+
+ DelegateVisitor(const std::string&);
+
+ virtual bool visitClassDefStart(const ClassDefPtr&);
+ };
+
+ class DelegateMVisitor : public JavaVisitor
+ {
+ public:
+
+ DelegateMVisitor(const std::string&);
+
+ virtual bool visitClassDefStart(const ClassDefPtr&);
+ };
+
+ class DelegateDVisitor : public JavaVisitor
+ {
+ public:
+
+ DelegateDVisitor(const std::string&);
+
+ virtual bool visitClassDefStart(const ClassDefPtr&);
+ };
+
+ class DispatcherVisitor : public JavaVisitor
+ {
+ public:
+
+ DispatcherVisitor(const std::string&);
+
+ virtual bool visitClassDefStart(const ClassDefPtr&);
+ };
+
+ class BaseImplVisitor : public JavaVisitor
+ {
+ public:
+
+ BaseImplVisitor(const std::string&);
+
+ protected:
+
+ //
+ // Generate code to emit a local variable declaration and initialize it
+ // if necessary.
+ //
+ void writeDecl(::IceUtil::Output&, const std::string&, const std::string&, const TypePtr&, const StringList&);
+
+ //
+ // Generate code to return a value.
+ //
+ void writeReturn(::IceUtil::Output&, const TypePtr&);
+
+ //
+ // Generate an operation.
+ //
+ void writeOperation(::IceUtil::Output&, const std::string&, const OperationPtr&, bool);
+ };
+
+ class ImplVisitor : public BaseImplVisitor
+ {
+ public:
+
+ ImplVisitor(const std::string&);
+
+ virtual bool visitClassDefStart(const ClassDefPtr&);
+ };
+
+ class ImplTieVisitor : public BaseImplVisitor
+ {
+ public:
+
+ ImplTieVisitor(const std::string&);
+
+ virtual bool visitClassDefStart(const ClassDefPtr&);
+ };
+
+ class AsyncVisitor : public JavaVisitor
+ {
+ public:
+
+ AsyncVisitor(const std::string&);
+
+ virtual void visitOperation(const OperationPtr&);
+ };
+};
+
+}
+
+#endif
diff --git a/cpp/src/slice2javae/Main.cpp b/cpp/src/slice2javae/Main.cpp
new file mode 100644
index 00000000000..cbbe476f91f
--- /dev/null
+++ b/cpp/src/slice2javae/Main.cpp
@@ -0,0 +1,226 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2005 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#include <IceUtil/Options.h>
+#include <Slice/Preprocessor.h>
+#include <Gen.h>
+
+using namespace std;
+using namespace Slice;
+
+void
+usage(const char* n)
+{
+ cerr << "Usage: " << n << " [options] slice-files...\n";
+ cerr <<
+ "Options:\n"
+ "-h, --help Show this message.\n"
+ "-v, --version Display the Ice version.\n"
+ "-DNAME Define NAME as 1.\n"
+ "-DNAME=DEF Define NAME as DEF.\n"
+ "-UNAME Remove any definition for NAME.\n"
+ "-IDIR Put DIR in the include file search path.\n"
+ "--output-dir DIR Create files in the directory DIR.\n"
+ "--tie Generate TIE classes.\n"
+ "--impl Generate sample implementations.\n"
+ "--impl-tie Generate sample TIE implementations.\n"
+ "--depend Generate Makefile dependencies.\n"
+ "-d, --debug Print debug messages.\n"
+ "--ice Permit `Ice' prefix (for building Ice source code only)\n"
+ "--checksum CLASS Generate checksums for Slice definitions into CLASS.\n"
+ "--stream Generate marshaling support for public stream API.\n"
+ ;
+ // Note: --case-sensitive is intentionally not shown here!
+}
+
+int
+main(int argc, char* argv[])
+{
+ string cppArgs;
+ vector<string> includePaths;
+ string output;
+ bool tie;
+ bool impl;
+ bool implTie;
+ bool depend;
+ bool debug;
+ bool ice;
+ string checksumClass;
+ bool stream;
+ bool caseSensitive;
+
+ IceUtil::Options opts;
+ opts.addOpt("h", "help");
+ opts.addOpt("v", "version");
+ opts.addOpt("D", "", IceUtil::Options::NeedArg, "", IceUtil::Options::Repeat);
+ opts.addOpt("U", "", IceUtil::Options::NeedArg, "", IceUtil::Options::Repeat);
+ opts.addOpt("I", "", IceUtil::Options::NeedArg, "", IceUtil::Options::Repeat);
+ opts.addOpt("", "output-dir", IceUtil::Options::NeedArg);
+ opts.addOpt("", "tie");
+ opts.addOpt("", "impl");
+ opts.addOpt("", "impl-tie");
+ opts.addOpt("", "depend");
+ opts.addOpt("d", "debug");
+ opts.addOpt("", "ice");
+ opts.addOpt("", "checksum", IceUtil::Options::NeedArg);
+ opts.addOpt("", "stream");
+ opts.addOpt("", "case-sensitive");
+
+ vector<string>args;
+ try
+ {
+ args = opts.parse(argc, argv);
+ }
+ catch(const IceUtil::Options::BadOpt& e)
+ {
+ cerr << argv[0] << ": " << e.reason << endl;
+ usage(argv[0]);
+ return EXIT_FAILURE;
+ }
+
+ if(opts.isSet("h") || opts.isSet("help"))
+ {
+ usage(argv[0]);
+ return EXIT_SUCCESS;
+ }
+ if(opts.isSet("v") || opts.isSet("version"))
+ {
+ cout << ICE_STRING_VERSION << endl;
+ return EXIT_SUCCESS;
+ }
+ if(opts.isSet("D"))
+ {
+ vector<string> optargs = opts.argVec("D");
+ for(vector<string>::const_iterator i = optargs.begin(); i != optargs.end(); ++i)
+ {
+ cppArgs += " -D" + *i;
+ }
+ }
+ if(opts.isSet("U"))
+ {
+ vector<string> optargs = opts.argVec("U");
+ for(vector<string>::const_iterator i = optargs.begin(); i != optargs.end(); ++i)
+ {
+ cppArgs += " -U" + *i;
+ }
+ }
+ if(opts.isSet("I"))
+ {
+ includePaths = opts.argVec("I");
+ for(vector<string>::const_iterator i = includePaths.begin(); i != includePaths.end(); ++i)
+ {
+ cppArgs += " -I" + *i;
+ }
+ }
+ if(opts.isSet("output-dir"))
+ {
+ output = opts.optArg("output-dir");
+ }
+ tie = opts.isSet("tie");
+ impl = opts.isSet("impl");
+ implTie = opts.isSet("impl-tie");
+ depend = opts.isSet("depend");
+ debug = opts.isSet("d") || opts.isSet("debug");
+ ice = opts.isSet("ice");
+ if(opts.isSet("checksum"))
+ {
+ checksumClass = opts.optArg("checksum");
+ }
+ stream = opts.isSet("stream");
+ caseSensitive = opts.isSet("case-sensitive");
+
+ if(args.empty())
+ {
+ cerr << argv[0] << ": no input file" << endl;
+ usage(argv[0]);
+ return EXIT_FAILURE;
+ }
+
+ if(impl && implTie)
+ {
+ cerr << argv[0] << ": cannot specify both --impl and --impl-tie" << endl;
+ usage(argv[0]);
+ return EXIT_FAILURE;
+ }
+
+ int status = EXIT_SUCCESS;
+
+ ChecksumMap checksums;
+
+ for(vector<string>::const_iterator i = args.begin(); i != args.end(); ++i)
+ {
+ if(depend)
+ {
+ Preprocessor icecpp(argv[0], *i, cppArgs);
+ icecpp.printMakefileDependencies(Preprocessor::Java);
+ }
+ else
+ {
+ Preprocessor icecpp(argv[0], *i, cppArgs);
+ FILE* cppHandle = icecpp.preprocess(false);
+
+ if(cppHandle == 0)
+ {
+ return EXIT_FAILURE;
+ }
+
+ UnitPtr p = Unit::createUnit(false, false, ice, caseSensitive);
+ int parseStatus = p->parse(cppHandle, debug, false);
+
+ if(!icecpp.close())
+ {
+ return EXIT_FAILURE;
+ }
+
+ if(parseStatus == EXIT_FAILURE)
+ {
+ status = EXIT_FAILURE;
+ }
+ else
+ {
+ Gen gen(argv[0], icecpp.getBaseName(), includePaths, output);
+ if(!gen)
+ {
+ p->destroy();
+ return EXIT_FAILURE;
+ }
+ gen.generate(p, stream);
+ if(tie)
+ {
+ gen.generateTie(p);
+ }
+ if(impl)
+ {
+ gen.generateImpl(p);
+ }
+ if(implTie)
+ {
+ gen.generateImplTie(p);
+ }
+ if(!checksumClass.empty())
+ {
+ //
+ // Calculate checksums for the Slice definitions in the unit.
+ //
+ ChecksumMap m = createChecksums(p);
+ copy(m.begin(), m.end(), inserter(checksums, checksums.begin()));
+ }
+ }
+
+ p->destroy();
+ }
+ }
+
+ if(!checksumClass.empty())
+ {
+ Gen::writeChecksumClass(checksumClass, output, checksums);
+ }
+
+ return status;
+}
diff --git a/cpp/src/slice2javae/Makefile b/cpp/src/slice2javae/Makefile
new file mode 100644
index 00000000000..502d0a214a9
--- /dev/null
+++ b/cpp/src/slice2javae/Makefile
@@ -0,0 +1,32 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2005 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice is licensed to you under the terms described in the
+# ICE_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+top_srcdir = ../..
+
+NAME = $(top_srcdir)/bin/slice2javae
+
+TARGETS = $(NAME)
+
+OBJS = Gen.o \
+ Main.o
+
+SRCS = $(OBJS:.o=.cpp)
+
+include $(top_srcdir)/config/Make.rules
+
+CPPFLAGS := -I. $(CPPFLAGS)
+
+$(NAME): $(OBJS)
+ rm -f $@
+ $(CXX) $(LDFLAGS) -o $@ $(OBJS) -lSlice $(BASELIBS)
+
+install:: all
+ $(INSTALL_PROGRAM) $(NAME) $(install_bindir)
+
+include .depend
diff --git a/cpp/src/slice2javae/slice2javae.dsp b/cpp/src/slice2javae/slice2javae.dsp
new file mode 100644
index 00000000000..2b64ade479a
--- /dev/null
+++ b/cpp/src/slice2javae/slice2javae.dsp
@@ -0,0 +1,126 @@
+# Microsoft Developer Studio Project File - Name="slice2javae" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=slice2javae - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "slice2javae.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "slice2javae.mak" CFG="slice2javae - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "slice2javae - Win32 Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "slice2javae - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "slice2javae - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /MD /W3 /WX /GR /GX /O2 /I "." /I "../../include" /D "NDEBUG" /D "_CONSOLE" /FD /c
+# SUBTRACT CPP /Fr /YX
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 setargv.obj /nologo /subsystem:console /incremental:yes /machine:I386
+# SUBTRACT LINK32 /nodefaultlib
+# Begin Special Build Tool
+OutDir=.\Release
+TargetName=slice2javae
+SOURCE="$(InputPath)"
+PostBuild_Cmds=copy $(OutDir)\$(TargetName).exe ..\..\bin
+# End Special Build Tool
+
+!ELSEIF "$(CFG)" == "slice2javae - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
+# ADD CPP /nologo /MDd /W3 /WX /Gm /GR /GX /Zi /Od /I "." /I "../../include" /D "_DEBUG" /D "_CONSOLE" /FD /GZ /c
+# SUBTRACT CPP /Fr /YX
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 setargv.obj /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# SUBTRACT LINK32 /incremental:no /nodefaultlib
+# Begin Special Build Tool
+OutDir=.\Debug
+TargetName=slice2javae
+SOURCE="$(InputPath)"
+PostBuild_Cmds=copy $(OutDir)\$(TargetName).exe ..\..\bin
+# End Special Build Tool
+
+!ENDIF
+
+# Begin Target
+
+# Name "slice2javae - Win32 Release"
+# Name "slice2javae - Win32 Debug"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=.\Gen.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\Main.cpp
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# Begin Source File
+
+SOURCE=.\Gen.h
+# End Source File
+# End Group
+# Begin Group "Resource Files"
+
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+# End Group
+# End Target
+# End Project