summaryrefslogtreecommitdiff
path: root/cpp/src/Slice
diff options
context:
space:
mode:
Diffstat (limited to 'cpp/src/Slice')
-rw-r--r--cpp/src/Slice/CPlusPlusUtil.cpp4
-rw-r--r--cpp/src/Slice/Checksum.cpp2
-rw-r--r--cpp/src/Slice/FileTracker.cpp2
-rw-r--r--cpp/src/Slice/Grammar.cpp2
-rw-r--r--cpp/src/Slice/Grammar.y2
-rw-r--r--cpp/src/Slice/GrammarUtil.h2
-rw-r--r--cpp/src/Slice/JavaUtil.cpp5045
-rw-r--r--cpp/src/Slice/MD5.cpp2
-rw-r--r--cpp/src/Slice/MD5.h2
-rw-r--r--cpp/src/Slice/PHPUtil.cpp2
-rw-r--r--cpp/src/Slice/Parser.cpp2
-rw-r--r--cpp/src/Slice/Preprocessor.cpp2
-rw-r--r--cpp/src/Slice/Python.cpp2
-rw-r--r--cpp/src/Slice/PythonUtil.cpp4
-rw-r--r--cpp/src/Slice/Ruby.cpp2
-rw-r--r--cpp/src/Slice/RubyUtil.cpp4
-rw-r--r--cpp/src/Slice/Scanner.cpp2
-rw-r--r--cpp/src/Slice/Scanner.l2
18 files changed, 20 insertions, 5065 deletions
diff --git a/cpp/src/Slice/CPlusPlusUtil.cpp b/cpp/src/Slice/CPlusPlusUtil.cpp
index fd61a1272b7..b65006e6c20 100644
--- a/cpp/src/Slice/CPlusPlusUtil.cpp
+++ b/cpp/src/Slice/CPlusPlusUtil.cpp
@@ -1,6 +1,6 @@
// **********************************************************************
//
-// Copyright (c) 2003-2016 ZeroC, Inc. All rights reserved.
+// Copyright (c) 2003-2017 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.
@@ -520,7 +520,7 @@ Slice::printHeader(Output& out)
static const char* header =
"// **********************************************************************\n"
"//\n"
-"// Copyright (c) 2003-2016 ZeroC, Inc. All rights reserved.\n"
+"// Copyright (c) 2003-2017 ZeroC, Inc. All rights reserved.\n"
"//\n"
"// This copy of Ice is licensed to you under the terms described in the\n"
"// ICE_LICENSE file included in this distribution.\n"
diff --git a/cpp/src/Slice/Checksum.cpp b/cpp/src/Slice/Checksum.cpp
index 11892bdedb7..d7bd960bb59 100644
--- a/cpp/src/Slice/Checksum.cpp
+++ b/cpp/src/Slice/Checksum.cpp
@@ -1,6 +1,6 @@
// **********************************************************************
//
-// Copyright (c) 2003-2016 ZeroC, Inc. All rights reserved.
+// Copyright (c) 2003-2017 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.
diff --git a/cpp/src/Slice/FileTracker.cpp b/cpp/src/Slice/FileTracker.cpp
index 398f7e49bc4..20dfc7ae93c 100644
--- a/cpp/src/Slice/FileTracker.cpp
+++ b/cpp/src/Slice/FileTracker.cpp
@@ -1,6 +1,6 @@
// **********************************************************************
//
-// Copyright (c) 2003-2016 ZeroC, Inc. All rights reserved.
+// Copyright (c) 2003-2017 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.
diff --git a/cpp/src/Slice/Grammar.cpp b/cpp/src/Slice/Grammar.cpp
index c81edc0c8b8..b94e5582bdf 100644
--- a/cpp/src/Slice/Grammar.cpp
+++ b/cpp/src/Slice/Grammar.cpp
@@ -73,7 +73,7 @@
// **********************************************************************
//
-// Copyright (c) 2003-2016 ZeroC, Inc. All rights reserved.
+// Copyright (c) 2003-2017 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.
diff --git a/cpp/src/Slice/Grammar.y b/cpp/src/Slice/Grammar.y
index 1cca612ee8b..0ff52066500 100644
--- a/cpp/src/Slice/Grammar.y
+++ b/cpp/src/Slice/Grammar.y
@@ -2,7 +2,7 @@
// **********************************************************************
//
-// Copyright (c) 2003-2016 ZeroC, Inc. All rights reserved.
+// Copyright (c) 2003-2017 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.
diff --git a/cpp/src/Slice/GrammarUtil.h b/cpp/src/Slice/GrammarUtil.h
index e11ec472a4b..ef155dd38dc 100644
--- a/cpp/src/Slice/GrammarUtil.h
+++ b/cpp/src/Slice/GrammarUtil.h
@@ -1,6 +1,6 @@
// **********************************************************************
//
-// Copyright (c) 2003-2016 ZeroC, Inc. All rights reserved.
+// Copyright (c) 2003-2017 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.
diff --git a/cpp/src/Slice/JavaUtil.cpp b/cpp/src/Slice/JavaUtil.cpp
deleted file mode 100644
index e8744143ae5..00000000000
--- a/cpp/src/Slice/JavaUtil.cpp
+++ /dev/null
@@ -1,5045 +0,0 @@
-// **********************************************************************
-//
-// Copyright (c) 2003-2016 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/DisableWarnings.h>
-#include <Slice/JavaUtil.h>
-#include <Slice/FileTracker.h>
-#include <Slice/Util.h>
-#include <Slice/MD5.h>
-#include <IceUtil/Functional.h>
-#include <IceUtil/FileUtil.h>
-
-#include <sys/types.h>
-#include <string.h>
-
-#ifdef _WIN32
-#include <direct.h>
-#endif
-
-#ifndef _WIN32
-#include <unistd.h>
-#endif
-
-using namespace std;
-using namespace Slice;
-using namespace IceUtil;
-using namespace IceUtilInternal;
-
-namespace
-{
-
-void
-hashAdd(long& hashCode, const std::string& value)
-{
- for(std::string::const_iterator p = value.begin(); p != value.end(); ++p)
- {
- hashCode = ((hashCode << 5) + hashCode) ^ *p;
- }
-}
-
-string
-typeToBufferString(const TypePtr& type)
-{
- static const char* builtinBufferTable[] =
- {
- "java.nio.ByteBuffer",
- "???",
- "java.nio.ShortBuffer",
- "java.nio.IntBuffer",
- "java.nio.LongBuffer",
- "java.nio.FloatBuffer",
- "java.nio.DoubleBuffer",
- "???",
- "???",
- "???",
- "???"
- };
-
- BuiltinPtr builtin = BuiltinPtr::dynamicCast(type);
- if(!builtin)
- {
- return "???";
- }
- else
- {
- return builtinBufferTable[builtin->kind()];
- }
-}
-
-string
-lookupKwd(const string& name)
-{
- //
- // Keyword list. *Must* be kept in alphabetical order. Note that checkedCast and uncheckedCast
- // are not Java keywords, but are in this list to prevent illegal code being generated if
- // someone defines Slice operations with that name.
- //
- // NOTE: Any changes made to this list must also be made in BasicStream.java.
- //
- static const string keywordList[] =
- {
- "abstract", "assert", "boolean", "break", "byte", "case", "catch",
- "char", "checkedCast", "class", "clone", "const", "continue", "default", "do",
- "double", "else", "enum", "equals", "extends", "false", "final", "finalize",
- "finally", "float", "for", "getClass", "goto", "hashCode", "if",
- "implements", "import", "instanceof", "int", "interface", "long",
- "native", "new", "notify", "notifyAll", "null", "package", "private",
- "protected", "public", "return", "short", "static", "strictfp", "super", "switch",
- "synchronized", "this", "throw", "throws", "toString", "transient",
- "true", "try", "uncheckedCast", "void", "volatile", "wait", "while"
- };
- bool found = binary_search(&keywordList[0],
- &keywordList[sizeof(keywordList) / sizeof(*keywordList)],
- name);
- return found ? "_" + name : name;
-}
-
-//
-// Split a scoped name into its components and return the components as a list of (unscoped) identifiers.
-//
-static StringList
-splitScopedName(const string& scoped)
-{
- assert(scoped[0] == ':');
- StringList ids;
- string::size_type next = 0;
- string::size_type pos;
- while((pos = scoped.find("::", next)) != string::npos)
- {
- pos += 2;
- if(pos != scoped.size())
- {
- string::size_type endpos = scoped.find("::", pos);
- if(endpos != string::npos)
- {
- ids.push_back(scoped.substr(pos, endpos - pos));
- }
- }
- next = pos;
- }
- if(next != scoped.size())
- {
- ids.push_back(scoped.substr(next));
- }
- else
- {
- ids.push_back("");
- }
-
- return ids;
-}
-
-class MetaDataVisitor : public ParserVisitor
-{
-public:
-
- virtual bool visitUnitStart(const UnitPtr& p)
- {
- static const string prefix = "java:";
-
- //
- // Validate global metadata in the top-level file and all included files.
- //
- StringList files = p->allFiles();
-
- for(StringList::iterator q = files.begin(); q != files.end(); ++q)
- {
- string file = *q;
- DefinitionContextPtr dc = p->findDefinitionContext(file);
- assert(dc);
- StringList globalMetaData = dc->getMetaData();
- for(StringList::const_iterator r = globalMetaData.begin(); r != globalMetaData.end();)
- {
- string s = *r++;
- if(s.find(prefix) == 0)
- {
- static const string packagePrefix = "java:package:";
- static const string checksumPrefix = "java:checksum:";
- if(s.find(packagePrefix) == 0 && s.size() > packagePrefix.size())
- {
- continue;
- }
- else if(s.find(checksumPrefix) == 0 && s.size() > checksumPrefix.size())
- {
- continue;
- }
- else
- {
- dc->warning(InvalidMetaData, file, "", "ignoring invalid global metadata `" + s + "'");
- globalMetaData.remove(s);
- continue;
- }
- };
- }
- dc->setMetaData(globalMetaData);
- }
- return true;
- }
-
- virtual bool visitModuleStart(const ModulePtr& p)
- {
- StringList metaData = getMetaData(p);
- metaData = validateType(p, metaData, p->file(), p->line());
- metaData = validateGetSet(p, metaData, p->file(), p->line());
- p->setMetaData(metaData);
- return true;
- }
-
- virtual void visitClassDecl(const ClassDeclPtr& p)
- {
- StringList metaData = getMetaData(p);
- metaData = validateType(p, metaData, p->file(), p->line());
- metaData = validateGetSet(p, metaData, p->file(), p->line());
- p->setMetaData(metaData);
- }
-
- virtual bool visitClassDefStart(const ClassDefPtr& p)
- {
- StringList metaData = getMetaData(p);
- metaData = validateType(p, metaData, p->file(), p->line());
- metaData = validateGetSet(p, metaData, p->file(), p->line());
- p->setMetaData(metaData);
- return true;
- }
-
- virtual bool visitExceptionStart(const ExceptionPtr& p)
- {
- StringList metaData = getMetaData(p);
- metaData = validateType(p, metaData, p->file(), p->line());
- metaData = validateGetSet(p, metaData, p->file(), p->line());
- p->setMetaData(metaData);
- return true;
- }
-
- virtual bool visitStructStart(const StructPtr& p)
- {
- StringList metaData = getMetaData(p);
- metaData = validateType(p, metaData, p->file(), p->line());
- metaData = validateGetSet(p, metaData, p->file(), p->line());
- p->setMetaData(metaData);
- return true;
- }
-
- virtual void visitOperation(const OperationPtr& p)
- {
- TypePtr returnType = p->returnType();
- StringList metaData = getMetaData(p);
-
- UnitPtr unit = p->unit();
- string file = p->file();
- DefinitionContextPtr dc = unit->findDefinitionContext(p->file());
-
- if(!returnType)
- {
- for(StringList::const_iterator q = metaData.begin(); q != metaData.end();)
- {
- string s = *q++;
- if(s.find("java:type:", 0) == 0)
- {
- dc->warning(InvalidMetaData, p->file(), p->line(), "ignoring invalid metadata `" + s +
- "' for operation with void return type");
- metaData.remove(s);
- continue;
- }
- }
- }
- else
- {
- metaData = validateType(returnType, metaData, p->file(), p->line());
- metaData = validateGetSet(p, metaData, p->file(), p->line());
- }
- p->setMetaData(metaData);
-
- ParamDeclList params = p->parameters();
- for(ParamDeclList::iterator q = params.begin(); q != params.end(); ++q)
- {
- metaData = getMetaData(*q);
- metaData = validateType((*q)->type(), metaData, p->file(), (*q)->line());
- metaData = validateGetSet((*q)->type(), metaData, p->file(), (*q)->line());
- (*q)->setMetaData(metaData);
- }
- }
-
- virtual void visitDataMember(const DataMemberPtr& p)
- {
- StringList metaData = getMetaData(p);
- metaData = validateType(p->type(), metaData, p->file(), p->line());
- metaData = validateGetSet(p, metaData, p->file(), p->line());
- p->setMetaData(metaData);
- }
-
- virtual void visitSequence(const SequencePtr& p)
- {
- static const string protobuf = "java:protobuf:";
- static const string serializable = "java:serializable:";
- static const string bytebuffer = "java:buffer";
- StringList metaData = getMetaData(p);
- StringList newMetaData;
-
- const string file = p->file();
- const string line = p->line();
- const UnitPtr unit = p->unit();
- const DefinitionContextPtr dc = unit->findDefinitionContext(file);
-
- for(StringList::const_iterator q = metaData.begin(); q != metaData.end(); )
- {
- string s = *q++;
-
- if(s.find(protobuf) == 0 || s.find(serializable) == 0)
- {
- //
- // Remove from list so validateType does not try to handle as well.
- //
- metaData.remove(s);
- BuiltinPtr builtin = BuiltinPtr::dynamicCast(p->type());
- if(!builtin || builtin->kind() != Builtin::KindByte)
- {
- dc->warning(InvalidMetaData, file, line, "ignoring invalid metadata `" + s + "': " +
- "this metadata can only be used with a byte sequence");
- continue;
- }
- newMetaData.push_back(s);
- }
- else if(s.find(bytebuffer) == 0)
- {
- metaData.remove(s);
-
- BuiltinPtr builtin = BuiltinPtr::dynamicCast(p->type());
- if(!builtin ||
- (builtin->kind() != Builtin::KindByte && builtin->kind() != Builtin::KindShort &&
- builtin->kind() != Builtin::KindInt && builtin->kind() != Builtin::KindLong &&
- builtin->kind() != Builtin::KindFloat && builtin->kind() != Builtin::KindDouble))
- {
- dc->warning(InvalidMetaData, file, line, "ignoring invalid metadata `" + s + "': " +
- "this metadata can not be used with this type");
- continue;
- }
- newMetaData.push_back(s);
- }
- }
-
- metaData = validateType(p, metaData, file, line);
- metaData = validateGetSet(p, metaData, file, line);
- newMetaData.insert(newMetaData.begin(), metaData.begin(), metaData.end());
- p->setMetaData(newMetaData);
- }
-
- virtual void visitDictionary(const DictionaryPtr& p)
- {
- StringList metaData = getMetaData(p);
- metaData = validateType(p, metaData, p->file(), p->line());
- metaData = validateGetSet(p, metaData, p->file(), p->line());
- p->setMetaData(metaData);
- }
-
- virtual void visitEnum(const EnumPtr& p)
- {
- StringList metaData = getMetaData(p);
- metaData = validateType(p, metaData, p->file(), p->line());
- metaData = validateGetSet(p, metaData, p->file(), p->line());
- p->setMetaData(metaData);
- }
-
- virtual void visitConst(const ConstPtr& p)
- {
- StringList metaData = getMetaData(p);
- metaData = validateType(p, metaData, p->file(), p->line());
- metaData = validateGetSet(p, metaData, p->file(), p->line());
- p->setMetaData(metaData);
- }
-
-private:
-
- StringList getMetaData(const ContainedPtr& cont)
- {
- static const string prefix = "java:";
-
- StringList metaData = cont->getMetaData();
- StringList result;
-
- UnitPtr unit = cont->container()->unit();
- string file = cont->file();
- DefinitionContextPtr dc = unit->findDefinitionContext(file);
- assert(dc);
-
- for(StringList::const_iterator p = metaData.begin(); p != metaData.end(); ++p)
- {
- string s = *p;
- if(s.find(prefix) == 0)
- {
- string::size_type pos = s.find(':', prefix.size());
- if(pos == string::npos)
- {
- if(s.size() > prefix.size())
- {
- string rest = s.substr(prefix.size());
- if(rest == "getset")
- {
- result.push_back(s);
- continue;
- }
- else if(rest == "buffer")
- {
- result.push_back(s);
- continue;
- }
- else if(rest == "tie")
- {
- result.push_back(s);
- continue;
- }
- else if(rest == "UserException")
- {
- result.push_back(s);
- continue;
- }
- else if(rest == "optional")
- {
- result.push_back(s);
- continue;
- }
- }
- }
- else if(s.substr(prefix.size(), pos - prefix.size()) == "type")
- {
- result.push_back(s);
- continue;
- }
- else if(s.substr(prefix.size(), pos - prefix.size()) == "serializable")
- {
- result.push_back(s);
- continue;
- }
- else if(s.substr(prefix.size(), pos - prefix.size()) == "protobuf")
- {
- result.push_back(s);
- continue;
- }
- else if(s.substr(prefix.size(), pos - prefix.size()) == "serialVersionUID")
- {
- result.push_back(s);
- continue;
- }
- else if(s.substr(prefix.size(), pos - prefix.size()) == "implements")
- {
- result.push_back(s);
- continue;
- }
-
- dc->warning(InvalidMetaData, cont->file(), cont->line(), "ignoring invalid metadata `" + s + "'");
- }
- else
- {
- result.push_back(s);
- continue;
- }
- }
-
- return result;
- }
-
- StringList validateType(const SyntaxTreeBasePtr& p, const StringList& metaData, const string& file, const string& line)
- {
- const UnitPtr unit = p->unit();
- const DefinitionContextPtr dc = unit->findDefinitionContext(file);
- assert(dc);
- StringList newMetaData;
- for(StringList::const_iterator i = metaData.begin(); i != metaData.end(); ++i)
- {
- //
- // Type metadata ("java:type:Foo") is only supported by sequences and dictionaries.
- //
- if(i->find("java:type:", 0) == 0 && (!SequencePtr::dynamicCast(p) && !DictionaryPtr::dynamicCast(p)))
- {
- string str;
- ContainedPtr cont = ContainedPtr::dynamicCast(p);
- if(cont)
- {
- str = cont->kindOf();
- }
- else
- {
- BuiltinPtr b = BuiltinPtr::dynamicCast(p);
- assert(b);
- str = b->typeId();
- }
- dc->warning(InvalidMetaData, file, line, "invalid metadata for " + str);
- }
- else if(i->find("java:buffer") == 0)
- {
- SequencePtr seq = SequencePtr::dynamicCast(p);
- if(seq)
- {
- BuiltinPtr builtin = BuiltinPtr::dynamicCast(seq->type());
- if(builtin &&
- (builtin->kind() == Builtin::KindByte || builtin->kind() == Builtin::KindShort ||
- builtin->kind() == Builtin::KindInt || builtin->kind() == Builtin::KindLong ||
- builtin->kind() == Builtin::KindFloat || builtin->kind() == Builtin::KindDouble))
- {
- newMetaData.push_back(*i);
- continue;
- }
-
- }
-
- dc->warning(InvalidMetaData, file, line, "ignoring invalid metadata `" + *i + "'");
- }
- else if(i->find("java:protobuf:") == 0 || i->find("java:serializable:") == 0)
- {
- //
- // Only valid in sequence definition which is checked in visitSequence
- //
- dc->warning(InvalidMetaData, file, line, "ignoring invalid metadata `" + *i + "'");
- }
- else if(i->find("delegate") == 0)
- {
- ClassDefPtr cl = ClassDefPtr::dynamicCast(p);
- if(cl && cl->isDelegate())
- {
- newMetaData.push_back(*i);
- }
- else
- {
- dc->warning(InvalidMetaData, file, line, "ignoring invalid metadata `" + *i + "'");
- }
- }
- else if(i->find("java:implements:") == 0)
- {
- if(ClassDefPtr::dynamicCast(p) || StructPtr::dynamicCast(p))
- {
- newMetaData.push_back(*i);
- }
- else
- {
- dc->warning(InvalidMetaData, file, line, "ignoring invalid metadata `" + *i + "'");
- }
- }
- else
- {
- newMetaData.push_back(*i);
- }
- }
- return newMetaData;
- }
-
- StringList validateGetSet(const SyntaxTreeBasePtr& p, const StringList& metaData, const string& file, const string& line)
- {
- const UnitPtr unit = p->unit();
- const DefinitionContextPtr dc= unit->findDefinitionContext(file);
- assert(dc);
- StringList newMetaData;
- for(StringList::const_iterator i = metaData.begin(); i != metaData.end(); ++i)
- {
- //
- // The "getset" metadata can only be specified on a class, struct, exception or data member.
- //
- if((*i) == "java:getset" &&
- (!ClassDefPtr::dynamicCast(p) && !StructPtr::dynamicCast(p) && !ExceptionPtr::dynamicCast(p) &&
- !DataMemberPtr::dynamicCast(p)))
- {
- string str;
- ContainedPtr cont = ContainedPtr::dynamicCast(p);
- if(cont)
- {
- str = cont->kindOf();
- }
- else
- {
- BuiltinPtr b = BuiltinPtr::dynamicCast(p);
- assert(b);
- str = b->typeId();
- }
- dc->warning(InvalidMetaData, file, line, "invalid metadata for " + str);
- continue;
- }
- newMetaData.push_back(*i);
- }
- return newMetaData;
- }
-};
-
-}
-
-long
-Slice::computeSerialVersionUUID(const ClassDefPtr& p)
-{
- ostringstream os;
-
- ClassList bases = p->bases();
- os << "Name: " << p->scoped();
-
- os << " Bases: [";
- for(ClassList::const_iterator i = bases.begin(); i != bases.end();)
- {
- os << (*i)->scoped();
- i++;
- if(i != bases.end())
- {
- os << ", ";
- }
- }
- os << "]";
-
- os << " Members: [";
- DataMemberList members = p->dataMembers();
- for(DataMemberList::const_iterator i = members.begin(); i != members.end();)
- {
- os << (*i)->name() << ":" << (*i)->type();
- i++;
- if(i != members.end())
- {
- os << ", ";
- }
- }
- os << "]";
-
- const string data = os.str();
- long hashCode = 5381;
- hashAdd(hashCode, data);
- return hashCode;
-}
-
-long
-Slice::computeSerialVersionUUID(const StructPtr& p)
-{
- ostringstream os;
-
- os << "Name: " << p->scoped();
- os << " Members: [";
- DataMemberList members = p->dataMembers();
- for(DataMemberList::const_iterator i = members.begin(); i != members.end();)
- {
- os << (*i)->name() << ":" << (*i)->type();
- i++;
- if(i != members.end())
- {
- os << ", ";
- }
- }
- os << "]";
-
- const string data = os.str();
- long hashCode = 5381;
- hashAdd(hashCode, data);
- return hashCode;
-}
-
-long
-Slice::computeSerialVersionUUID(const ExceptionPtr& p)
-{
- ostringstream os;
-
- os << "Name: " << p->scoped();
- os << " Members: [";
- DataMemberList members = p->dataMembers();
- for(DataMemberList::const_iterator i = members.begin(); i != members.end();)
- {
- os << (*i)->name() << ":" << (*i)->type();
- i++;
- if(i != members.end())
- {
- os << ", ";
- }
- }
- os << "]";
-
- const string data = os.str();
- long hashCode = 5381;
- hashAdd(hashCode, data);
- return hashCode;
-}
-
-Slice::JavaOutput::JavaOutput()
-{
-}
-
-Slice::JavaOutput::JavaOutput(ostream& os) :
- Output(os)
-{
-}
-
-Slice::JavaOutput::JavaOutput(const char* s) :
- Output(s)
-{
-}
-
-void
-Slice::JavaOutput::openClass(const string& cls, const string& prefix, const string& sliceFile)
-{
- string package;
- string file;
- string path = prefix;
-
- string::size_type pos = cls.rfind('.');
- if(pos != string::npos)
- {
- package = cls.substr(0, pos);
- file = cls.substr(pos + 1);
- string dir = package;
-
- //
- // Create package directories if necessary.
- //
- pos = 0;
- string::size_type start = 0;
- do
- {
- if(!path.empty())
- {
- path += "/";
- }
- pos = dir.find('.', start);
- if(pos != string::npos)
- {
- path += dir.substr(start, pos - start);
- start = pos + 1;
- }
- else
- {
- path += dir.substr(start);
- }
-
- IceUtilInternal::structstat st;
- if(!IceUtilInternal::stat(path, &st))
- {
- if(!(st.st_mode & S_IFDIR))
- {
- ostringstream os;
- os << "failed to create package directory `" << path
- << "': file already exists and is not a directory";
- throw FileException(__FILE__, __LINE__, os.str());
- }
- continue;
- }
-
- if(IceUtilInternal::mkdir(path, 0777) != 0)
- {
- ostringstream os;
- os << "cannot create directory `" << path << "': " << strerror(errno);
- throw FileException(__FILE__, __LINE__, os.str());
- }
- FileTracker::instance()->addDirectory(path);
- }
- while(pos != string::npos);
- }
- else
- {
- file = cls;
- }
- file += ".java";
-
- //
- // Open class file.
- //
- if(!path.empty())
- {
- path += "/";
- }
- path += file;
-
- open(path.c_str());
- if(isOpen())
- {
- FileTracker::instance()->addFile(path);
- printHeader();
- printGeneratedHeader(*this, sliceFile);
- if(!package.empty())
- {
- separator();
- print("package ");
- print(package.c_str());
- print(";");
- }
- }
- else
- {
- ostringstream os;
- os << "cannot open file `" << path << "': " << strerror(errno);
- throw FileException(__FILE__, __LINE__, os.str());
- }
-}
-
-void
-Slice::JavaOutput::printHeader()
-{
- static const char* header =
-"// **********************************************************************\n"
-"//\n"
-"// Copyright (c) 2003-2016 ZeroC, Inc. All rights reserved.\n"
-"//\n"
-"// This copy of Ice is licensed to you under the terms described in the\n"
-"// ICE_LICENSE file included in this distribution.\n"
-"//\n"
-"// **********************************************************************\n"
- ;
-
- print(header);
- print("//\n");
- print("// Ice version ");
- print(ICE_STRING_VERSION);
- print("\n");
- print("//\n");
-}
-
-const string Slice::JavaCompatGenerator::_getSetMetaData = "java:getset";
-
-Slice::JavaCompatGenerator::JavaCompatGenerator(const string& dir) :
- _dir(dir),
- _out(0)
-{
-}
-
-Slice::JavaCompatGenerator::~JavaCompatGenerator()
-{
- // If open throws an exception other generators could be left open
- // during the stack unwind.
- if(_out != 0)
- {
- close();
- }
- assert(_out == 0);
-}
-
-void
-Slice::JavaCompatGenerator::open(const string& absolute, const string& file)
-{
- assert(_out == 0);
-
- JavaOutput* out = createOutput();
- try
- {
- out->openClass(absolute, _dir, file);
- }
- catch(const FileException&)
- {
- delete out;
- throw;
- }
- _out = out;
-}
-
-void
-Slice::JavaCompatGenerator::close()
-{
- assert(_out != 0);
- *_out << nl;
- delete _out;
- _out = 0;
-}
-
-Output&
-Slice::JavaCompatGenerator::output() const
-{
- assert(_out != 0);
- return *_out;
-}
-
-//
-// If the passed name is a scoped name, return the identical scoped name,
-// but with all components that are Java keywords replaced by
-// their "_"-prefixed version; otherwise, if the passed name is
-// not scoped, but a Java keyword, return the "_"-prefixed name;
-// otherwise, return the name unchanged.
-//
-string
-Slice::JavaCompatGenerator::fixKwd(const string& name) const
-{
- if(name.empty())
- {
- return name;
- }
- if(name[0] != ':')
- {
- return lookupKwd(name);
- }
- StringList ids = splitScopedName(name);
- transform(ids.begin(), ids.end(), ids.begin(), ptr_fun(lookupKwd));
- stringstream result;
- for(StringList::const_iterator i = ids.begin(); i != ids.end(); ++i)
- {
- result << "::" + *i;
- }
- return result.str();
-}
-
-string
-Slice::JavaCompatGenerator::convertScopedName(const string& scoped, const string& prefix, const string& suffix) const
-{
- string result;
- string::size_type start = 0;
- string fscoped = fixKwd(scoped);
-
- //
- // Skip leading "::"
- //
- if(fscoped[start] == ':')
- {
- assert(fscoped[start + 1] == ':');
- start += 2;
- }
-
- //
- // Convert all occurrences of "::" to "."
- //
- string::size_type pos;
- do
- {
- pos = fscoped.find(':', start);
- string fix;
- if(pos == string::npos)
- {
- string s = fscoped.substr(start);
- if(!s.empty())
- {
- fix = prefix + fixKwd(s) + suffix;
- }
- }
- else
- {
- assert(fscoped[pos + 1] == ':');
- fix = fixKwd(fscoped.substr(start, pos - start));
- start = pos + 2;
- }
-
- if(!result.empty() && !fix.empty())
- {
- result += ".";
- }
- result += fix;
- }
- while(pos != string::npos);
-
- return result;
-}
-
-string
-Slice::JavaCompatGenerator::getPackagePrefix(const ContainedPtr& cont) const
-{
- UnitPtr unit = cont->container()->unit();
- string file = cont->file();
- assert(!file.empty());
-
- map<string, string>::const_iterator p = _filePackagePrefix.find(file);
- if(p != _filePackagePrefix.end())
- {
- return p->second;
- }
-
- static const string prefix = "java:package:";
- DefinitionContextPtr dc = unit->findDefinitionContext(file);
- assert(dc);
- string q = dc->findMetaData(prefix);
- if(!q.empty())
- {
- q = q.substr(prefix.size());
- }
- _filePackagePrefix[file] = q;
- return q;
-}
-
-string
-Slice::JavaCompatGenerator::getPackage(const ContainedPtr& cont) const
-{
- string scope = convertScopedName(cont->scope());
- string prefix = getPackagePrefix(cont);
- if(!prefix.empty())
- {
- if(!scope.empty())
- {
- return prefix + "." + scope;
- }
- else
- {
- return prefix;
- }
- }
-
- return scope;
-}
-
-string
-Slice::JavaCompatGenerator::getAbsolute(const ContainedPtr& cont,
- const string& package,
- const string& prefix,
- const string& suffix) const
-{
- string name = cont->name();
- if(prefix == "" && suffix == "")
- {
- name = fixKwd(name);
- }
- string contPkg = getPackage(cont);
- if(contPkg == package)
- {
- return prefix + name + suffix;
- }
- else if(!contPkg.empty())
- {
- return contPkg + "." + prefix + name + suffix;
- }
- else
- {
- return prefix + name + suffix;
- }
-}
-
-string
-Slice::JavaCompatGenerator::getStaticId(const TypePtr& type, const string& package) const
-{
- BuiltinPtr b = BuiltinPtr::dynamicCast(type);
- ClassDeclPtr cl = ClassDeclPtr::dynamicCast(type);
-
- assert((b && b->usesClasses()) || cl);
-
- if(b)
- {
- return "Ice.ObjectImpl.ice_staticId()";
- }
- else if(cl->isInterface())
- {
- return getAbsolute(cl, package, "_", "Disp") + ".ice_staticId()";
- }
- else
- {
- return getAbsolute(cl, package) + ".ice_staticId()";
- }
-}
-
-bool
-Slice::JavaCompatGenerator::useOptionalMapping(const OperationPtr& p)
-{
- //
- // The "java:optional" metadata can be applied to an operation or its
- // interface to force the mapping to use the Ice.Optional types.
- //
- // Without the tag, parameters use the normal (non-optional) mapping.
- //
- static const string tag = "java:optional";
-
- ClassDefPtr cl = ClassDefPtr::dynamicCast(p->container());
- assert(cl);
-
- return p->hasMetaData(tag) || cl->hasMetaData(tag);
-}
-
-string
-Slice::JavaCompatGenerator::getOptionalFormat(const TypePtr& type)
-{
- BuiltinPtr bp = BuiltinPtr::dynamicCast(type);
- if(bp)
- {
- switch(bp->kind())
- {
- case Builtin::KindByte:
- case Builtin::KindBool:
- {
- return "Ice.OptionalFormat.F1";
- }
- case Builtin::KindShort:
- {
- return "Ice.OptionalFormat.F2";
- }
- case Builtin::KindInt:
- case Builtin::KindFloat:
- {
- return "Ice.OptionalFormat.F4";
- }
- case Builtin::KindLong:
- case Builtin::KindDouble:
- {
- return "Ice.OptionalFormat.F8";
- }
- case Builtin::KindString:
- {
- return "Ice.OptionalFormat.VSize";
- }
- case Builtin::KindObject:
- {
- return "Ice.OptionalFormat.Class";
- }
- case Builtin::KindObjectProxy:
- {
- return "Ice.OptionalFormat.FSize";
- }
- case Builtin::KindLocalObject:
- {
- assert(false);
- break;
- }
- case Builtin::KindValue:
- {
- return "Ice.OptionalFormat.Class";
- }
- }
- }
-
- if(EnumPtr::dynamicCast(type))
- {
- return "Ice.OptionalFormat.Size";
- }
-
- SequencePtr seq = SequencePtr::dynamicCast(type);
- if(seq)
- {
- return seq->type()->isVariableLength() ? "Ice.OptionalFormat.FSize" : "Ice.OptionalFormat.VSize";
- }
-
- DictionaryPtr d = DictionaryPtr::dynamicCast(type);
- if(d)
- {
- return (d->keyType()->isVariableLength() || d->valueType()->isVariableLength()) ?
- "Ice.OptionalFormat.FSize" : "Ice.OptionalFormat.VSize";
- }
-
- StructPtr st = StructPtr::dynamicCast(type);
- if(st)
- {
- return st->isVariableLength() ? "Ice.OptionalFormat.FSize" : "Ice.OptionalFormat.VSize";
- }
-
- if(ProxyPtr::dynamicCast(type))
- {
- return "Ice.OptionalFormat.FSize";
- }
-
- ClassDeclPtr cl = ClassDeclPtr::dynamicCast(type);
- assert(cl);
- return "Ice.OptionalFormat.Class";
-}
-
-string
-Slice::JavaCompatGenerator::typeToString(const TypePtr& type,
- TypeMode mode,
- const string& package,
- const StringList& metaData,
- bool formal,
- bool optional) const
-{
- static const char* builtinTable[] =
- {
- "byte",
- "boolean",
- "short",
- "int",
- "long",
- "float",
- "double",
- "String",
- "Ice.Object",
- "Ice.ObjectPrx",
- "java.lang.Object",
- "Ice.Object" // Ice.Value
- };
- static const char* builtinHolderTable[] =
- {
- "Ice.ByteHolder",
- "Ice.BooleanHolder",
- "Ice.ShortHolder",
- "Ice.IntHolder",
- "Ice.LongHolder",
- "Ice.FloatHolder",
- "Ice.DoubleHolder",
- "Ice.StringHolder",
- "Ice.ObjectHolder",
- "Ice.ObjectPrxHolder",
- "Ice.LocalObjectHolder",
- "Ice.ObjectHolder" // Ice.ValueHolder
- };
- static const char* builtinOptionalTable[] =
- {
- "Ice.ByteOptional",
- "Ice.BooleanOptional",
- "Ice.ShortOptional",
- "Ice.IntOptional",
- "Ice.LongOptional",
- "Ice.FloatOptional",
- "Ice.DoubleOptional",
- "???",
- "???",
- "???",
- "???",
- "???"
- };
-
- if(!type)
- {
- assert(mode == TypeModeReturn);
- return "void";
- }
-
- BuiltinPtr builtin = BuiltinPtr::dynamicCast(type);
- if(builtin)
- {
- if(optional)
- {
- switch(builtin->kind())
- {
- case Builtin::KindByte:
- case Builtin::KindBool:
- case Builtin::KindShort:
- case Builtin::KindInt:
- case Builtin::KindLong:
- case Builtin::KindFloat:
- case Builtin::KindDouble:
- {
- return builtinOptionalTable[builtin->kind()];
- }
- case Builtin::KindString:
- case Builtin::KindObject:
- case Builtin::KindObjectProxy:
- case Builtin::KindLocalObject:
- case Builtin::KindValue:
- {
- break;
- }
- }
- }
- else
- {
- if(mode == TypeModeOut)
- {
- return builtinHolderTable[builtin->kind()];
- }
- else
- {
- return builtinTable[builtin->kind()];
- }
- }
- }
-
- if(optional)
- {
- return "Ice.Optional<" + typeToString(type, TypeModeIn, package, metaData, formal) + ">";
- }
-
- ClassDeclPtr cl = ClassDeclPtr::dynamicCast(type);
- if(cl)
- {
- return getAbsolute(cl, package, "", mode == TypeModeOut ? "Holder" : "");
- }
-
- ProxyPtr proxy = ProxyPtr::dynamicCast(type);
- if(proxy)
- {
- return getAbsolute(proxy->_class(), package, "", mode == TypeModeOut ? "PrxHolder" : "Prx");
- }
-
- DictionaryPtr dict = DictionaryPtr::dynamicCast(type);
- if(dict)
- {
- if(mode == TypeModeOut)
- {
- //
- // Only use the type's generated holder if the instance and
- // formal types match.
- //
- string instanceType, formalType;
- getDictionaryTypes(dict, "", metaData, instanceType, formalType);
- string origInstanceType, origFormalType;
- getDictionaryTypes(dict, "", StringList(), origInstanceType, origFormalType);
- if(formalType == origFormalType && instanceType == origInstanceType)
- {
- return getAbsolute(dict, package, "", "Holder");
- }
-
- //
- // The custom type may or may not be compatible with the type used
- // in the generated holder. We use a generic holder that holds a value of the
- // formal custom type.
- //
- return string("Ice.Holder<") + formalType + " >";
- }
- else
- {
- string instanceType, formalType;
- getDictionaryTypes(dict, package, metaData, instanceType, formalType);
- return formal ? formalType : instanceType;
- }
- }
-
- SequencePtr seq = SequencePtr::dynamicCast(type);
- if(seq)
- {
- if(mode == TypeModeOut)
- {
- string instanceType, formalType;
- getSequenceTypes(seq, "", metaData, instanceType, formalType);
- if(sequenceHasHolder(seq))
- {
- //
- // Only use the type's generated holder if the instance and
- // formal types match.
- //
- string origInstanceType, origFormalType;
- getSequenceTypes(seq, "", StringList(), origInstanceType, origFormalType);
- if(formalType == origFormalType && instanceType == origInstanceType)
- {
- return getAbsolute(seq, package, "", "Holder");
- }
- }
-
- //
- // The custom type may or may not be compatible with the type used
- // in the generated holder. We use a generic holder that holds a value of the
- // formal custom type.
- //
- return string("Ice.Holder<") + formalType + " >";
- }
- else
- {
- string instanceType, formalType;
- getSequenceTypes(seq, package, metaData, instanceType, formalType);
- return formal ? formalType : instanceType;
- }
- }
-
- ContainedPtr contained = ContainedPtr::dynamicCast(type);
- if(contained)
- {
- if(mode == TypeModeOut)
- {
- return getAbsolute(contained, package, "", "Holder");
- }
- else
- {
- return getAbsolute(contained, package);
- }
- }
-
- return "???";
-}
-
-string
-Slice::JavaCompatGenerator::typeToObjectString(const TypePtr& type,
- TypeMode mode,
- const string& package,
- const StringList& metaData,
- bool formal) const
-{
- static const char* builtinTable[] =
- {
- "java.lang.Byte",
- "java.lang.Boolean",
- "java.lang.Short",
- "java.lang.Integer",
- "java.lang.Long",
- "java.lang.Float",
- "java.lang.Double",
- "java.lang.String",
- "Ice.Object",
- "Ice.ObjectPrx",
- "java.lang.Object",
- "Ice.Object" // Ice.Value
- };
-
- BuiltinPtr builtin = BuiltinPtr::dynamicCast(type);
- if(builtin && mode != TypeModeOut)
- {
- return builtinTable[builtin->kind()];
- }
-
- return typeToString(type, mode, package, metaData, formal);
-}
-
-void
-Slice::JavaCompatGenerator::writeMarshalUnmarshalCode(Output& out,
- const string& package,
- const TypePtr& type,
- OptionalMode mode,
- bool optionalMapping,
- int tag,
- const string& param,
- bool marshal,
- int& iter,
- bool holder,
- const string& customStream,
- const StringList& metaData,
- const string& patchParams)
-{
- string stream = customStream;
- if(stream.empty())
- {
- stream = marshal ? "ostr" : "istr";
- }
-
- string v;
- if(holder)
- {
- v = param + ".value";
- }
- else
- {
- v = param;
- }
-
- const bool optionalParam = mode == OptionalInParam || mode == OptionalOutParam || mode == OptionalReturnParam;
-
- BuiltinPtr builtin = BuiltinPtr::dynamicCast(type);
- if(builtin)
- {
- switch(builtin->kind())
- {
- case Builtin::KindByte:
- {
- if(marshal)
- {
- if(optionalParam)
- {
- out << nl << stream << ".writeByte(" << tag << ", " << v << ");";
- }
- else
- {
- out << nl << stream << ".writeByte(" << v << ");";
- }
- }
- else
- {
- if(optionalParam)
- {
- out << nl << stream << ".readByte(" << tag << ", " << v << ");";
- }
- else
- {
- out << nl << v << " = " << stream << ".readByte();";
- }
- }
- break;
- }
- case Builtin::KindBool:
- {
- if(marshal)
- {
- if(optionalParam)
- {
- out << nl << stream << ".writeBool(" << tag << ", " << v << ");";
- }
- else
- {
- out << nl << stream << ".writeBool(" << v << ");";
- }
- }
- else
- {
- if(optionalParam)
- {
- out << nl << stream << ".readBool(" << tag << ", " << v << ");";
- }
- else
- {
- out << nl << v << " = " << stream << ".readBool();";
- }
- }
- break;
- }
- case Builtin::KindShort:
- {
- if(marshal)
- {
- if(optionalParam)
- {
- out << nl << stream << ".writeShort(" << tag << ", " << v << ");";
- }
- else
- {
- out << nl << stream << ".writeShort(" << v << ");";
- }
- }
- else
- {
- if(optionalParam)
- {
- out << nl << stream << ".readShort(" << tag << ", " << v << ");";
- }
- else
- {
- out << nl << v << " = " << stream << ".readShort();";
- }
- }
- break;
- }
- case Builtin::KindInt:
- {
- if(marshal)
- {
- if(optionalParam)
- {
- out << nl << stream << ".writeInt(" << tag << ", " << v << ");";
- }
- else
- {
- out << nl << stream << ".writeInt(" << v << ");";
- }
- }
- else
- {
- if(optionalParam)
- {
- out << nl << stream << ".readInt(" << tag << ", " << v << ");";
- }
- else
- {
- out << nl << v << " = " << stream << ".readInt();";
- }
- }
- break;
- }
- case Builtin::KindLong:
- {
- if(marshal)
- {
- if(optionalParam)
- {
- out << nl << stream << ".writeLong(" << tag << ", " << v << ");";
- }
- else
- {
- out << nl << stream << ".writeLong(" << v << ");";
- }
- }
- else
- {
- if(optionalParam)
- {
- out << nl << stream << ".readLong(" << tag << ", " << v << ");";
- }
- else
- {
- out << nl << v << " = " << stream << ".readLong();";
- }
- }
- break;
- }
- case Builtin::KindFloat:
- {
- if(marshal)
- {
- if(optionalParam)
- {
- out << nl << stream << ".writeFloat(" << tag << ", " << v << ");";
- }
- else
- {
- out << nl << stream << ".writeFloat(" << v << ");";
- }
- }
- else
- {
- if(optionalParam)
- {
- out << nl << stream << ".readFloat(" << tag << ", " << v << ");";
- }
- else
- {
- out << nl << v << " = " << stream << ".readFloat();";
- }
- }
- break;
- }
- case Builtin::KindDouble:
- {
- if(marshal)
- {
- if(optionalParam)
- {
- out << nl << stream << ".writeDouble(" << tag << ", " << v << ");";
- }
- else
- {
- out << nl << stream << ".writeDouble(" << v << ");";
- }
- }
- else
- {
- if(optionalParam)
- {
- out << nl << stream << ".readDouble(" << tag << ", " << v << ");";
- }
- else
- {
- out << nl << v << " = " << stream << ".readDouble();";
- }
- }
- break;
- }
- case Builtin::KindString:
- {
- if(marshal)
- {
- if(optionalParam)
- {
- out << nl << stream << ".writeString(" << tag << ", " << v << ");";
- }
- else
- {
- out << nl << stream << ".writeString(" << v << ");";
- }
- }
- else
- {
- if(optionalParam)
- {
- out << nl << stream << ".readString(" << tag << ", " << v << ");";
- }
- else
- {
- out << nl << v << " = " << stream << ".readString();";
- }
- }
- break;
- }
- case Builtin::KindObject:
- case Builtin::KindValue:
- {
- if(marshal)
- {
- if(optionalParam)
- {
- out << nl << stream << ".writeValue(" << tag << ", " << v << ");";
- }
- else
- {
- out << nl << stream << ".writeValue(" << v << ");";
- }
- }
- else
- {
- if(optionalParam)
- {
- out << nl << stream << ".readValue(" << tag << ", " << param << ");";
- }
- else if(holder && mode == OptionalNone)
- {
- out << nl << stream << ".readValue(" << param << ");";
- }
- else
- {
- if(patchParams.empty())
- {
- out << nl << stream << ".readValue(new Patcher());";
- }
- else
- {
- out << nl << stream << ".readValue(" << patchParams << ");";
- }
- }
- }
- break;
- }
- case Builtin::KindObjectProxy:
- {
- if(marshal)
- {
- if(optionalParam)
- {
- out << nl << stream << ".writeProxy(" << tag << ", " << v << ");";
- }
- else if(mode == OptionalMember)
- {
- out << nl << "int pos = " << stream << ".startSize();";
- out << nl << stream << ".writeProxy(" << v << ");";
- out << nl << stream << ".endSize(pos);";
- }
- else
- {
- out << nl << stream << ".writeProxy(" << v << ");";
- }
- }
- else
- {
- if(optionalParam)
- {
- out << nl << stream << ".readProxy(" << tag << ", " << v << ");";
- }
- else if(mode == OptionalMember)
- {
- out << nl << stream << ".skip(4);";
- out << nl << v << " = " << stream << ".readProxy();";
- }
- else
- {
- out << nl << v << " = " << stream << ".readProxy();";
- }
- }
- break;
- }
- case Builtin::KindLocalObject:
- {
- assert(false);
- break;
- }
- }
- return;
- }
-
- ProxyPtr prx = ProxyPtr::dynamicCast(type);
- if(prx)
- {
- string typeS = typeToString(type, TypeModeIn, package);
- if(marshal)
- {
- if(optionalParam)
- {
- if(optionalMapping)
- {
- out << nl << "if(" << v << " != null && " << v << ".isSet() && " << stream << ".writeOptional("
- << tag << ", " << getOptionalFormat(type) << "))";
- out << sb;
- out << nl << "int pos = " << stream << ".startSize();";
- out << nl << typeS << "Helper.write(" << stream << ", " << v << ".get());";
- out << nl << stream << ".endSize(pos);";
- out << eb;
- }
- else
- {
- out << nl << "if(" << stream << ".writeOptional(" << tag << ", " << getOptionalFormat(type) << "))";
- out << sb;
- out << nl << "int pos = " << stream << ".startSize();";
- out << nl << typeS << "Helper.write(" << stream << ", " << v << ");";
- out << nl << stream << ".endSize(pos);";
- out << eb;
- }
- }
- else if(mode == OptionalMember)
- {
- out << nl << "int pos = " << stream << ".startSize();";
- out << nl << typeS << "Helper.write(" << stream << ", " << v << ");";
- out << nl << stream << ".endSize(pos);";
- }
- else
- {
- out << nl << typeS << "Helper.write(" << stream << ", " << v << ");";
- }
- }
- else
- {
- if(optionalParam)
- {
- out << nl << "if(" << stream << ".readOptional(" << tag << ", " << getOptionalFormat(type) << "))";
- out << sb;
- out << nl << stream << ".skip(4);";
- out << nl << v << ".set(" << typeS << "Helper.read(" << stream << "));";
- out << eb;
- if(mode == OptionalOutParam)
- {
- out << nl << "else";
- out << sb;
- out << nl << v << ".clear();";
- out << eb;
- }
- }
- else if(mode == OptionalMember)
- {
- out << nl << stream << ".skip(4);";
- out << nl << v << " = " << typeS << "Helper.read(" << stream << ");";
- }
- else
- {
- out << nl << v << " = " << typeS << "Helper.read(" << stream << ");";
- }
- }
- return;
- }
-
- ClassDeclPtr cl = ClassDeclPtr::dynamicCast(type);
- if(cl)
- {
- if(marshal)
- {
- if(optionalParam)
- {
- out << nl << stream << ".writeValue(" << tag << ", " << v << ");";
- }
- else
- {
- out << nl << stream << ".writeValue(" << v << ");";
- }
- }
- else
- {
- if(optionalParam)
- {
- string typeS = typeToString(type, TypeModeIn, package);
- out << nl << "if(" << stream << ".readOptional(" << tag << ", " << getOptionalFormat(type) << "))";
- out << sb;
- out << nl << stream << ".readValue(new Ice.OptionalObject(" << v << ", " << typeS << ".class, "
- << getStaticId(type, package) << "));";
- out << eb;
- if(mode == OptionalOutParam)
- {
- out << nl << "else";
- out << sb;
- out << nl << v << ".clear();";
- out << eb;
- }
- }
- else
- {
- if(holder && mode == OptionalNone)
- {
- out << nl << stream << ".readValue(" << param << ");";
- }
- else
- {
- if(patchParams.empty())
- {
- out << nl << stream << ".readValue(new Patcher());";
- }
- else
- {
- out << nl << stream << ".readValue(" << patchParams << ");";
- }
- }
- }
- }
- return;
- }
-
- StructPtr st = StructPtr::dynamicCast(type);
- if(st)
- {
- string typeS = typeToString(type, TypeModeIn, package, metaData);
- if(marshal)
- {
- if(optionalParam || mode == OptionalMember)
- {
- string val;
- if(optionalParam)
- {
- if(optionalMapping)
- {
- out << nl << "if(" << v << " != null && " << v << ".isSet() && " << stream << ".writeOptional("
- << tag << ", " << getOptionalFormat(type) << "))";
- val = v + ".get()";
- }
- else
- {
- out << nl << "if(" << stream << ".writeOptional(" << tag << ", " << getOptionalFormat(type)
- << "))";
- val = v;
- }
- out << sb;
- }
- else
- {
- val = v;
- }
-
- if(st->isVariableLength())
- {
- out << nl << "int pos = " << stream << ".startSize();";
- out << nl << typeS << ".ice_write(" << stream << ", " << val << ");";
- out << nl << stream << ".endSize(pos);";
- }
- else
- {
- out << nl << stream << ".writeSize(" << st->minWireSize() << ");";
- out << nl << typeS << ".ice_write(" << stream << ", " << val << ");";
- }
- if(optionalParam)
- {
- out << eb;
- }
- }
- else
- {
- out << nl << typeS << ".ice_write(" << stream << ", " << v << ");";
- }
- }
- else
- {
- if(optionalParam)
- {
- out << nl << "if(" << stream << ".readOptional(" << tag << ", " << getOptionalFormat(type) << "))";
- out << sb;
-
- if(st->isVariableLength())
- {
- out << nl << stream << ".skip(4);";
- }
- else
- {
- out << nl << stream << ".skipSize();";
- }
-
- out << nl << typeS << " tmpOpt = new " << typeS << "();";
- out << nl << "tmpOpt.ice_readMembers(" << stream << ");";
- out << nl << v << ".set(tmpOpt);";
-
- out << eb;
-
- if(mode == OptionalOutParam)
- {
- out << nl << "else";
- out << sb;
- out << nl << v << ".clear();";
- out << eb;
- }
- }
- else if(mode == OptionalMember)
- {
- if(st->isVariableLength())
- {
- out << nl << stream << ".skip(4);";
- }
- else
- {
- out << nl << stream << ".skipSize();";
- }
- out << nl << v << " = " << typeS << ".ice_read(" << stream << ");";
- }
- else
- {
- out << nl << v << " = " << typeS << ".ice_read(" << stream << ");";
- }
- }
- return;
- }
-
- EnumPtr en = EnumPtr::dynamicCast(type);
- if(en)
- {
- string typeS = typeToString(type, TypeModeIn, package, metaData);
- if(marshal)
- {
- if(optionalParam)
- {
- if(optionalMapping)
- {
- out << nl << "if(" << v << " != null && " << v << ".isSet() && " << stream << ".writeOptional("
- << tag << ", " << getOptionalFormat(type) << "))";
- out << sb;
- out << nl << typeS << ".ice_write(" << stream << ", " << v << ".get());";
- out << eb;
- }
- else
- {
- out << nl << "if(" << stream << ".writeOptional(" << tag << ", " << getOptionalFormat(type) << "))";
- out << sb;
- out << nl << typeS << ".ice_write(" << stream << ", " << v << ");";
- out << eb;
- }
- }
- else
- {
- out << nl << typeS << ".ice_write(" << stream << ", " << v << ");";
- }
- }
- else
- {
- if(optionalParam)
- {
- out << nl << "if(" << stream << ".readOptional(" << tag << ", " << getOptionalFormat(type) << "))";
- out << sb;
- out << nl << v << ".set(" << typeS << ".ice_read(" << stream << "));";
- out << eb;
- if(mode == OptionalOutParam)
- {
- out << nl << "else";
- out << sb;
- out << nl << v << ".clear();";
- out << eb;
- }
- }
- else
- {
- out << nl << v << " = " << typeS << ".ice_read(" << stream << ");";
- }
- }
- return;
- }
-
- DictionaryPtr dict = DictionaryPtr::dynamicCast(type);
- if(dict)
- {
- if(optionalParam || mode == OptionalMember)
- {
- string typeS = typeToString(type, TypeModeIn, package, metaData);
- TypePtr keyType = dict->keyType();
- TypePtr valueType = dict->valueType();
-
- if(marshal)
- {
- if(optionalParam)
- {
- if(optionalMapping)
- {
- out << nl << "if(" << v << " != null && " << v << ".isSet() && " << stream << ".writeOptional("
- << tag << ", " << getOptionalFormat(type) << "))";
- out << sb;
- }
- else
- {
- out << nl << "if(" << stream << ".writeOptional(" << tag << ", " << getOptionalFormat(type)
- << "))";
- out << sb;
- }
- }
-
- if(keyType->isVariableLength() || valueType->isVariableLength())
- {
- string d = optionalParam && optionalMapping ? v + ".get()" : v;
- out << nl << "int pos = " << stream << ".startSize();";
- writeDictionaryMarshalUnmarshalCode(out, package, dict, d, marshal, iter, true, customStream, metaData);
- out << nl << stream << ".endSize(pos);";
- }
- else
- {
- const size_t wireSize = keyType->minWireSize() + valueType->minWireSize();
- string tmpName;
- if(optionalParam && optionalMapping)
- {
- tmpName = "optDict";
- out << nl << "final " << typeS << ' ' << tmpName << " = " << v << ".get();";
- }
- else
- {
- tmpName = v;
- }
- out << nl << "final int optSize = " << tmpName << " == null ? 0 : " << tmpName << ".size();";
- out << nl << stream << ".writeSize(optSize > 254 ? optSize * " << wireSize
- << " + 5 : optSize * " << wireSize << " + 1);";
- writeDictionaryMarshalUnmarshalCode(out, package, dict, tmpName, marshal, iter, true, customStream, metaData);
- }
-
- if(optionalParam)
- {
- out << eb;
- }
- }
- else
- {
- string tmpName;
-
- if(optionalParam)
- {
- tmpName = "optDict";
- out << nl << "if(" << stream << ".readOptional(" << tag << ", " << getOptionalFormat(type) << "))";
- out << sb;
- out << nl << typeS << ' ' << tmpName << ';';
- }
- else
- {
- tmpName = v;
- }
-
- if(keyType->isVariableLength() || valueType->isVariableLength())
- {
- out << nl << stream << ".skip(4);";
- }
- else
- {
- out << nl << stream << ".skipSize();";
- }
-
- writeDictionaryMarshalUnmarshalCode(out, package, dict, tmpName, marshal, iter, true, customStream, metaData);
-
- if(optionalParam)
- {
- out << nl << v << ".set(" << tmpName << ");";
- out << eb;
- if(mode == OptionalOutParam)
- {
- out << nl << "else";
- out << sb;
- out << nl << v << ".clear();";
- out << eb;
- }
- }
- }
- }
- else
- {
- writeDictionaryMarshalUnmarshalCode(out, package, dict, v, marshal, iter, true, customStream, metaData);
- }
- return;
- }
-
- SequencePtr seq = SequencePtr::dynamicCast(type);
- if(seq)
- {
- if(optionalParam || mode == OptionalMember)
- {
- string typeS = typeToString(type, TypeModeIn, package, metaData);
- TypePtr elemType = seq->type();
- BuiltinPtr elemBuiltin = BuiltinPtr::dynamicCast(elemType);
-
- if(optionalParam && elemBuiltin && elemBuiltin->kind() != Builtin::KindObject &&
- elemBuiltin->kind() != Builtin::KindObjectProxy && elemBuiltin->kind() != Builtin::KindValue &&
- !hasTypeMetaData(seq, metaData))
- {
- static const char* builtinTable[] =
- {
- "Byte",
- "Bool",
- "Short",
- "Int",
- "Long",
- "Float",
- "Double",
- "String",
- "???",
- "???",
- "???"
- };
-
- switch(elemBuiltin->kind())
- {
- case Builtin::KindByte:
- case Builtin::KindBool:
- case Builtin::KindShort:
- case Builtin::KindInt:
- case Builtin::KindLong:
- case Builtin::KindFloat:
- case Builtin::KindDouble:
- case Builtin::KindString:
- {
- string bs = builtinTable[elemBuiltin->kind()];
-
- if(marshal)
- {
- out << nl << stream << ".write" << bs << "Seq(" << tag << ", " << v << ");";
- }
- else
- {
- out << nl << stream << ".read" << bs << "Seq(" << tag << ", " << v << ");";
- }
- return;
- }
- case Builtin::KindValue:
- case Builtin::KindObject:
- case Builtin::KindObjectProxy:
- case Builtin::KindLocalObject:
- {
- assert(false);
- break;
- }
- }
- }
-
- string ignore;
- const size_t wireSize = elemType->minWireSize();
-
- if(marshal)
- {
- if(optionalParam)
- {
- if(optionalMapping)
- {
- out << nl << "if(" << v << " != null && " << v << ".isSet() && " << stream << ".writeOptional("
- << tag << ", " << getOptionalFormat(type) << "))";
- }
- else
- {
- out << nl << "if(" << stream << ".writeOptional(" << tag << ", " << getOptionalFormat(type)
- << "))";
- }
-
- out << sb;
- }
-
- if(elemType->isVariableLength())
- {
- string s = optionalParam && optionalMapping ? v + ".get()" : v;
- out << nl << "int pos = " << stream << ".startSize();";
- writeSequenceMarshalUnmarshalCode(out, package, seq, s, marshal, iter, true, customStream, metaData);
- out << nl << stream << ".endSize(pos);";
- }
- else if(findMetaData("java:type:", metaData, ignore) ||
- findMetaData("java:type:", seq->getMetaData(), ignore))
- {
- //
- // The sequence is an instance of java.util.List<E>, where E is a fixed-size type.
- // If the element type is bool or byte, we do NOT write an extra size.
- //
-
- string tmpName;
- if(optionalParam && optionalMapping)
- {
- tmpName = "optSeq";
- out << nl << "final " << typeS << ' ' << tmpName << " = " << v << ".get();";
- }
- else
- {
- tmpName = v;
- }
-
- if(wireSize > 1)
- {
- out << nl << "final int optSize = " << tmpName << " == null ? 0 : " << tmpName << ".size();";
- out << nl << stream << ".writeSize(optSize > 254 ? optSize * " << wireSize
- << " + 5 : optSize * " << wireSize << " + 1);";
- }
- writeSequenceMarshalUnmarshalCode(out, package, seq, tmpName, marshal, iter, true, customStream, metaData);
- }
- else if(findMetaData("java:protobuf:", seq->getMetaData(), ignore) ||
- findMetaData("java:serializable:", seq->getMetaData(), ignore))
- {
- //
- // This just writes a byte sequence.
- //
- string s = optionalParam && optionalMapping ? v + ".get()" : v;
- writeSequenceMarshalUnmarshalCode(out, package, seq, s, marshal, iter, true, customStream, metaData);
- }
- else
- {
- //
- // At this point we have a regular Java array of a fixed-size type.
- //
-
- string tmpName;
- if(optionalParam && optionalMapping)
- {
- tmpName = "optSeq";
- out << nl << "final " << typeS << ' ' << tmpName << " = " << v << ".get();";
- }
- else
- {
- tmpName = v;
- }
-
- if(wireSize > 1)
- {
- out << nl << "final int optSize = " << tmpName << " == null ? 0 : " << tmpName << ".length;";
- out << nl << stream << ".writeSize(optSize > 254 ? optSize * " << wireSize
- << " + 5 : optSize * " << wireSize << " + 1);";
- }
-
- writeSequenceMarshalUnmarshalCode(out, package, seq, tmpName, marshal, iter, true, customStream, metaData);
- }
-
- if(optionalParam)
- {
- out << eb;
- }
- }
- else
- {
- string tmpName;
- if(optionalParam)
- {
- tmpName = "optSeq";
- out << nl << "if(" << stream << ".readOptional(" << tag << ", " << getOptionalFormat(type) << "))";
- out << sb;
- out << nl << typeS << ' ' << tmpName << ';';
- }
- else
- {
- tmpName = v;
- }
-
- if(elemType->isVariableLength())
- {
- out << nl << stream << ".skip(4);";
- }
- else if(wireSize > 1)
- {
- if(findMetaData("java:type:", metaData, ignore) ||
- findMetaData("java:type:", seq->getMetaData(), ignore))
- {
- //
- // The sequence is an instance of java.util.List<E>, where E is a fixed-size type.
- //
-
- out << nl << stream << ".skipSize();";
- }
- else if(!findMetaData("java:protobuf:", seq->getMetaData(), ignore) &&
- !findMetaData("java:serializable:", seq->getMetaData(), ignore))
- {
- out << nl << stream << ".skipSize();";
- }
- }
-
- writeSequenceMarshalUnmarshalCode(out, package, seq, tmpName, marshal, iter, true, customStream, metaData);
-
- if(optionalParam)
- {
- out << nl << v << ".set(" << tmpName << ");";
- out << eb;
- if(mode == OptionalOutParam)
- {
- out << nl << "else";
- out << sb;
- out << nl << v << ".clear();";
- out << eb;
- }
- }
- }
- }
- else
- {
- writeSequenceMarshalUnmarshalCode(out, package, seq, v, marshal, iter, true, customStream, metaData);
- }
- return;
- }
-
- ConstructedPtr constructed = ConstructedPtr::dynamicCast(type);
- assert(constructed);
- string typeS = getAbsolute(constructed, package, "", "Helper");
- if(marshal)
- {
- out << nl << typeS << ".write(" << stream << ", " << v << ");";
- }
- else
- {
- out << nl << v << " = " << typeS << ".read(" << stream << ");";
- }
-}
-
-void
-Slice::JavaCompatGenerator::writeDictionaryMarshalUnmarshalCode(Output& out,
- const string& package,
- const DictionaryPtr& dict,
- const string& param,
- bool marshal,
- int& iter,
- bool useHelper,
- const string& customStream,
- const StringList& metaData)
-{
- string stream = customStream;
- if(stream.empty())
- {
- stream = marshal ? "ostr" : "istr";
- }
-
- string v = param;
-
- string instanceType;
-
- //
- // We have to determine whether it's possible to use the
- // type's generated helper class for this marshal/unmarshal
- // task. Since the user may have specified a custom type in
- // metadata, it's possible that the helper class is not
- // compatible and therefore we'll need to generate the code
- // in-line instead.
- //
- // Specifically, there may be "local" metadata (i.e., from
- // a data member or parameter definition) that overrides the
- // original type. We'll compare the mapped types with and
- // without local metadata to determine whether we can use
- // the helper.
- //
- string formalType;
- getDictionaryTypes(dict, "", metaData, instanceType, formalType);
- string origInstanceType, origFormalType;
- getDictionaryTypes(dict, "", StringList(), origInstanceType, origFormalType);
- if((formalType != origFormalType) || (!marshal && instanceType != origInstanceType))
- {
- useHelper = false;
- }
-
- //
- // If we can use the helper, it's easy.
- //
- if(useHelper)
- {
- string typeS = getAbsolute(dict, package, "", "Helper");
- if(marshal)
- {
- out << nl << typeS << ".write(" << stream << ", " << v << ");";
- }
- else
- {
- out << nl << v << " = " << typeS << ".read(" << stream << ");";
- }
- return;
- }
-
- TypePtr key = dict->keyType();
- TypePtr value = dict->valueType();
-
- string keyS = typeToString(key, TypeModeIn, package);
- string valueS = typeToString(value, TypeModeIn, package);
-
- ostringstream o;
- o << iter;
- string iterS = o.str();
- iter++;
-
- if(marshal)
- {
- out << nl << "if(" << v << " == null)";
- out << sb;
- out << nl << "ostr.writeSize(0);";
- out << eb;
- out << nl << "else";
- out << sb;
- out << nl << "ostr.writeSize(" << v << ".size());";
- string keyObjectS = typeToObjectString(key, TypeModeIn, package);
- string valueObjectS = typeToObjectString(value, TypeModeIn, package);
- out << nl << "for(java.util.Map.Entry<" << keyObjectS << ", " << valueObjectS << "> e : " << v
- << ".entrySet())";
- out << sb;
- for(int i = 0; i < 2; i++)
- {
- string arg;
- TypePtr type;
- if(i == 0)
- {
- arg = "e.getKey()";
- type = key;
- }
- else
- {
- arg = "e.getValue()";
- type = value;
- }
- writeMarshalUnmarshalCode(out, package, type, OptionalNone, false, 0, arg, true, iter, false, customStream);
- }
- out << eb;
- out << eb;
- }
- else
- {
- out << nl << v << " = new " << instanceType << "();";
- out << nl << "int sz" << iterS << " = " << stream << ".readSize();";
- out << nl << "for(int i" << iterS << " = 0; i" << iterS << " < sz" << iterS << "; i" << iterS << "++)";
- out << sb;
- for(int i = 0; i < 2; i++)
- {
- string arg;
- TypePtr type;
- string typeS;
- if(i == 0)
- {
- arg = "key";
- type = key;
- typeS = keyS;
- }
- else
- {
- arg = "value";
- type = value;
- typeS = valueS;
- }
-
- BuiltinPtr b = BuiltinPtr::dynamicCast(type);
- if(ClassDeclPtr::dynamicCast(type) || (b && b->usesClasses()))
- {
- string keyTypeStr = typeToObjectString(key, TypeModeIn, package);
- string valueTypeStr = typeToObjectString(value, TypeModeIn, package);
- writeMarshalUnmarshalCode(out, package, type, OptionalNone, false, 0, arg, false, iter, false,
- customStream, StringList(),
- "new IceInternal.DictionaryPatcher<" + keyTypeStr + ", " + valueTypeStr +
- ">(" + v + ", " + typeS + ".class, key)");
- }
- else
- {
- if(StructPtr::dynamicCast(type))
- {
- out << nl << typeS << ' ' << arg << " = null;";
- }
- else
- {
- out << nl << typeS << ' ' << arg << ';';
- }
- writeMarshalUnmarshalCode(out, package, type, OptionalNone, false, 0, arg, false, iter, false, customStream);
- }
- }
- BuiltinPtr builtin = BuiltinPtr::dynamicCast(value);
- if(!(builtin && builtin->usesClasses()) && !ClassDeclPtr::dynamicCast(value))
- {
- out << nl << "" << v << ".put(key, value);";
- }
- out << eb;
- }
-}
-
-void
-Slice::JavaCompatGenerator::writeSequenceMarshalUnmarshalCode(Output& out,
- const string& package,
- const SequencePtr& seq,
- const string& param,
- bool marshal,
- int& iter,
- bool useHelper,
- const string& customStream,
- const StringList& metaData)
-{
- string stream = customStream;
- if(stream.empty())
- {
- stream = marshal ? "ostr" : "istr";
- }
- string v = param;
-
- //
- // If the sequence is a byte sequence, check if there's the serializable or protobuf metadata to
- // get rid of these two easy cases first.
- //
- BuiltinPtr builtin = BuiltinPtr::dynamicCast(seq->type());
- if(builtin && builtin->kind() == Builtin::KindByte)
- {
- string meta;
- static const string protobuf = "java:protobuf:";
- static const string serializable = "java:serializable:";
- if(seq->findMetaData(serializable, meta))
- {
- if(marshal)
- {
- out << nl << stream << ".writeSerializable(" << v << ");";
- }
- else
- {
- string type = typeToString(seq, TypeModeIn, package);
- out << nl << v << " = (" << type << ")" << stream << ".readSerializable();";
- }
- return;
- }
- else if(seq->findMetaData(protobuf, meta))
- {
- if(marshal)
- {
- out << nl << "if(!" << v << ".isInitialized())";
- out << sb;
- out << nl << "throw new Ice.MarshalException(\"type not fully initialized\");";
- out << eb;
- out << nl << stream << ".writeByteSeq(" << v << ".toByteArray());";
- }
- else
- {
- string type = typeToString(seq, TypeModeIn, package);
- out << nl << "try";
- out << sb;
- out << nl << v << " = " << type << ".parseFrom(" << stream << ".readByteSeq());";
- out << eb;
- out << nl << "catch(com.google.protobuf.InvalidProtocolBufferException ex)";
- out << sb;
- out << nl << "throw new Ice.MarshalException(ex);";
- out << eb;
- }
- return;
- }
- }
-
- if(builtin &&
- (builtin->kind() == Builtin::KindByte || builtin->kind() == Builtin::KindShort ||
- builtin->kind() == Builtin::KindInt || builtin->kind() == Builtin::KindLong ||
- builtin->kind() == Builtin::KindFloat || builtin->kind() == Builtin::KindDouble))
- {
- string meta;
- static const string bytebuffer = "java:buffer";
- if(seq->findMetaData(bytebuffer, meta) || findMetaData(bytebuffer, metaData, meta))
- {
- switch(builtin->kind())
- {
- case Builtin::KindByte:
- {
- if(marshal)
- {
- out << nl << stream << ".writeByteBuffer(" << v << ");";
- }
- else
- {
- out << nl << v << " = " << stream << ".readByteBuffer();";
- }
- break;
- }
- case Builtin::KindShort:
- {
- if(marshal)
- {
- out << nl << stream << ".writeShortBuffer(" << v << ");";
- }
- else
- {
- out << nl << v << " = " << stream << ".readShortBuffer();";
- }
- break;
- }
- case Builtin::KindInt:
- {
- if(marshal)
- {
- out << nl << stream << ".writeIntBuffer(" << v << ");";
- }
- else
- {
- out << nl << v << " = " << stream << ".readIntBuffer();";
- }
- break;
- }
- case Builtin::KindLong:
- {
- if(marshal)
- {
- out << nl << stream << ".writeLongBuffer(" << v << ");";
- }
- else
- {
- out << nl << v << " = " << stream << ".readLongBuffer();";
- }
- break;
- }
- case Builtin::KindFloat:
- {
- if(marshal)
- {
- out << nl << stream << ".writeFloatBuffer(" << v << ");";
- }
- else
- {
- out << nl << v << " = " << stream << ".readFloatBuffer();";
- }
- break;
- }
- case Builtin::KindDouble:
- {
- if(marshal)
- {
- out << nl << stream << ".writeDoubleBuffer(" << v << ");";
- }
- else
- {
- out << nl << v << " = " << stream << ".readDoubleBuffer();";
- }
- break;
- }
- case Builtin::KindBool:
- case Builtin::KindString:
- case Builtin::KindObject:
- case Builtin::KindObjectProxy:
- case Builtin::KindLocalObject:
- case Builtin::KindValue:
- {
- assert(false);
- break;
- }
- }
- return;
- }
- }
-
- bool customType = false;
- string instanceType;
-
- //
- // We have to determine whether it's possible to use the
- // type's generated helper class for this marshal/unmarshal
- // task. Since the user may have specified a custom type in
- // metadata, it's possible that the helper class is not
- // compatible and therefore we'll need to generate the code
- // in-line instead.
- //
- // Specifically, there may be "local" metadata (i.e., from
- // a data member or parameter definition) that overrides the
- // original type. We'll compare the mapped types with and
- // without local metadata to determine whether we can use
- // the helper.
- //
- string formalType;
- customType = getSequenceTypes(seq, "", metaData, instanceType, formalType);
- string origInstanceType, origFormalType;
- getSequenceTypes(seq, "", StringList(), origInstanceType, origFormalType);
- if((formalType != origFormalType) || (!marshal && instanceType != origInstanceType))
- {
- useHelper = false;
- }
-
- //
- // If we can use the helper, it's easy.
- //
- if(useHelper)
- {
- string typeS = getAbsolute(seq, package, "", "Helper");
- if(marshal)
- {
- out << nl << typeS << ".write(" << stream << ", " << v << ");";
- }
- else
- {
- out << nl << v << " = " << typeS << ".read(" << stream << ");";
- }
- return;
- }
-
- //
- // Determine sequence depth.
- //
- int depth = 0;
- TypePtr origContent = seq->type();
- SequencePtr s = SequencePtr::dynamicCast(origContent);
- while(s)
- {
- //
- // Stop if the inner sequence type has a custom, serializable or protobuf type.
- //
- if(hasTypeMetaData(s))
- {
- break;
- }
- depth++;
- origContent = s->type();
- s = SequencePtr::dynamicCast(origContent);
- }
- string origContentS = typeToString(origContent, TypeModeIn, package);
-
- TypePtr type = seq->type();
-
- if(customType)
- {
- //
- // Marshal/unmarshal a custom sequence type.
- //
- BuiltinPtr b = BuiltinPtr::dynamicCast(type);
- string typeS = getAbsolute(seq, package);
- ostringstream o;
- o << origContentS;
- int d = depth;
- while(d--)
- {
- o << "[]";
- }
- string cont = o.str();
- if(marshal)
- {
- out << nl << "if(" << v << " == null)";
- out << sb;
- out << nl << stream << ".writeSize(0);";
- out << eb;
- out << nl << "else";
- out << sb;
- out << nl << stream << ".writeSize(" << v << ".size());";
- string typeS = typeToString(type, TypeModeIn, package);
- out << nl << "for(" << typeS << " elem : " << v << ')';
- out << sb;
- writeMarshalUnmarshalCode(out, package, type, OptionalNone, false, 0, "elem", true, iter, false, customStream);
- out << eb;
- out << eb; // else
- }
- else
- {
- bool isObject = false;
- ClassDeclPtr cl = ClassDeclPtr::dynamicCast(type);
- if((b && b->usesClasses()) || cl)
- {
- isObject = true;
- }
- out << nl << v << " = new " << instanceType << "();";
- out << nl << "final int len" << iter << " = " << stream << ".readAndCheckSeqSize(" << type->minWireSize()
- << ");";
- out << nl << "for(int i" << iter << " = 0; i" << iter << " < len" << iter << "; i" << iter
- << "++)";
- out << sb;
- if(isObject)
- {
- //
- // Add a null value to the list as a placeholder for the element.
- //
- out << nl << v << ".add(null);";
- ostringstream patchParams;
- patchParams << "new IceInternal.ListPatcher<" << origContentS << ">(" << v << ", " << origContentS
- << ".class, i" << iter << ')';
- writeMarshalUnmarshalCode(out, package, type, OptionalNone, false, 0, "elem", false, iter,
- false, customStream, StringList(), patchParams.str());
- }
- else
- {
- if(StructPtr::dynamicCast(type))
- {
- out << nl << cont << " elem = null;";
- }
- else
- {
- out << nl << cont << " elem;";
- }
- writeMarshalUnmarshalCode(out, package, type, OptionalNone, false, 0, "elem", false, iter, false, customStream);
- }
- if(!isObject)
- {
- out << nl << v << ".add(elem);";
- }
- out << eb;
- iter++;
- }
- }
- else
- {
- BuiltinPtr b = BuiltinPtr::dynamicCast(type);
- if(b && b->kind() != Builtin::KindObject &&
- b->kind() != Builtin::KindValue &&
- b->kind() != Builtin::KindObjectProxy)
- {
- switch(b->kind())
- {
- case Builtin::KindByte:
- {
- if(marshal)
- {
- out << nl << stream << ".writeByteSeq(" << v << ");";
- }
- else
- {
- out << nl << v << " = " << stream << ".readByteSeq();";
- }
- break;
- }
- case Builtin::KindBool:
- {
- if(marshal)
- {
- out << nl << stream << ".writeBoolSeq(" << v << ");";
- }
- else
- {
- out << nl << v << " = " << stream << ".readBoolSeq();";
- }
- break;
- }
- case Builtin::KindShort:
- {
- if(marshal)
- {
- out << nl << stream << ".writeShortSeq(" << v << ");";
- }
- else
- {
- out << nl << v << " = " << stream << ".readShortSeq();";
- }
- break;
- }
- case Builtin::KindInt:
- {
- if(marshal)
- {
- out << nl << stream << ".writeIntSeq(" << v << ");";
- }
- else
- {
- out << nl << v << " = " << stream << ".readIntSeq();";
- }
- break;
- }
- case Builtin::KindLong:
- {
- if(marshal)
- {
- out << nl << stream << ".writeLongSeq(" << v << ");";
- }
- else
- {
- out << nl << v << " = " << stream << ".readLongSeq();";
- }
- break;
- }
- case Builtin::KindFloat:
- {
- if(marshal)
- {
- out << nl << stream << ".writeFloatSeq(" << v << ");";
- }
- else
- {
- out << nl << v << " = " << stream << ".readFloatSeq();";
- }
- break;
- }
- case Builtin::KindDouble:
- {
- if(marshal)
- {
- out << nl << stream << ".writeDoubleSeq(" << v << ");";
- }
- else
- {
- out << nl << v << " = " << stream << ".readDoubleSeq();";
- }
- break;
- }
- case Builtin::KindString:
- {
- if(marshal)
- {
- out << nl << stream << ".writeStringSeq(" << v << ");";
- }
- else
- {
- out << nl << v << " = " << stream << ".readStringSeq();";
- }
- break;
- }
- case Builtin::KindValue:
- case Builtin::KindObject:
- case Builtin::KindObjectProxy:
- case Builtin::KindLocalObject:
- {
- assert(false);
- break;
- }
- }
- }
- else
- {
- if(marshal)
- {
- out << nl << "if(" << v << " == null)";
- out << sb;
- out << nl << stream << ".writeSize(0);";
- out << eb;
- out << nl << "else";
- out << sb;
- out << nl << stream << ".writeSize(" << v << ".length);";
- out << nl << "for(int i" << iter << " = 0; i" << iter << " < " << v << ".length; i" << iter
- << "++)";
- out << sb;
- ostringstream o;
- o << v << "[i" << iter << "]";
- iter++;
- writeMarshalUnmarshalCode(out, package, type, OptionalNone, false, 0, o.str(), true, iter, false, customStream);
- out << eb;
- out << eb;
- }
- else
- {
- bool isObject = false;
- ClassDeclPtr cl = ClassDeclPtr::dynamicCast(origContent);
- if((b && b->usesClasses()) || cl)
- {
- isObject = true;
- }
- out << nl << "final int len" << iter << " = " << stream << ".readAndCheckSeqSize("
- << type->minWireSize() << ");";
- //
- // We cannot allocate an array of a generic type, such as
- //
- // arr = new Map<String, String>[sz];
- //
- // Attempting to compile this code results in a "generic array creation" error
- // message. This problem can occur when the sequence's element type is a
- // dictionary, or when the element type is a nested sequence that uses a custom
- // mapping.
- //
- // The solution is to rewrite the code as follows:
- //
- // arr = (Map<String, String>[])new Map[sz];
- //
- // Unfortunately, this produces an unchecked warning during compilation.
- //
- // A simple test is to look for a "<" character in the content type, which
- // indicates the use of a generic type.
- //
- string::size_type pos = origContentS.find('<');
- if(pos != string::npos)
- {
- string nonGenericType = origContentS.substr(0, pos);
- out << nl << v << " = (" << origContentS << "[]";
- int d = depth;
- while(d--)
- {
- out << "[]";
- }
- out << ")new " << nonGenericType << "[len" << iter << "]";
- }
- else
- {
- out << nl << v << " = new " << origContentS << "[len" << iter << "]";
- }
- int d = depth;
- while(d--)
- {
- out << "[]";
- }
- out << ';';
- out << nl << "for(int i" << iter << " = 0; i" << iter << " < len" << iter << "; i" << iter
- << "++)";
- out << sb;
- ostringstream o;
- o << v << "[i" << iter << "]";
- ostringstream patchParams;
- if(isObject)
- {
- patchParams << "new IceInternal.SequencePatcher(" << v << ", " << origContentS
- << ".class, i" << iter << ')';
- writeMarshalUnmarshalCode(out, package, type, OptionalNone, false, 0, o.str(), false, iter,
- false, customStream, StringList(), patchParams.str());
- }
- else
- {
- writeMarshalUnmarshalCode(out, package, type, OptionalNone, false, 0, o.str(), false,
- iter, false, customStream);
- }
- out << eb;
- iter++;
- }
- }
- }
-}
-
-bool
-Slice::JavaCompatGenerator::findMetaData(const string& prefix, const StringList& metaData, string& value)
-{
- for(StringList::const_iterator q = metaData.begin(); q != metaData.end(); ++q)
- {
- if(q->find(prefix) == 0)
- {
- value = *q;
- return true;
- }
- }
-
- return false;
-}
-
-bool
-Slice::JavaCompatGenerator::getTypeMetaData(const StringList& metaData, string& instanceType, string& formalType)
-{
- //
- // Extract the instance type and an optional formal type.
- // The correct syntax is "java:type:instance-type[:formal-type]".
- //
- static const string prefix = "java:type:";
- string directive;
- if(findMetaData(prefix, metaData, directive))
- {
- string::size_type pos = directive.find(':', prefix.size());
- if(pos != string::npos)
- {
- instanceType = directive.substr(prefix.size(), pos - prefix.size());
- formalType = directive.substr(pos + 1);
- }
- else
- {
- instanceType = directive.substr(prefix.size());
- formalType.clear();
- }
- return true;
- }
-
- return false;
-}
-
-bool
-Slice::JavaCompatGenerator::hasTypeMetaData(const TypePtr& type, const StringList& localMetaData)
-{
- ContainedPtr cont = ContainedPtr::dynamicCast(type);
- if(cont)
- {
- static const string prefix = "java:type:";
- string directive;
-
- if(findMetaData(prefix, localMetaData, directive))
- {
- return true;
- }
-
- StringList metaData = cont->getMetaData();
-
- if(findMetaData(prefix, metaData, directive))
- {
- return true;
- }
-
- if(findMetaData("java:protobuf:", metaData, directive) ||
- findMetaData("java:serializable:", metaData, directive))
- {
- SequencePtr seq = SequencePtr::dynamicCast(cont);
- if(seq)
- {
- BuiltinPtr builtin = BuiltinPtr::dynamicCast(seq->type());
- if(builtin && builtin->kind() == Builtin::KindByte)
- {
- return true;
- }
- }
- }
-
- if(findMetaData("java:buffer", localMetaData, directive))
- {
- SequencePtr seq = SequencePtr::dynamicCast(cont);
- if(seq)
- {
- BuiltinPtr builtin = BuiltinPtr::dynamicCast(seq->type());
- if(builtin &&
- (builtin->kind() == Builtin::KindByte || builtin->kind() == Builtin::KindShort ||
- builtin->kind() == Builtin::KindInt || builtin->kind() == Builtin::KindLong ||
- builtin->kind() == Builtin::KindFloat || builtin->kind() == Builtin::KindDouble))
- {
- return true;
- }
- }
- }
- }
-
- return false;
-}
-
-bool
-Slice::JavaCompatGenerator::getDictionaryTypes(const DictionaryPtr& dict,
- const string& package,
- const StringList& metaData,
- string& instanceType,
- string& formalType) const
-{
- //
- // Get the types of the key and value.
- //
- string keyTypeStr = typeToObjectString(dict->keyType(), TypeModeIn, package);
- string valueTypeStr = typeToObjectString(dict->valueType(), TypeModeIn, package);
-
- //
- // Collect metadata for a custom type.
- //
- if(getTypeMetaData(metaData, instanceType, formalType) ||
- getTypeMetaData(dict->getMetaData(), instanceType, formalType))
- {
- assert(!instanceType.empty());
- if(formalType.empty())
- {
- formalType = "java.util.Map<" + keyTypeStr + ", " + valueTypeStr + ">";
- }
- return true;
- }
-
- //
- // Return a default type for the platform.
- //
- instanceType = "java.util.HashMap<" + keyTypeStr + ", " + valueTypeStr + ">";
- formalType = "java.util.Map<" + keyTypeStr + ", " + valueTypeStr + ">";
- return false;
-}
-
-bool
-Slice::JavaCompatGenerator::getSequenceTypes(const SequencePtr& seq,
- const string& package,
- const StringList& metaData,
- string& instanceType,
- string& formalType) const
-{
- BuiltinPtr builtin = BuiltinPtr::dynamicCast(seq->type());
- if(builtin)
- {
- if(builtin->kind() == Builtin::KindByte)
- {
- string prefix = "java:serializable:";
- string meta;
- if(seq->findMetaData(prefix, meta))
- {
- instanceType = formalType = meta.substr(prefix.size());
- return true;
- }
- prefix = "java:protobuf:";
- if(seq->findMetaData(prefix, meta))
- {
- instanceType = formalType = meta.substr(prefix.size());
- return true;
- }
- }
-
- if((builtin->kind() == Builtin::KindByte || builtin->kind() == Builtin::KindShort ||
- builtin->kind() == Builtin::KindInt || builtin->kind() == Builtin::KindLong ||
- builtin->kind() == Builtin::KindFloat || builtin->kind() == Builtin::KindDouble))
- {
- string prefix = "java:buffer";
- string meta;
- string ignore;
- if(seq->findMetaData(prefix, meta) || findMetaData(prefix, metaData, ignore))
- {
- instanceType = formalType = typeToBufferString(seq->type());
- return true;
- }
- }
- }
-
- //
- // Collect metadata for a custom type.
- //
- if(getTypeMetaData(metaData, instanceType, formalType) ||
- getTypeMetaData(seq->getMetaData(), instanceType, formalType))
- {
- assert(!instanceType.empty());
- if(formalType.empty())
- {
- formalType = "java.util.List<" + typeToObjectString(seq->type(), TypeModeIn, package) + ">";
- }
- return true;
- }
-
- //
- // The default mapping is a native array.
- //
- instanceType = formalType = typeToString(seq->type(), TypeModeIn, package, metaData) + "[]";
- return false;
-}
-
-bool
-Slice::JavaCompatGenerator::sequenceHasHolder(const SequencePtr& p) const
-{
- BuiltinPtr builtin = BuiltinPtr::dynamicCast(p->type());
- if(builtin && builtin->kind() == Builtin::KindByte)
- {
- string prefix = "java:serializable:";
- string meta;
- if(p->findMetaData(prefix, meta))
- {
- return false;
- }
- prefix = "java:protobuf:";
- if(p->findMetaData(prefix, meta))
- {
- return false;
- }
- }
-
- if(builtin &&
- (builtin->kind() == Builtin::KindByte || builtin->kind() == Builtin::KindShort ||
- builtin->kind() == Builtin::KindInt || builtin->kind() == Builtin::KindLong ||
- builtin->kind() == Builtin::KindFloat || builtin->kind() == Builtin::KindDouble))
- {
- string meta;
- string prefix = "java:buffer";
- if(p->findMetaData(prefix, meta))
- {
- return false;
- }
- }
-
- return true;
-}
-
-
-JavaOutput*
-Slice::JavaCompatGenerator::createOutput()
-{
- return new JavaOutput;
-}
-
-void
-Slice::JavaCompatGenerator::validateMetaData(const UnitPtr& u)
-{
- MetaDataVisitor visitor;
- u->visit(&visitor, true);
-}
-
-const string Slice::JavaGenerator::_getSetMetaData = "java:getset";
-
-Slice::JavaGenerator::JavaGenerator(const string& dir) :
- _dir(dir),
- _out(0)
-{
-}
-
-Slice::JavaGenerator::~JavaGenerator()
-{
- // If open throws an exception other generators could be left open
- // during the stack unwind.
- if(_out != 0)
- {
- close();
- }
- assert(_out == 0);
-}
-
-void
-Slice::JavaGenerator::open(const string& absolute, const string& file)
-{
- assert(_out == 0);
-
- JavaOutput* out = createOutput();
- try
- {
- out->openClass(absolute, _dir, file);
- }
- catch(const FileException&)
- {
- delete out;
- throw;
- }
- _out = out;
-}
-
-void
-Slice::JavaGenerator::close()
-{
- assert(_out != 0);
- *_out << nl;
- delete _out;
- _out = 0;
-}
-
-Output&
-Slice::JavaGenerator::output() const
-{
- assert(_out != 0);
- return *_out;
-}
-
-//
-// If the passed name is a scoped name, return the identical scoped name,
-// but with all components that are Java keywords replaced by
-// their "_"-prefixed version; otherwise, if the passed name is
-// not scoped, but a Java keyword, return the "_"-prefixed name;
-// otherwise, return the name unchanged.
-//
-string
-Slice::JavaGenerator::fixKwd(const string& name) const
-{
- if(name.empty())
- {
- return name;
- }
- if(name[0] != ':')
- {
- return lookupKwd(name);
- }
- StringList ids = splitScopedName(name);
- transform(ids.begin(), ids.end(), ids.begin(), ptr_fun(lookupKwd));
- stringstream result;
- for(StringList::const_iterator i = ids.begin(); i != ids.end(); ++i)
- {
- result << "::" + *i;
- }
- return result.str();
-}
-
-string
-Slice::JavaGenerator::convertScopedName(const string& scoped, const string& prefix, const string& suffix) const
-{
- string result;
- string::size_type start = 0;
- string fscoped = fixKwd(scoped);
-
- //
- // Skip leading "::"
- //
- if(fscoped[start] == ':')
- {
- assert(fscoped[start + 1] == ':');
- start += 2;
- }
-
- //
- // Convert all occurrences of "::" to "."
- //
- string::size_type pos;
- do
- {
- pos = fscoped.find(':', start);
- string fix;
- if(pos == string::npos)
- {
- string s = fscoped.substr(start);
- if(!s.empty())
- {
- fix = prefix + fixKwd(s) + suffix;
- }
- }
- else
- {
- assert(fscoped[pos + 1] == ':');
- fix = fixKwd(fscoped.substr(start, pos - start));
- start = pos + 2;
- }
-
- if(!result.empty() && !fix.empty())
- {
- result += ".";
- }
- result += fix;
- }
- while(pos != string::npos);
-
- return result;
-}
-
-string
-Slice::JavaGenerator::getPackagePrefix(const ContainedPtr& cont) const
-{
- UnitPtr unit = cont->container()->unit();
- string file = cont->file();
- assert(!file.empty());
-
- map<string, string>::const_iterator p = _filePackagePrefix.find(file);
- if(p != _filePackagePrefix.end())
- {
- return p->second;
- }
-
- static const string prefix = "java:package:";
- DefinitionContextPtr dc = unit->findDefinitionContext(file);
- assert(dc);
- string q = dc->findMetaData(prefix);
- if(!q.empty())
- {
- q = q.substr(prefix.size());
- }
- _filePackagePrefix[file] = q;
- return q;
-}
-
-string
-Slice::JavaGenerator::getPackage(const ContainedPtr& cont) const
-{
- string scope = convertScopedName(cont->scope());
- string prefix = getPackagePrefix(cont);
- if(!prefix.empty())
- {
- if(!scope.empty())
- {
- return prefix + "." + scope;
- }
- else
- {
- return prefix;
- }
- }
-
- return scope;
-}
-
-string
-Slice::JavaGenerator::getAbsolute(const ContainedPtr& cont,
- const string& package,
- const string& prefix,
- const string& suffix) const
-{
- string name = cont->name();
- if(prefix == "" && suffix == "")
- {
- name = fixKwd(name);
- }
- string contPkg = getPackage(cont);
- if(contPkg == package)
- {
- return prefix + name + suffix;
- }
- else if(!contPkg.empty())
- {
- return contPkg + "." + prefix + name + suffix;
- }
- else
- {
- return prefix + name + suffix;
- }
-}
-
-string
-Slice::JavaGenerator::getStaticId(const TypePtr& type, const string& package) const
-{
- BuiltinPtr b = BuiltinPtr::dynamicCast(type);
- ClassDeclPtr cl = ClassDeclPtr::dynamicCast(type);
-
- assert((b && b->usesClasses()) || cl);
-
- if(b && b->kind() == Builtin::KindObject)
- {
- return "com.zeroc.Ice.Object.ice_staticId()";
- }
- else if(b && b->kind() == Builtin::KindValue)
- {
- return "com.zeroc.Ice.Value.ice_staticId()";
- }
- else
- {
- return getAbsolute(cl, package) + ".ice_staticId()";
- }
-}
-
-bool
-Slice::JavaGenerator::useOptionalMapping(const OperationPtr& p)
-{
- //
- // The "java:optional" metadata can be applied to an operation or its
- // interface to force the mapping to use the Optional types.
- //
- // Without the tag, parameters use the normal (non-optional) mapping.
- //
- static const string tag = "java:optional";
-
- ClassDefPtr cl = ClassDefPtr::dynamicCast(p->container());
- assert(cl);
-
- return p->hasMetaData(tag) || cl->hasMetaData(tag);
-}
-
-string
-Slice::JavaGenerator::getOptionalFormat(const TypePtr& type)
-{
- const string prefix = "com.zeroc.Ice.OptionalFormat.";
-
- BuiltinPtr bp = BuiltinPtr::dynamicCast(type);
- if(bp)
- {
- switch(bp->kind())
- {
- case Builtin::KindByte:
- case Builtin::KindBool:
- {
- return prefix + "F1";
- }
- case Builtin::KindShort:
- {
- return prefix + "F2";
- }
- case Builtin::KindInt:
- case Builtin::KindFloat:
- {
- return prefix + "F4";
- }
- case Builtin::KindLong:
- case Builtin::KindDouble:
- {
- return prefix + "F8";
- }
- case Builtin::KindString:
- {
- return prefix + "VSize";
- }
- case Builtin::KindObject:
- {
- return prefix + "Class";
- }
- case Builtin::KindObjectProxy:
- {
- return prefix + "FSize";
- }
- case Builtin::KindLocalObject:
- {
- assert(false);
- break;
- }
- case Builtin::KindValue:
- {
- return prefix + "Class";
- }
- }
- }
-
- if(EnumPtr::dynamicCast(type))
- {
- return prefix + "Size";
- }
-
- SequencePtr seq = SequencePtr::dynamicCast(type);
- if(seq)
- {
- return seq->type()->isVariableLength() ? prefix + "FSize" : prefix + "VSize";
- }
-
- DictionaryPtr d = DictionaryPtr::dynamicCast(type);
- if(d)
- {
- return (d->keyType()->isVariableLength() || d->valueType()->isVariableLength()) ?
- prefix + "FSize" : prefix + "VSize";
- }
-
- StructPtr st = StructPtr::dynamicCast(type);
- if(st)
- {
- return st->isVariableLength() ? prefix + "FSize" : prefix + "VSize";
- }
-
- if(ProxyPtr::dynamicCast(type))
- {
- return prefix + "FSize";
- }
-
- ClassDeclPtr cl = ClassDeclPtr::dynamicCast(type);
- assert(cl);
- return prefix + "Class";
-}
-
-string
-Slice::JavaGenerator::typeToString(const TypePtr& type,
- TypeMode mode,
- const string& package,
- const StringList& metaData,
- bool formal,
- bool optional,
- bool local) const
-{
- static const char* builtinTable[] =
- {
- "byte",
- "boolean",
- "short",
- "int",
- "long",
- "float",
- "double",
- "String",
- "com.zeroc.Ice.Value",
- "com.zeroc.Ice.ObjectPrx",
- "java.lang.Object",
- "com.zeroc.Ice.Value"
- };
- static const char* builtinLocalTable[] =
- {
- "byte",
- "boolean",
- "short",
- "int",
- "long",
- "float",
- "double",
- "String",
- "com.zeroc.Ice.Object",
- "com.zeroc.Ice.ObjectPrx",
- "java.lang.Object",
- "com.zeroc.Ice.Value"
- };
- static const char* builtinOptionalTable[] =
- {
- "java.util.Optional<java.lang.Byte>",
- "java.util.Optional<java.lang.Boolean>",
- "java.util.Optional<java.lang.Short>",
- "java.util.OptionalInt",
- "java.util.OptionalLong",
- "java.util.Optional<java.lang.Float>",
- "java.util.OptionalDouble",
- "???",
- "???",
- "???",
- "???",
- "???"
- };
-
- if(!type)
- {
- assert(mode == TypeModeReturn);
- return "void";
- }
-
- BuiltinPtr builtin = BuiltinPtr::dynamicCast(type);
- if(builtin)
- {
- if(optional)
- {
- switch(builtin->kind())
- {
- case Builtin::KindByte:
- case Builtin::KindBool:
- case Builtin::KindShort:
- case Builtin::KindInt:
- case Builtin::KindLong:
- case Builtin::KindFloat:
- case Builtin::KindDouble:
- {
- return builtinOptionalTable[builtin->kind()];
- }
- case Builtin::KindString:
- case Builtin::KindObject:
- case Builtin::KindObjectProxy:
- case Builtin::KindLocalObject:
- case Builtin::KindValue:
- {
- break;
- }
- }
- }
- else
- {
- return local ? builtinLocalTable[builtin->kind()] : builtinTable[builtin->kind()];
- }
- }
-
- ClassDeclPtr cl = ClassDeclPtr::dynamicCast(type);
-
- if(optional)
- {
- return "java.util.Optional<" + typeToObjectString(type, mode, package, metaData, formal, local) + ">";
- }
-
- if(cl)
- {
- if(cl->isInterface() && !local)
- {
- return "com.zeroc.Ice.Value";
- }
- else
- {
- return getAbsolute(cl, package);
- }
- }
-
- ProxyPtr proxy = ProxyPtr::dynamicCast(type);
- if(proxy)
- {
- ClassDefPtr def = proxy->_class()->definition();
- assert(def);
- if(def->isAbstract())
- {
- return getAbsolute(proxy->_class(), package, "", "Prx");
- }
- else
- {
- return "com.zeroc.Ice.ObjectPrx";
- }
- }
-
- DictionaryPtr dict = DictionaryPtr::dynamicCast(type);
- if(dict)
- {
- string instanceType, formalType;
- getDictionaryTypes(dict, package, metaData, instanceType, formalType, local);
- return formal ? formalType : instanceType;
- }
-
- SequencePtr seq = SequencePtr::dynamicCast(type);
- if(seq)
- {
- string instanceType, formalType;
- getSequenceTypes(seq, package, metaData, instanceType, formalType, local);
- return formal ? formalType : instanceType;
- }
-
- ContainedPtr contained = ContainedPtr::dynamicCast(type);
- if(contained)
- {
- if(mode == TypeModeOut)
- {
- return getAbsolute(contained, package, "", "Holder");
- }
- else
- {
- return getAbsolute(contained, package);
- }
- }
-
- return "???";
-}
-
-string
-Slice::JavaGenerator::typeToObjectString(const TypePtr& type,
- TypeMode mode,
- const string& package,
- const StringList& metaData,
- bool formal,
- bool local) const
-{
- static const char* builtinTable[] =
- {
- "java.lang.Byte",
- "java.lang.Boolean",
- "java.lang.Short",
- "java.lang.Integer",
- "java.lang.Long",
- "java.lang.Float",
- "java.lang.Double",
- "java.lang.String",
- "com.zeroc.Ice.Value",
- "com.zeroc.Ice.ObjectPrx",
- "java.lang.Object",
- "com.zeroc.Ice.Value"
- };
- static const char* builtinLocalTable[] =
- {
- "java.lang.Byte",
- "java.lang.Boolean",
- "java.lang.Short",
- "java.lang.Integer",
- "java.lang.Long",
- "java.lang.Float",
- "java.lang.Double",
- "java.lang.String",
- "com.zeroc.Ice.Object",
- "com.zeroc.Ice.ObjectPrx",
- "java.lang.Object",
- "com.zeroc.Ice.Value"
- };
-
- BuiltinPtr builtin = BuiltinPtr::dynamicCast(type);
- if(builtin && mode != TypeModeOut)
- {
- return local ? builtinLocalTable[builtin->kind()] : builtinTable[builtin->kind()];
- }
-
- return typeToString(type, mode, package, metaData, formal, false, local);
-}
-
-void
-Slice::JavaGenerator::writeMarshalUnmarshalCode(Output& out,
- const string& package,
- const TypePtr& type,
- OptionalMode mode,
- bool optionalMapping,
- int tag,
- const string& param,
- bool marshal,
- int& iter,
- const string& customStream,
- const StringList& metaData,
- const string& patchParams)
-{
- string stream = customStream;
- if(stream.empty())
- {
- stream = marshal ? "ostr" : "istr";
- }
-
- const bool optionalParam = mode == OptionalInParam || mode == OptionalOutParam || mode == OptionalReturnParam;
- string typeS = typeToString(type, TypeModeIn, package, metaData);
-
- assert(!marshal || mode != OptionalMember); // Only support OptionalMember for un-marshaling
-
- static const char* builtinTable[] =
- {
- "Byte",
- "Bool",
- "Short",
- "Int",
- "Long",
- "Float",
- "Double",
- "String",
- "???",
- "???",
- "???"
- };
-
- const BuiltinPtr builtin = BuiltinPtr::dynamicCast(type);
- if(builtin)
- {
- switch(builtin->kind())
- {
- case Builtin::KindByte:
- case Builtin::KindBool:
- case Builtin::KindShort:
- case Builtin::KindInt:
- case Builtin::KindLong:
- case Builtin::KindFloat:
- case Builtin::KindDouble:
- case Builtin::KindString:
- {
- string s = builtinTable[builtin->kind()];
- if(marshal)
- {
- if(optionalParam)
- {
- out << nl << stream << ".write" << s << "(" << tag << ", " << param << ");";
- }
- else
- {
- out << nl << stream << ".write" << s << "(" << param << ");";
- }
- }
- else
- {
- if(optionalParam)
- {
- out << nl << param << " = " << stream << ".read" << s << "(" << tag << ");";
- }
- else
- {
- out << nl << param << " = " << stream << ".read" << s << "();";
- }
- }
- break;
- }
- case Builtin::KindObject:
- case Builtin::KindValue:
- {
- if(marshal)
- {
- if(optionalParam)
- {
- out << nl << stream << ".writeValue(" << tag << ", " << param << ");";
- }
- else
- {
- out << nl << stream << ".writeValue(" << param << ");";
- }
- }
- else
- {
- assert(!patchParams.empty());
- if(optionalParam)
- {
- out << nl << stream << ".readValue(" << tag << ", " << patchParams << ");";
- }
- else
- {
- out << nl << stream << ".readValue(" << patchParams << ");";
- }
- }
- break;
- }
- case Builtin::KindObjectProxy:
- {
- if(marshal)
- {
- if(optionalParam)
- {
- out << nl << stream << ".writeProxy(" << tag << ", " << param << ");";
- }
- else
- {
- out << nl << stream << ".writeProxy(" << param << ");";
- }
- }
- else
- {
- if(optionalParam)
- {
- out << nl << param << " = " << stream << ".readProxy(" << tag << ");";
- }
- else if(mode == OptionalMember)
- {
- out << nl << stream << ".skip(4);";
- out << nl << param << " = " << stream << ".readProxy();";
- }
- else
- {
- out << nl << param << " = " << stream << ".readProxy();";
- }
- }
- break;
- }
- case Builtin::KindLocalObject:
- {
- assert(false);
- break;
- }
- }
- return;
- }
-
- ProxyPtr prx = ProxyPtr::dynamicCast(type);
- if(prx)
- {
- if(marshal)
- {
- if(optionalParam)
- {
- out << nl << stream << ".writeProxy(" << tag << ", " << param << ");";
- }
- else
- {
- out << nl << stream << ".writeProxy(" << param << ");";
- }
- }
- else
- {
- if(optionalParam)
- {
- out << nl << param << " = " << stream << ".readProxy(" << tag << ", " << typeS << "::uncheckedCast);";
- }
- else if(mode == OptionalMember)
- {
- out << nl << stream << ".skip(4);";
- out << nl << param << " = " << typeS << ".uncheckedCast(" << stream << ".readProxy());";
- }
- else
- {
- out << nl << param << " = " << typeS << ".uncheckedCast(" << stream << ".readProxy());";
- }
- }
- return;
- }
-
- ClassDeclPtr cl = ClassDeclPtr::dynamicCast(type);
- if(cl)
- {
- if(marshal)
- {
- if(optionalParam)
- {
- out << nl << stream << ".writeValue(" << tag << ", " << param << ");";
- }
- else
- {
- out << nl << stream << ".writeValue(" << param << ");";
- }
- }
- else
- {
- assert(!patchParams.empty());
- if(optionalParam)
- {
- out << nl << stream << ".readValue(" << tag << ", " << patchParams << ");";
- }
- else
- {
- out << nl << stream << ".readValue(" << patchParams << ");";
- }
- }
- return;
- }
-
- DictionaryPtr dict = DictionaryPtr::dynamicCast(type);
- if(dict)
- {
- if(optionalParam || mode == OptionalMember)
- {
- string instanceType, formalType, origInstanceType, origFormalType;
- getDictionaryTypes(dict, "", metaData, instanceType, formalType, false);
- getDictionaryTypes(dict, "", StringList(), origInstanceType, origFormalType, false);
- if(formalType == origFormalType && (marshal || instanceType == origInstanceType))
- {
- //
- // If we can use the helper, it's easy.
- //
- string helper = getAbsolute(dict, package, "", "Helper");
- if(marshal)
- {
- out << nl << helper << ".write" << spar << stream << tag << param << epar << ";";
- return;
- }
- else if(mode != OptionalMember)
- {
- out << nl << param << " = " << helper << ".read" << spar << stream << tag << epar << ";";
- return;
- }
- }
-
- TypePtr keyType = dict->keyType();
- TypePtr valueType = dict->valueType();
- if(marshal)
- {
- if(optionalParam)
- {
- out << nl;
- if(optionalMapping)
- {
- out << "if(" << param << " != null && " << param << ".isPresent() && " << stream
- << ".writeOptional(" << tag << ", " << getOptionalFormat(type) << "))";
- }
- else
- {
- out << "if(" << stream << ".writeOptional(" << tag << ", " << getOptionalFormat(type) << "))";
- }
- out << sb;
- }
-
- if(keyType->isVariableLength() || valueType->isVariableLength())
- {
- string d = optionalParam && optionalMapping ? param + ".get()" : param;
- out << nl << "int pos = " << stream << ".startSize();";
- writeDictionaryMarshalUnmarshalCode(out, package, dict, d, marshal, iter, true, customStream, metaData);
- out << nl << stream << ".endSize(pos);";
- }
- else
- {
- const size_t sz = keyType->minWireSize() + valueType->minWireSize();
- string d = optionalParam && optionalMapping ? param + ".get()" : param;
- out << nl << "final int optSize = " << d << " == null ? 0 : " << d << ".size();";
- out << nl << stream
- << ".writeSize(optSize > 254 ? optSize * " << sz << " + 5 : optSize * " << sz << " + 1);";
- writeDictionaryMarshalUnmarshalCode(out, package, dict, d, marshal, iter, true, customStream, metaData);
- }
-
- if(optionalParam)
- {
- out << eb;
- }
- }
- else
- {
- string d = optionalParam ? "optDict" : param;
- if(optionalParam)
- {
- out << nl << "if(" << stream << ".readOptional(" << tag << ", " << getOptionalFormat(type) << "))";
- out << sb;
- out << nl << typeS << ' ' << d << ';';
- }
- if(keyType->isVariableLength() || valueType->isVariableLength())
- {
- out << nl << stream << ".skip(4);";
- }
- else
- {
- out << nl << stream << ".skipSize();";
- }
- writeDictionaryMarshalUnmarshalCode(out, package, dict, d, marshal, iter, true, customStream, metaData);
- if(optionalParam)
- {
- out << nl << param << " = java.util.Optional.of(" << d << ");";
- out << eb;
- out << nl << "else";
- out << sb;
- out << nl << param << " = java.util.Optional.empty();";
- out << eb;
- }
- }
- }
- else
- {
- writeDictionaryMarshalUnmarshalCode(out, package, dict, param, marshal, iter, true, customStream, metaData);
- }
- return;
- }
-
- SequencePtr seq = SequencePtr::dynamicCast(type);
- if(seq)
- {
- if(optionalParam || mode == OptionalMember)
- {
- string ignore;
- TypePtr elemType = seq->type();
- BuiltinPtr eltBltin = BuiltinPtr::dynamicCast(elemType);
- if(!hasTypeMetaData(seq, metaData) && eltBltin && eltBltin->kind() < Builtin::KindObject)
- {
- string bs = builtinTable[eltBltin->kind()];
- if(marshal)
- {
- out << nl << stream << ".write" << bs << "Seq(" << tag << ", " << param << ");";
- return;
- }
- else if(mode != OptionalMember)
- {
- out << nl << param << " = " << stream << ".read" << bs << "Seq(" << tag << ");";
- return;
- }
- }
- else if(findMetaData("java:serializable", seq->getMetaData(), ignore))
- {
- if(marshal)
- {
- out << nl << stream << ".writeSerializable" << spar << tag << param << epar << ";";
- return;
- }
- else if(mode != OptionalMember)
- {
- out << nl << param << " = " << stream << ".readSerializable" << spar << tag << typeS + ".class" << epar << ";";
- return;
- }
- }
- else if(!hasTypeMetaData(seq, metaData) ||
- findMetaData("java:type", seq->getMetaData(), ignore) ||
- findMetaData("java:type", metaData, ignore))
- {
- string instanceType, formalType, origInstanceType, origFormalType;
- getSequenceTypes(seq, "", metaData, instanceType, formalType, false);
- getSequenceTypes(seq, "", StringList(), origInstanceType, origFormalType, false);
- if(formalType == origFormalType && (marshal || instanceType == origInstanceType))
- {
- string helper = getAbsolute(seq, package, "", "Helper");
- if(marshal)
- {
- out << nl << helper << ".write" << spar << stream << tag << param << epar << ";";
- return;
- }
- else if(mode != OptionalMember)
- {
- out << nl << param << " = " << helper << ".read" << spar << stream << tag << epar << ";";
- return;
- }
- }
- }
-
- if(marshal)
- {
- if(optionalParam)
- {
- out << nl;
- if(optionalMapping)
- {
- out << "if(" << param << " != null && " << param << ".isPresent() && " << stream
- << ".writeOptional(" << tag << ", " << getOptionalFormat(type) << "))";
- }
- else
- {
- out << "if(" << stream << ".writeOptional(" << tag << ", " << getOptionalFormat(type) << "))";
- }
- out << sb;
- }
-
- if(elemType->isVariableLength())
- {
- string s = optionalParam && optionalMapping ? param + ".get()" : param;
- out << nl << "int pos = " << stream << ".startSize();";
- writeSequenceMarshalUnmarshalCode(out, package, seq, s, true, iter, true, customStream, metaData);
- out << nl << stream << ".endSize(pos);";
- }
- else
- {
- const size_t sz = elemType->minWireSize();
- string s = optionalParam && optionalMapping ? param + ".get()" : param;
- if(sz > 1)
- {
- string ignore;
- out << nl << "final int optSize = " << s << " == null ? 0 : ";
- if(findMetaData("java:buffer", seq->getMetaData(), ignore) ||
- findMetaData("java:buffer", metaData, ignore))
- {
- out << s << ".remaining() / " << sz << ";";
- }
- else if(hasTypeMetaData(seq, metaData))
- {
- out << s << ".size();";
- }
- else
- {
- out << s << ".length;";
- }
- out << nl << stream << ".writeSize(optSize > 254 ? optSize * " << sz
- << " + 5 : optSize * " << sz << " + 1);";
- }
- writeSequenceMarshalUnmarshalCode(out, package, seq, s, true, iter, true, customStream, metaData);
- }
-
- if(optionalParam)
- {
- out << eb;
- }
- }
- else
- {
- const size_t sz = elemType->minWireSize();
- string s = optionalParam ? "optSeq" : param;
- if(optionalParam)
- {
- out << nl << "if(" << stream << ".readOptional(" << tag << ", " << getOptionalFormat(type) << "))";
- out << sb;
- out << nl << typeS << ' ' << s << ';';
- }
- if(elemType->isVariableLength())
- {
- out << nl << stream << ".skip(4);";
- }
- else if(sz > 1)
- {
- out << nl << stream << ".skipSize();";
- }
- writeSequenceMarshalUnmarshalCode(out, package, seq, s, false, iter, true, customStream, metaData);
- if(optionalParam)
- {
- out << nl << param << " = java.util.Optional.of(" << s << ");";
- out << eb;
- out << nl << "else";
- out << sb;
- out << nl << param << " = java.util.Optional.empty();";
- out << eb;
- }
- }
- }
- else
- {
- writeSequenceMarshalUnmarshalCode(out, package, seq, param, marshal, iter, true, customStream, metaData);
- }
- return;
- }
-
- ConstructedPtr constructed = ConstructedPtr::dynamicCast(type);
- StructPtr st = StructPtr::dynamicCast(type);
- assert(constructed);
- if(marshal)
- {
- if(optionalParam)
- {
- out << nl << typeS << ".ice_write(" << stream << ", " << tag << ", " << param << ");";
- }
- else
- {
- out << nl << typeS << ".ice_write(" << stream << ", " << param << ");";
- }
- }
- else
- {
- if(optionalParam)
- {
- out << nl << param << " = " << typeS << ".ice_read(" << stream << ", " << tag << ");";
- }
- else if(mode == OptionalMember && st)
- {
- out << nl << stream << (st->isVariableLength() ? ".skip(4);" : ".skipSize();");
- out << nl << param << " = " << typeS << ".ice_read(" << stream << ");";
- }
- else
- {
- out << nl << param << " = " << typeS << ".ice_read(" << stream << ");";
- }
- }
-}
-
-void
-Slice::JavaGenerator::writeDictionaryMarshalUnmarshalCode(Output& out,
- const string& package,
- const DictionaryPtr& dict,
- const string& param,
- bool marshal,
- int& iter,
- bool useHelper,
- const string& customStream,
- const StringList& metaData)
-{
- string stream = customStream;
- if(stream.empty())
- {
- stream = marshal ? "ostr" : "istr";
- }
-
- string v = param;
-
- //
- // We have to determine whether it's possible to use the
- // type's generated helper class for this marshal/unmarshal
- // task. Since the user may have specified a custom type in
- // metadata, it's possible that the helper class is not
- // compatible and therefore we'll need to generate the code
- // in-line instead.
- //
- // Specifically, there may be "local" metadata (i.e., from
- // a data member or parameter definition) that overrides the
- // original type. We'll compare the mapped types with and
- // without local metadata to determine whether we can use
- // the helper.
- //
- string instanceType, formalType, origInstanceType, origFormalType;
- getDictionaryTypes(dict, "", metaData, instanceType, formalType, false);
- getDictionaryTypes(dict, "", StringList(), origInstanceType, origFormalType, false);
- if(useHelper && formalType == origFormalType && (marshal || instanceType == origInstanceType))
- {
- //
- // If we can use the helper, it's easy.
- //
- string helper = getAbsolute(dict, package, "", "Helper");
- if(marshal)
- {
- out << nl << helper << ".write" << spar << stream << v << epar << ";";
- }
- else
- {
- out << nl << v << " = " << helper << ".read" << spar << stream << epar << ";";
- }
- return;
- }
-
- TypePtr key = dict->keyType();
- TypePtr value = dict->valueType();
-
- string keyS = typeToString(key, TypeModeIn, package);
- string valueS = typeToString(value, TypeModeIn, package);
-
- ostringstream o;
- o << iter;
- string iterS = o.str();
- iter++;
-
- if(marshal)
- {
- out << nl << "if(" << v << " == null)";
- out << sb;
- out << nl << "ostr.writeSize(0);";
- out << eb;
- out << nl << "else";
- out << sb;
- out << nl << "ostr.writeSize(" << v << ".size());";
- string keyObjectS = typeToObjectString(key, TypeModeIn, package);
- string valueObjectS = typeToObjectString(value, TypeModeIn, package);
- out << nl;
- out << "for(java.util.Map.Entry<" << keyObjectS << ", " << valueObjectS << "> e : " << v << ".entrySet())";
- out << sb;
- for(int i = 0; i < 2; i++)
- {
- string arg;
- TypePtr type;
- if(i == 0)
- {
- arg = "e.getKey()";
- type = key;
- }
- else
- {
- arg = "e.getValue()";
- type = value;
- }
- writeMarshalUnmarshalCode(out, package, type, OptionalNone, false, 0, arg, true, iter, customStream);
- }
- out << eb;
- out << eb;
- }
- else
- {
- out << nl << v << " = new " << instanceType << "();";
- out << nl << "int sz" << iterS << " = " << stream << ".readSize();";
- out << nl << "for(int i" << iterS << " = 0; i" << iterS << " < sz" << iterS << "; i" << iterS << "++)";
- out << sb;
-
- BuiltinPtr b = BuiltinPtr::dynamicCast(value);
- if(ClassDeclPtr::dynamicCast(value) || (b && b->usesClasses()))
- {
- out << nl << "final " << keyS << " key;";
- writeMarshalUnmarshalCode(out, package, key, OptionalNone, false, 0, "key", false, iter, customStream);
-
- string valueS = typeToObjectString(value, TypeModeIn, package);
- ostringstream patchParams;
- patchParams << "value -> " << v << ".put(key, value), " << valueS << ".class";
- writeMarshalUnmarshalCode(out, package, value, OptionalNone, false, 0, "value", false, iter, customStream,
- StringList(), patchParams.str());
- }
- else
- {
- out << nl << keyS << " key;";
- writeMarshalUnmarshalCode(out, package, key, OptionalNone, false, 0, "key", false, iter, customStream);
-
- out << nl << valueS << " value;";
- writeMarshalUnmarshalCode(out, package, value, OptionalNone, false, 0, "value", false, iter, customStream);
-
- BuiltinPtr builtin = BuiltinPtr::dynamicCast(value);
- if(!(builtin && builtin->usesClasses()) && !ClassDeclPtr::dynamicCast(value))
- {
- out << nl << "" << v << ".put(key, value);";
- }
- }
- out << eb;
- }
-}
-
-void
-Slice::JavaGenerator::writeSequenceMarshalUnmarshalCode(Output& out,
- const string& package,
- const SequencePtr& seq,
- const string& param,
- bool marshal,
- int& iter,
- bool useHelper,
- const string& customStream,
- const StringList& metaData)
-{
- string stream = customStream;
- if(stream.empty())
- {
- stream = marshal ? "ostr" : "istr";
- }
-
- string typeS = typeToString(seq, TypeModeIn, package);
- string v = param;
-
- //
- // If the sequence is a byte sequence, check if there's the serializable or protobuf metadata to
- // get rid of these two easy cases first.
- //
- BuiltinPtr builtin = BuiltinPtr::dynamicCast(seq->type());
- if(builtin && builtin->kind() == Builtin::KindByte)
- {
- string meta;
- static const string protobuf = "java:protobuf:";
- static const string serializable = "java:serializable:";
- if(seq->findMetaData(serializable, meta))
- {
- if(marshal)
- {
- out << nl << stream << ".writeSerializable(" << v << ");";
- }
- else
- {
- out << nl << v << " = " << stream << ".readSerializable(" << typeS << ".class);";
- }
- return;
- }
- else if(seq->findMetaData(protobuf, meta))
- {
- if(marshal)
- {
- out << nl << "if(!" << v << ".isInitialized())";
- out << sb;
- out << nl << "throw new com.zeroc.Ice.MarshalException(\"type not fully initialized\");";
- out << eb;
- out << nl << stream << ".writeByteSeq(" << v << ".toByteArray());";
- }
- else
- {
- string type = typeToString(seq, TypeModeIn, package);
- out << nl << "try";
- out << sb;
- out << nl << v << " = " << typeS << ".parseFrom(" << stream << ".readByteSeq());";
- out << eb;
- out << nl << "catch(com.google.protobuf.InvalidProtocolBufferException ex)";
- out << sb;
- out << nl << "throw new com.zeroc.Ice.MarshalException(ex);";
- out << eb;
- }
- return;
- }
- }
-
- static const char* builtinTable[] =
- {
- "Byte",
- "Bool",
- "Short",
- "Int",
- "Long",
- "Float",
- "Double",
- "String"
- };
-
- if(builtin &&
- (builtin->kind() == Builtin::KindByte || builtin->kind() == Builtin::KindShort ||
- builtin->kind() == Builtin::KindInt || builtin->kind() == Builtin::KindLong ||
- builtin->kind() == Builtin::KindFloat || builtin->kind() == Builtin::KindDouble))
- {
- string meta;
- static const string bytebuffer = "java:buffer";
- if(seq->findMetaData(bytebuffer, meta) || findMetaData(bytebuffer, metaData, meta))
- {
- if(marshal)
- {
- out << nl << stream << ".write" << builtinTable[builtin->kind()] << "Buffer(" << v << ");";
- }
- else
- {
- out << nl << v << " = " << stream << ".read" << builtinTable[builtin->kind()] << "Buffer();";
- }
- return;
- }
- }
-
- if(!hasTypeMetaData(seq, metaData) && builtin && builtin->kind() <= Builtin::KindString)
- {
- if(marshal)
- {
- out << nl << stream << ".write" << builtinTable[builtin->kind()] << "Seq(" << v << ");";
- }
- else
- {
- out << nl << v << " = " << stream << ".read" << builtinTable[builtin->kind()] << "Seq();";
- }
- return;
- }
-
- //
- // We have to determine whether it's possible to use the
- // type's generated helper class for this marshal/unmarshal
- // task. Since the user may have specified a custom type in
- // metadata, it's possible that the helper class is not
- // compatible and therefore we'll need to generate the code
- // in-line instead.
- //
- // Specifically, there may be "local" metadata (i.e., from
- // a data member or parameter definition) that overrides the
- // original type. We'll compare the mapped types with and
- // without local metadata to determine whether we can use
- // the helper.
- //
- string instanceType, formalType, origInstanceType, origFormalType;
- bool customType = getSequenceTypes(seq, "", metaData, instanceType, formalType, false);
- getSequenceTypes(seq, "", StringList(), origInstanceType, origFormalType, false);
- if(useHelper && formalType == origFormalType && (marshal || instanceType == origInstanceType))
- {
- //
- // If we can use the helper, it's easy.
- //
- string helper = getAbsolute(seq, package, "", "Helper");
- if(marshal)
- {
- out << nl << helper << ".write" << spar << stream << v << epar << ";";
- }
- else
- {
- out << nl << v << " = " << helper << ".read" << spar << stream << epar << ";";
- }
- return;
- }
-
- //
- // Determine sequence depth.
- //
- int depth = 0;
- TypePtr origContent = seq->type();
- SequencePtr s = SequencePtr::dynamicCast(origContent);
- while(s)
- {
- //
- // Stop if the inner sequence type has a custom, serializable or protobuf type.
- //
- if(hasTypeMetaData(s))
- {
- break;
- }
- depth++;
- origContent = s->type();
- s = SequencePtr::dynamicCast(origContent);
- }
- string origContentS = typeToString(origContent, TypeModeIn, package);
-
- TypePtr type = seq->type();
-
- if(customType)
- {
- //
- // Marshal/unmarshal a custom sequence type.
- //
- BuiltinPtr b = BuiltinPtr::dynamicCast(type);
- string typeS = getAbsolute(seq, package);
- ostringstream o;
- o << origContentS;
- int d = depth;
- while(d--)
- {
- o << "[]";
- }
- string cont = o.str();
- if(marshal)
- {
- out << nl << "if(" << v << " == null)";
- out << sb;
- out << nl << stream << ".writeSize(0);";
- out << eb;
- out << nl << "else";
- out << sb;
- out << nl << stream << ".writeSize(" << v << ".size());";
- string typeS = typeToString(type, TypeModeIn, package);
- out << nl << "for(" << typeS << " elem : " << v << ')';
- out << sb;
- writeMarshalUnmarshalCode(out, package, type, OptionalNone, false, 0, "elem", true, iter, customStream);
- out << eb;
- out << eb; // else
- }
- else
- {
- bool isObject = false;
- ClassDeclPtr cl = ClassDeclPtr::dynamicCast(type);
- if((b && b->usesClasses()) || cl)
- {
- isObject = true;
- }
- out << nl << v << " = new " << instanceType << "();";
- out << nl << "final int len" << iter << " = " << stream << ".readAndCheckSeqSize(" << type->minWireSize()
- << ");";
- out << nl << "for(int i" << iter << " = 0; i" << iter << " < len" << iter << "; i" << iter << "++)";
- out << sb;
- if(isObject)
- {
- //
- // Add a null value to the list as a placeholder for the element.
- //
- out << nl << v << ".add(null);";
- ostringstream patchParams;
- out << nl << "final int fi" << iter << " = i" << iter << ";";
- patchParams << "value -> " << v << ".set(fi" << iter << ", value), " << origContentS << ".class";
-
- writeMarshalUnmarshalCode(out, package, type, OptionalNone, false, 0, "elem", false, iter,
- customStream, StringList(), patchParams.str());
- }
- else
- {
- out << nl << cont << " elem;";
- writeMarshalUnmarshalCode(out, package, type, OptionalNone, false, 0, "elem", false, iter, customStream);
- out << nl << v << ".add(elem);";
- }
- out << eb;
- iter++;
- }
- }
- else
- {
- BuiltinPtr b = BuiltinPtr::dynamicCast(type);
- if(b && b->kind() != Builtin::KindObject &&
- b->kind() != Builtin::KindValue &&
- b->kind() != Builtin::KindObjectProxy)
- {
- switch(b->kind())
- {
- case Builtin::KindByte:
- {
- if(marshal)
- {
- out << nl << stream << ".writeByteSeq(" << v << ");";
- }
- else
- {
- out << nl << v << " = " << stream << ".readByteSeq();";
- }
- break;
- }
- case Builtin::KindBool:
- {
- if(marshal)
- {
- out << nl << stream << ".writeBoolSeq(" << v << ");";
- }
- else
- {
- out << nl << v << " = " << stream << ".readBoolSeq();";
- }
- break;
- }
- case Builtin::KindShort:
- {
- if(marshal)
- {
- out << nl << stream << ".writeShortSeq(" << v << ");";
- }
- else
- {
- out << nl << v << " = " << stream << ".readShortSeq();";
- }
- break;
- }
- case Builtin::KindInt:
- {
- if(marshal)
- {
- out << nl << stream << ".writeIntSeq(" << v << ");";
- }
- else
- {
- out << nl << v << " = " << stream << ".readIntSeq();";
- }
- break;
- }
- case Builtin::KindLong:
- {
- if(marshal)
- {
- out << nl << stream << ".writeLongSeq(" << v << ");";
- }
- else
- {
- out << nl << v << " = " << stream << ".readLongSeq();";
- }
- break;
- }
- case Builtin::KindFloat:
- {
- if(marshal)
- {
- out << nl << stream << ".writeFloatSeq(" << v << ");";
- }
- else
- {
- out << nl << v << " = " << stream << ".readFloatSeq();";
- }
- break;
- }
- case Builtin::KindDouble:
- {
- if(marshal)
- {
- out << nl << stream << ".writeDoubleSeq(" << v << ");";
- }
- else
- {
- out << nl << v << " = " << stream << ".readDoubleSeq();";
- }
- break;
- }
- case Builtin::KindString:
- {
- if(marshal)
- {
- out << nl << stream << ".writeStringSeq(" << v << ");";
- }
- else
- {
- out << nl << v << " = " << stream << ".readStringSeq();";
- }
- break;
- }
- case Builtin::KindValue:
- case Builtin::KindObject:
- case Builtin::KindObjectProxy:
- case Builtin::KindLocalObject:
- {
- assert(false);
- break;
- }
- }
- }
- else
- {
- if(marshal)
- {
- out << nl << "if(" << v << " == null)";
- out << sb;
- out << nl << stream << ".writeSize(0);";
- out << eb;
- out << nl << "else";
- out << sb;
- out << nl << stream << ".writeSize(" << v << ".length);";
- out << nl << "for(int i" << iter << " = 0; i" << iter << " < " << v << ".length; i" << iter
- << "++)";
- out << sb;
- ostringstream o;
- o << v << "[i" << iter << "]";
- iter++;
- writeMarshalUnmarshalCode(out, package, type, OptionalNone, false, 0, o.str(), true, iter, customStream);
- out << eb;
- out << eb;
- }
- else
- {
- bool isObject = false;
- ClassDeclPtr cl = ClassDeclPtr::dynamicCast(origContent);
- if((b && b->usesClasses()) || cl)
- {
- isObject = true;
- }
- out << nl << "final int len" << iter << " = " << stream << ".readAndCheckSeqSize("
- << type->minWireSize() << ");";
- //
- // We cannot allocate an array of a generic type, such as
- //
- // arr = new Map<String, String>[sz];
- //
- // Attempting to compile this code results in a "generic array creation" error
- // message. This problem can occur when the sequence's element type is a
- // dictionary, or when the element type is a nested sequence that uses a custom
- // mapping.
- //
- // The solution is to rewrite the code as follows:
- //
- // arr = (Map<String, String>[])new Map[sz];
- //
- // Unfortunately, this produces an unchecked warning during compilation.
- //
- // A simple test is to look for a "<" character in the content type, which
- // indicates the use of a generic type.
- //
- string::size_type pos = origContentS.find('<');
- if(pos != string::npos)
- {
- string nonGenericType = origContentS.substr(0, pos);
- out << nl << v << " = (" << origContentS << "[]";
- int d = depth;
- while(d--)
- {
- out << "[]";
- }
- out << ")new " << nonGenericType << "[len" << iter << "]";
- }
- else
- {
- out << nl << v << " = new " << origContentS << "[len" << iter << "]";
- }
- int d = depth;
- while(d--)
- {
- out << "[]";
- }
- out << ';';
- out << nl << "for(int i" << iter << " = 0; i" << iter << " < len" << iter << "; i" << iter
- << "++)";
- out << sb;
- ostringstream o;
- o << v << "[i" << iter << "]";
- if(isObject)
- {
- ostringstream patchParams;
- out << nl << "final int fi" << iter << " = i" << iter << ";";
- patchParams << "value -> " << v << "[fi" << iter << "] = value, " << origContentS << ".class";
- writeMarshalUnmarshalCode(out, package, type, OptionalNone, false, 0, o.str(), false, iter,
- customStream, StringList(), patchParams.str());
- }
- else
- {
- writeMarshalUnmarshalCode(out, package, type, OptionalNone, false, 0, o.str(), false, iter, customStream);
- }
- out << eb;
- iter++;
- }
- }
- }
-}
-
-bool
-Slice::JavaGenerator::findMetaData(const string& prefix, const StringList& metaData, string& value)
-{
- for(StringList::const_iterator q = metaData.begin(); q != metaData.end(); ++q)
- {
- if(q->find(prefix) == 0)
- {
- value = *q;
- return true;
- }
- }
-
- return false;
-}
-
-bool
-Slice::JavaGenerator::getTypeMetaData(const StringList& metaData, string& instanceType, string& formalType)
-{
- //
- // Extract the instance type and an optional formal type.
- // The correct syntax is "java:type:instance-type[:formal-type]".
- //
- static const string prefix = "java:type:";
- string directive;
- if(findMetaData(prefix, metaData, directive))
- {
- string::size_type pos = directive.find(':', prefix.size());
- if(pos != string::npos)
- {
- instanceType = directive.substr(prefix.size(), pos - prefix.size());
- formalType = directive.substr(pos + 1);
- }
- else
- {
- instanceType = directive.substr(prefix.size());
- formalType.clear();
- }
- return true;
- }
-
- return false;
-}
-
-bool
-Slice::JavaGenerator::hasTypeMetaData(const TypePtr& type, const StringList& localMetaData)
-{
- ContainedPtr cont = ContainedPtr::dynamicCast(type);
- if(cont)
- {
- static const string prefix = "java:type:";
- string directive;
-
- if(findMetaData(prefix, localMetaData, directive))
- {
- return true;
- }
-
- StringList metaData = cont->getMetaData();
-
- if(findMetaData(prefix, metaData, directive))
- {
- return true;
- }
-
- if(findMetaData("java:protobuf:", metaData, directive) ||
- findMetaData("java:serializable:", metaData, directive))
- {
- SequencePtr seq = SequencePtr::dynamicCast(cont);
- if(seq)
- {
- BuiltinPtr builtin = BuiltinPtr::dynamicCast(seq->type());
- if(builtin && builtin->kind() == Builtin::KindByte)
- {
- return true;
- }
- }
- }
-
- if(findMetaData("java:buffer", metaData, directive) ||
- findMetaData("java:buffer", localMetaData, directive))
- {
- SequencePtr seq = SequencePtr::dynamicCast(cont);
- if(seq)
- {
- BuiltinPtr builtin = BuiltinPtr::dynamicCast(seq->type());
- if(builtin &&
- (builtin->kind() == Builtin::KindByte || builtin->kind() == Builtin::KindShort ||
- builtin->kind() == Builtin::KindInt || builtin->kind() == Builtin::KindLong ||
- builtin->kind() == Builtin::KindFloat || builtin->kind() == Builtin::KindDouble))
- {
- return true;
- }
- }
- }
- }
-
- return false;
-}
-
-bool
-Slice::JavaGenerator::getDictionaryTypes(const DictionaryPtr& dict,
- const string& package,
- const StringList& metaData,
- string& instanceType,
- string& formalType,
- bool local) const
-{
- //
- // Get the types of the key and value.
- //
- string keyTypeStr = typeToObjectString(dict->keyType(), TypeModeIn, package, StringList(), true, local);
- string valueTypeStr = typeToObjectString(dict->valueType(), TypeModeIn, package, StringList(), true, local);
-
- //
- // Collect metadata for a custom type.
- //
- if(getTypeMetaData(metaData, instanceType, formalType) ||
- getTypeMetaData(dict->getMetaData(), instanceType, formalType))
- {
- assert(!instanceType.empty());
- if(formalType.empty())
- {
- formalType = "java.util.Map<" + keyTypeStr + ", " + valueTypeStr + ">";
- }
- return true;
- }
-
- //
- // Return a default type for the platform.
- //
- instanceType = "java.util.HashMap<" + keyTypeStr + ", " + valueTypeStr + ">";
- formalType = "java.util.Map<" + keyTypeStr + ", " + valueTypeStr + ">";
- return false;
-}
-
-bool
-Slice::JavaGenerator::getSequenceTypes(const SequencePtr& seq,
- const string& package,
- const StringList& metaData,
- string& instanceType,
- string& formalType,
- bool local) const
-{
- BuiltinPtr builtin = BuiltinPtr::dynamicCast(seq->type());
- if(builtin)
- {
- if(builtin->kind() == Builtin::KindByte)
- {
- string prefix = "java:serializable:";
- string meta;
- if(seq->findMetaData(prefix, meta))
- {
- instanceType = formalType = meta.substr(prefix.size());
- return true;
- }
- prefix = "java:protobuf:";
- if(seq->findMetaData(prefix, meta))
- {
- instanceType = formalType = meta.substr(prefix.size());
- return true;
- }
- }
-
- if((builtin->kind() == Builtin::KindByte || builtin->kind() == Builtin::KindShort ||
- builtin->kind() == Builtin::KindInt || builtin->kind() == Builtin::KindLong ||
- builtin->kind() == Builtin::KindFloat || builtin->kind() == Builtin::KindDouble))
- {
- string prefix = "java:buffer";
- string meta;
- string ignore;
- if(seq->findMetaData(prefix, meta) || findMetaData(prefix, metaData, ignore))
- {
- instanceType = formalType = typeToBufferString(seq->type());
- return true;
- }
- }
- }
-
- //
- // Collect metadata for a custom type.
- //
- if(getTypeMetaData(metaData, instanceType, formalType) ||
- getTypeMetaData(seq->getMetaData(), instanceType, formalType))
- {
- assert(!instanceType.empty());
- if(formalType.empty())
- {
- formalType = "java.util.List<" +
- typeToObjectString(seq->type(), TypeModeIn, package, StringList(), true, local) + ">";
- }
- return true;
- }
-
- //
- // The default mapping is a native array.
- //
- instanceType = formalType = typeToString(seq->type(), TypeModeIn, package, metaData, true, false, local) + "[]";
- return false;
-}
-
-JavaOutput*
-Slice::JavaGenerator::createOutput()
-{
- return new JavaOutput;
-}
-
-void
-Slice::JavaGenerator::validateMetaData(const UnitPtr& u)
-{
- MetaDataVisitor visitor;
- u->visit(&visitor, true);
-}
diff --git a/cpp/src/Slice/MD5.cpp b/cpp/src/Slice/MD5.cpp
index 3d881b36b6a..8b14ada3f36 100644
--- a/cpp/src/Slice/MD5.cpp
+++ b/cpp/src/Slice/MD5.cpp
@@ -1,6 +1,6 @@
// **********************************************************************
//
-// Copyright (c) 2003-2016 ZeroC, Inc. All rights reserved.
+// Copyright (c) 2003-2017 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.
diff --git a/cpp/src/Slice/MD5.h b/cpp/src/Slice/MD5.h
index 182a89bb9b7..9e339d27080 100644
--- a/cpp/src/Slice/MD5.h
+++ b/cpp/src/Slice/MD5.h
@@ -1,6 +1,6 @@
// **********************************************************************
//
-// Copyright (c) 2003-2016 ZeroC, Inc. All rights reserved.
+// Copyright (c) 2003-2017 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.
diff --git a/cpp/src/Slice/PHPUtil.cpp b/cpp/src/Slice/PHPUtil.cpp
index 8db417bd24c..09114294b32 100644
--- a/cpp/src/Slice/PHPUtil.cpp
+++ b/cpp/src/Slice/PHPUtil.cpp
@@ -1,6 +1,6 @@
// **********************************************************************
//
-// Copyright (c) 2003-2016 ZeroC, Inc. All rights reserved.
+// Copyright (c) 2003-2017 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.
diff --git a/cpp/src/Slice/Parser.cpp b/cpp/src/Slice/Parser.cpp
index ca774ef54a8..00fb1d42047 100644
--- a/cpp/src/Slice/Parser.cpp
+++ b/cpp/src/Slice/Parser.cpp
@@ -1,6 +1,6 @@
// **********************************************************************
//
-// Copyright (c) 2003-2016 ZeroC, Inc. All rights reserved.
+// Copyright (c) 2003-2017 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.
diff --git a/cpp/src/Slice/Preprocessor.cpp b/cpp/src/Slice/Preprocessor.cpp
index aa47dd1e716..9ed4eee10ab 100644
--- a/cpp/src/Slice/Preprocessor.cpp
+++ b/cpp/src/Slice/Preprocessor.cpp
@@ -1,6 +1,6 @@
// **********************************************************************
//
-// Copyright (c) 2003-2016 ZeroC, Inc. All rights reserved.
+// Copyright (c) 2003-2017 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.
diff --git a/cpp/src/Slice/Python.cpp b/cpp/src/Slice/Python.cpp
index bc1da962d70..a866992af48 100644
--- a/cpp/src/Slice/Python.cpp
+++ b/cpp/src/Slice/Python.cpp
@@ -1,6 +1,6 @@
// **********************************************************************
//
-// Copyright (c) 2003-2016 ZeroC, Inc. All rights reserved.
+// Copyright (c) 2003-2017 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.
diff --git a/cpp/src/Slice/PythonUtil.cpp b/cpp/src/Slice/PythonUtil.cpp
index bb21315c21a..05c928c0e7d 100644
--- a/cpp/src/Slice/PythonUtil.cpp
+++ b/cpp/src/Slice/PythonUtil.cpp
@@ -1,6 +1,6 @@
// **********************************************************************
//
-// Copyright (c) 2003-2016 ZeroC, Inc. All rights reserved.
+// Copyright (c) 2003-2017 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.
@@ -2959,7 +2959,7 @@ Slice::Python::printHeader(IceUtilInternal::Output& out)
static const char* header =
"# **********************************************************************\n"
"#\n"
-"# Copyright (c) 2003-2016 ZeroC, Inc. All rights reserved.\n"
+"# Copyright (c) 2003-2017 ZeroC, Inc. All rights reserved.\n"
"#\n"
"# This copy of Ice is licensed to you under the terms described in the\n"
"# ICE_LICENSE file included in this distribution.\n"
diff --git a/cpp/src/Slice/Ruby.cpp b/cpp/src/Slice/Ruby.cpp
index 7861bcb8c0b..310b84bf4a6 100644
--- a/cpp/src/Slice/Ruby.cpp
+++ b/cpp/src/Slice/Ruby.cpp
@@ -1,6 +1,6 @@
// **********************************************************************
//
-// Copyright (c) 2003-2016 ZeroC, Inc. All rights reserved.
+// Copyright (c) 2003-2017 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.
diff --git a/cpp/src/Slice/RubyUtil.cpp b/cpp/src/Slice/RubyUtil.cpp
index 3a670035bc4..b27f91d75bb 100644
--- a/cpp/src/Slice/RubyUtil.cpp
+++ b/cpp/src/Slice/RubyUtil.cpp
@@ -1,6 +1,6 @@
// **********************************************************************
//
-// Copyright (c) 2003-2016 ZeroC, Inc. All rights reserved.
+// Copyright (c) 2003-2017 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.
@@ -1562,7 +1562,7 @@ Slice::Ruby::printHeader(IceUtilInternal::Output& out)
static const char* header =
"# **********************************************************************\n"
"#\n"
-"# Copyright (c) 2003-2016 ZeroC, Inc. All rights reserved.\n"
+"# Copyright (c) 2003-2017 ZeroC, Inc. All rights reserved.\n"
"#\n"
"# This copy of Ice is licensed to you under the terms described in the\n"
"# ICE_LICENSE file included in this distribution.\n"
diff --git a/cpp/src/Slice/Scanner.cpp b/cpp/src/Slice/Scanner.cpp
index 8d14ff3cd30..b338b8e5390 100644
--- a/cpp/src/Slice/Scanner.cpp
+++ b/cpp/src/Slice/Scanner.cpp
@@ -611,7 +611,7 @@ char *slice_text;
// **********************************************************************
//
-// Copyright (c) 2003-2016 ZeroC, Inc. All rights reserved.
+// Copyright (c) 2003-2017 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.
diff --git a/cpp/src/Slice/Scanner.l b/cpp/src/Slice/Scanner.l
index e2a825c0deb..6aa153f039d 100644
--- a/cpp/src/Slice/Scanner.l
+++ b/cpp/src/Slice/Scanner.l
@@ -2,7 +2,7 @@
// **********************************************************************
//
-// Copyright (c) 2003-2016 ZeroC, Inc. All rights reserved.
+// Copyright (c) 2003-2017 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.