summaryrefslogtreecommitdiff
path: root/cpp/src
diff options
context:
space:
mode:
Diffstat (limited to 'cpp/src')
-rw-r--r--cpp/src/Slice/JavaUtil.cpp787
-rw-r--r--cpp/src/slice2java/Gen.cpp223
-rw-r--r--cpp/src/slice2java/Gen.h3
3 files changed, 800 insertions, 213 deletions
diff --git a/cpp/src/Slice/JavaUtil.cpp b/cpp/src/Slice/JavaUtil.cpp
index dfca45db6ae..fc88786c836 100644
--- a/cpp/src/Slice/JavaUtil.cpp
+++ b/cpp/src/Slice/JavaUtil.cpp
@@ -275,7 +275,8 @@ Slice::JavaGenerator::getAbsolute(const string& scoped,
string
Slice::JavaGenerator::typeToString(const TypePtr& type,
TypeMode mode,
- const string& scope) const
+ const string& scope,
+ const list<string>& metaData) const
{
static const char* builtinTable[] =
{
@@ -369,8 +370,21 @@ Slice::JavaGenerator::typeToString(const TypePtr& type,
}
else
{
- TypePtr content = seq->type();
- return typeToString(content, mode, scope) + "[]";
+ string listType = findMetaData(metaData);
+ if (listType.empty())
+ {
+ list<string> l = seq->getMetaData();
+ listType = findMetaData(l);
+ }
+ if (!listType.empty())
+ {
+ return listType;
+ }
+ else
+ {
+ TypePtr content = seq->type();
+ return typeToString(content, mode, scope) + "[]";
+ }
}
}
@@ -397,7 +411,8 @@ Slice::JavaGenerator::writeMarshalUnmarshalCode(Output& out,
const string& param,
bool marshal,
int& iter,
- bool holder)
+ bool holder,
+ const list<string>& metaData)
{
string stream = marshal ? "__os" : "__is";
string v;
@@ -617,8 +632,320 @@ Slice::JavaGenerator::writeMarshalUnmarshalCode(Output& out,
SequencePtr seq = SequencePtr::dynamicCast(type);
if (seq)
{
+ writeSequenceMarshalUnmarshalCode(out, scope, seq, v, marshal, iter, true, metaData);
+ return;
+ }
+
+ ConstructedPtr constructed = ConstructedPtr::dynamicCast(type);
+ assert(constructed);
+ string typeS = getAbsolute(constructed->scoped(), scope);
+ if (marshal)
+ {
+ out << nl << typeS << "Helper.write(" << stream << ", " << v << ");";
+ }
+ else
+ {
+ out << nl << v << " = " << typeS << "Helper.read(" << stream << ");";
+ }
+}
+
+void
+Slice::JavaGenerator::writeSequenceMarshalUnmarshalCode(Output& out,
+ const string& scope,
+ const SequencePtr& seq,
+ const string& param,
+ bool marshal,
+ int& iter,
+ bool useHelper,
+ const list<string>& metaData)
+{
+ string stream = marshal ? "__os" : "__is";
+ string v = param;
+
+ //
+ // Check for metadata that overrides the default sequence
+ // mapping. If no metadata is found, we use a regular Java
+ // array. If metadata is found, the value of the metadata
+ // must be the name of a class which implements the
+ // java.util.List interface.
+ //
+ // There are two sources of metadata - that passed into
+ // this function (which most likely comes from a data
+ // member definition), and that associated with the type
+ // itself. If data member metadata is found, and does
+ // not match the type's metadata, then we cannot use
+ // the type's Helper class for marshalling - we must
+ // generate marshalling code inline.
+ //
+ string listType = findMetaData(metaData);
+ list<string> typeMetaData = seq->getMetaData();
+ if (listType.empty())
+ {
+ listType = findMetaData(typeMetaData);
+ }
+ else
+ {
+ string s = findMetaData(typeMetaData);
+ if (listType != s)
+ {
+ useHelper = false;
+ }
+ }
+
+ //
+ // If we can use the sequence's helper, it's easy.
+ //
+ if (useHelper)
+ {
+ string typeS = getAbsolute(seq->scoped(), scope);
+ if (marshal)
+ {
+ out << nl << typeS << "Helper.write(" << stream << ", " << v << ");";
+ }
+ else
+ {
+ out << nl << v << " = " << typeS << "Helper.read(" << stream << ");";
+ }
+ return;
+ }
+
+ //
+ // Determine sequence depth
+ //
+ int depth = 0;
+ TypePtr origContent = seq->type();
+ SequencePtr s = SequencePtr::dynamicCast(origContent);
+ while (s)
+ {
+ depth++;
+ origContent = s->type();
+ s = SequencePtr::dynamicCast(origContent);
+ }
+ string origContentS = typeToString(origContent, TypeModeIn, scope);
+
+ if (!listType.empty())
+ {
+ BuiltinPtr b = BuiltinPtr::dynamicCast(seq->type());
+ if (b && b->kind() != Builtin::KindObject && b->kind() != Builtin::KindObjectProxy)
+ {
+ if (marshal)
+ {
+ out << nl << stream << ".writeSize(" << v << ".size());";
+ ostringstream o;
+ o << "__i" << iter;
+ string it = o.str();
+ iter++;
+ out << nl << "java.util.Iterator " << it << " = " << v << ".iterator();";
+ out << nl << "while (" << it << ".hasNext())";
+ out << sb;
+
+ switch (b->kind())
+ {
+ case Builtin::KindByte:
+ {
+ out << nl << "java.lang.Byte __elem = (java.lang.Byte)" << it << ".next();";
+ out << nl << stream << ".writeByte(__elem.byteValue());";
+ break;
+ }
+ case Builtin::KindBool:
+ {
+ out << nl << "java.lang.Boolean __elem = (java.lang.Boolean)" << it << ".next();";
+ out << nl << stream << ".writeBool(__elem.booleanValue());";
+ break;
+ }
+ case Builtin::KindShort:
+ {
+ out << nl << "java.lang.Short __elem = (java.lang.Short)" << it << ".next();";
+ out << nl << stream << ".writeShort(__elem.shortValue());";
+ break;
+ }
+ case Builtin::KindInt:
+ {
+ out << nl << "java.lang.Integer __elem = (java.lang.Integer)" << it << ".next();";
+ out << nl << stream << ".writeInt(__elem.intValue());";
+ break;
+ }
+ case Builtin::KindLong:
+ {
+ out << nl << "java.lang.Long __elem = (java.lang.Long)" << it << ".next();";
+ out << nl << stream << ".writeLong(__elem.longValue());";
+ break;
+ }
+ case Builtin::KindFloat:
+ {
+ out << nl << "java.lang.Float __elem = (java.lang.Float)" << it << ".next();";
+ out << nl << stream << ".writeFloat(__elem.floatValue());";
+ break;
+ }
+ case Builtin::KindDouble:
+ {
+ out << nl << "java.lang.Double __elem = (java.lang.Double)" << it << ".next();";
+ out << nl << stream << ".writeDouble(__elem.doubleValue());";
+ break;
+ }
+ case Builtin::KindString:
+ {
+ out << nl << "java.lang.String __elem = (java.lang.String)" << it << ".next();";
+ out << nl << stream << ".writeString(__elem);";
+ break;
+ }
+ case Builtin::KindObject:
+ case Builtin::KindObjectProxy:
+ case Builtin::KindLocalObject:
+ {
+ assert(false);
+ break;
+ }
+ }
+ out << eb; // while
+ }
+ else
+ {
+ out << nl << v << " = new " << listType << "();";
+ ostringstream o;
+ o << origContentS << "[]";
+ int d = depth;
+ while (d--)
+ {
+ o << "[]";
+ }
+ switch (b->kind())
+ {
+ case Builtin::KindByte:
+ {
+ out << nl << o.str() << " __seq" << iter << " = " << stream << ".readByteSeq();";
+ out << nl << "for (int __i" << iter << " = 0; __i" << iter << " < __seq" << iter
+ << ".length; __i" << iter << "++)";
+ out << sb;
+ out << nl << v << ".add(new java.lang.Byte(__seq" << iter << "[__i" << iter << "]));";
+ out << eb;
+ iter++;
+ break;
+ }
+ case Builtin::KindBool:
+ {
+ out << nl << o.str() << " __seq" << iter << " = " << stream << ".readByteSeq();";
+ out << nl << "for (int __i" << iter << " = 0; __i" << iter << " < __seq" << iter
+ << ".length; __i" << iter << "++)";
+ out << sb;
+ out << nl << v << ".add(__seq" << iter << "[__i" << iter
+ << "] ? java.lang.Boolean.TRUE : java.lang.Boolean.FALSE);";
+ out << eb;
+ iter++;
+ break;
+ }
+ case Builtin::KindShort:
+ {
+ out << nl << o.str() << " __seq" << iter << " = " << stream << ".readShortSeq();";
+ out << nl << "for (int __i" << iter << " = 0; __i" << iter << " < __seq" << iter
+ << ".length; __i" << iter << "++)";
+ out << sb;
+ out << nl << v << ".add(new java.lang.Short(__seq" << iter << "[__i" << iter << "]));";
+ out << eb;
+ iter++;
+ break;
+ }
+ case Builtin::KindInt:
+ {
+ out << nl << o.str() << " __seq" << iter << " = " << stream << ".readIntSeq();";
+ out << nl << "for (int __i" << iter << " = 0; __i" << iter << " < __seq" << iter
+ << ".length; __i" << iter << "++)";
+ out << sb;
+ out << nl << v << ".add(new java.lang.Integer(__seq" << iter << "[__i" << iter << "]));";
+ out << eb;
+ iter++;
+ break;
+ }
+ case Builtin::KindLong:
+ {
+ out << nl << o.str() << " __seq" << iter << " = " << stream << ".readLongSeq();";
+ out << nl << "for (int __i" << iter << " = 0; __i" << iter << " < __seq" << iter
+ << ".length; __i" << iter << "++)";
+ out << sb;
+ out << nl << v << ".add(new java.lang.Long(__seq" << iter << "[__i" << iter << "]));";
+ out << eb;
+ iter++;
+ break;
+ }
+ case Builtin::KindFloat:
+ {
+ out << nl << o.str() << " __seq" << iter << " = " << stream << ".readFloatSeq();";
+ out << nl << "for (int __i" << iter << " = 0; __i" << iter << " < __seq" << iter
+ << ".length; __i" << iter << "++)";
+ out << sb;
+ out << nl << v << ".add(new java.lang.Float(__seq" << iter << "[__i" << iter << "]));";
+ out << eb;
+ iter++;
+ break;
+ }
+ case Builtin::KindDouble:
+ {
+ out << nl << o.str() << " __seq" << iter << " = " << stream << ".readDoubleSeq();";
+ out << nl << "for (int __i" << iter << " = 0; __i" << iter << " < __seq" << iter
+ << ".length; __i" << iter << "++)";
+ out << sb;
+ out << nl << v << ".add(new java.lang.Double(__seq" << iter << "[__i" << iter << "]));";
+ out << eb;
+ iter++;
+ break;
+ }
+ case Builtin::KindString:
+ {
+ out << nl << o.str() << " __seq" << iter << " = " << stream << ".readStringSeq();";
+ out << nl << "for (int __i" << iter << " = 0; __i" << iter << " < __seq" << iter
+ << ".length; __i" << iter << "++)";
+ out << sb;
+ out << nl << v << ".add(__seq" << iter << "[__i" << iter << "]);";
+ out << eb;
+ iter++;
+ break;
+ }
+ case Builtin::KindObject:
+ case Builtin::KindObjectProxy:
+ case Builtin::KindLocalObject:
+ {
+ assert(false);
+ break;
+ }
+ }
+ }
+ }
+ else
+ {
+ string typeS = getAbsolute(seq->scoped(), scope);
+ if (marshal)
+ {
+ out << nl << stream << ".writeSize(" << v << ".size());";
+ ostringstream o;
+ o << "__i" << iter;
+ iter++;
+ string it = o.str();
+ out << nl << "java.util.Iterator " << it << " = " << v << ".iterator();";
+ out << nl << "while (" << it << ".hasNext())";
+ out << sb;
+ out << nl << origContentS << " __elem = (" << origContentS << ")" << it << ".next();";
+ writeMarshalUnmarshalCode(out, scope, seq->type(), "__elem", true, iter, false);
+ out << eb;
+ }
+ else
+ {
+ out << nl << v << " = new " << listType << "();";
+ out << nl << "int __len" << iter << " = " << stream << ".readSize();";
+ out << nl << "for (int __i" << iter << " = 0; __i" << iter << " < __len" << iter << "; __i" << iter
+ << "++);";
+ out << sb;
+ out << nl << origContentS << " __elem;";
+ iter++;
+ writeMarshalUnmarshalCode(out, scope, seq->type(), "__elem", false, iter, false);
+ out << nl << v << ".add(__elem);";
+ out << eb;
+ }
+ }
+ }
+ else
+ {
BuiltinPtr b = BuiltinPtr::dynamicCast(seq->type());
- if (b)
+ if (b && b->kind() != Builtin::KindObject && b->kind() != Builtin::KindObjectProxy)
{
switch (b->kind())
{
@@ -720,18 +1047,6 @@ Slice::JavaGenerator::writeMarshalUnmarshalCode(Output& out,
}
case Builtin::KindObject:
case Builtin::KindObjectProxy:
- {
- string typeS = getAbsolute(seq->scoped(), scope);
- if (marshal)
- {
- out << nl << typeS << "Helper.write(" << stream << ", " << v << ");";
- }
- else
- {
- out << nl << v << " = " << typeS << "Helper.read(" << stream << ");";
- }
- break;
- }
case Builtin::KindLocalObject:
{
assert(false);
@@ -741,31 +1056,38 @@ Slice::JavaGenerator::writeMarshalUnmarshalCode(Output& out,
}
else
{
- ContainedPtr cont = ContainedPtr::dynamicCast(type);
- assert(cont);
- string typeS = getAbsolute(cont->scoped(), scope);
if (marshal)
{
- out << nl << typeS << "Helper.write(" << stream << ", " << v << ");";
+ 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, scope, seq->type(), o.str(), true, iter, false);
+ out << eb;
}
else
{
- out << nl << v << " = " << typeS << "Helper.read(" << stream << ");";
+ out << nl << "int __len" << iter << " = " << stream << ".readSize();";
+ 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 << "]";
+ iter++;
+ writeMarshalUnmarshalCode(out, scope, seq->type(), o.str(), false, iter, false);
+ out << eb;
}
}
- return;
- }
-
- ConstructedPtr constructed = ConstructedPtr::dynamicCast(type);
- assert(constructed);
- string typeS = getAbsolute(constructed->scoped(), scope);
- if (marshal)
- {
- out << nl << typeS << "Helper.write(" << stream << ", " << v << ");";
- }
- else
- {
- out << nl << v << " = " << typeS << "Helper.read(" << stream << ");";
}
}
@@ -777,7 +1099,8 @@ Slice::JavaGenerator::writeGenericMarshalUnmarshalCode(Output& out,
const string& param,
bool marshal,
int& iter,
- bool holder)
+ bool holder,
+ const list<string>& metaData)
{
string stream = marshal ? "__os" : "__is";
string v;
@@ -1007,8 +1330,325 @@ Slice::JavaGenerator::writeGenericMarshalUnmarshalCode(Output& out,
SequencePtr seq = SequencePtr::dynamicCast(type);
if (seq)
{
+ writeGenericSequenceMarshalUnmarshalCode(out, scope, seq, name, v, marshal, iter, true, metaData);
+ return;
+ }
+
+ ConstructedPtr constructed = ConstructedPtr::dynamicCast(type);
+ assert(constructed);
+ string typeS = getAbsolute(constructed->scoped(), scope);
+ if (marshal)
+ {
+ out << nl << typeS << "Helper.ice_marshal(" << name << ", " << stream << ", " << v << ");";
+ }
+ else
+ {
+ out << nl << v << " = " << typeS << "Helper.ice_unmarshal(" << name << ", " << stream << ");";
+ }
+}
+
+void
+Slice::JavaGenerator::writeGenericSequenceMarshalUnmarshalCode(Output& out,
+ const string& scope,
+ const SequencePtr& seq,
+ const string& name,
+ const string& param,
+ bool marshal,
+ int& iter,
+ bool useHelper,
+ const list<string>& metaData)
+{
+ string stream = marshal ? "__os" : "__is";
+ string v = param;
+
+ //
+ // Check for metadata that overrides the default sequence
+ // mapping. If no metadata is found, we use a regular Java
+ // array. If metadata is found, the value of the metadata
+ // must be the name of a class which implements the
+ // java.util.List interface.
+ //
+ // There are two sources of metadata - that passed into
+ // this function (which most likely comes from a data
+ // member definition), and that associated with the type
+ // itself. If data member metadata is found, and does
+ // not match the type's metadata, then we cannot use
+ // the type's Helper class for marshalling - we must
+ // generate marshalling code inline.
+ //
+ string listType = findMetaData(metaData);
+ list<string> typeMetaData = seq->getMetaData();
+ if (listType.empty())
+ {
+ listType = findMetaData(typeMetaData);
+ }
+ else
+ {
+ string s = findMetaData(typeMetaData);
+ if (listType != s)
+ {
+ useHelper = false;
+ }
+ }
+
+ //
+ // If we can use the sequence's helper, it's easy.
+ //
+ if (useHelper)
+ {
+ string typeS = getAbsolute(seq->scoped(), scope);
+ if (marshal)
+ {
+ out << nl << typeS << "Helper.ice_marshal(" << name << ", " << stream << ", " << v << ");";
+ }
+ else
+ {
+ out << nl << v << " = " << typeS << "Helper.ice_unmarshal(" << name << ", " << stream << ");";
+ }
+ return;
+ }
+
+ //
+ // Determine sequence depth
+ //
+ int depth = 0;
+ TypePtr origContent = seq->type();
+ SequencePtr s = SequencePtr::dynamicCast(origContent);
+ while (s)
+ {
+ depth++;
+ origContent = s->type();
+ s = SequencePtr::dynamicCast(origContent);
+ }
+ string origContentS = typeToString(origContent, TypeModeIn, scope);
+
+ if (!listType.empty())
+ {
+ BuiltinPtr b = BuiltinPtr::dynamicCast(seq->type());
+ if (b && b->kind() != Builtin::KindObject && b->kind() != Builtin::KindObjectProxy)
+ {
+ if (marshal)
+ {
+ out << nl << stream << ".startWriteSequence(" << name << ", " << v << ".size());";
+ ostringstream o;
+ o << "__i" << iter;
+ string it = o.str();
+ iter++;
+ out << nl << "java.util.Iterator " << it << " = " << v << ".iterator();";
+ out << nl << "while (" << it << ".hasNext())";
+ out << sb;
+
+ switch (b->kind())
+ {
+ case Builtin::KindByte:
+ {
+ out << nl << "java.lang.Byte __elem = (java.lang.Byte)" << it << ".next();";
+ out << nl << stream << ".writeByte(\"e\", __elem.byteValue());";
+ break;
+ }
+ case Builtin::KindBool:
+ {
+ out << nl << "java.lang.Boolean __elem = (java.lang.Boolean)" << it << ".next();";
+ out << nl << stream << ".writeBool(\"e\", __elem.booleanValue());";
+ break;
+ }
+ case Builtin::KindShort:
+ {
+ out << nl << "java.lang.Short __elem = (java.lang.Short)" << it << ".next();";
+ out << nl << stream << ".writeShort(\"e\", __elem.shortValue());";
+ break;
+ }
+ case Builtin::KindInt:
+ {
+ out << nl << "java.lang.Integer __elem = (java.lang.Integer)" << it << ".next();";
+ out << nl << stream << ".writeInt(\"e\", __elem.intValue());";
+ break;
+ }
+ case Builtin::KindLong:
+ {
+ out << nl << "java.lang.Long __elem = (java.lang.Long)" << it << ".next();";
+ out << nl << stream << ".writeLong(\"e\", __elem.longValue());";
+ break;
+ }
+ case Builtin::KindFloat:
+ {
+ out << nl << "java.lang.Float __elem = (java.lang.Float)" << it << ".next();";
+ out << nl << stream << ".writeFloat(\"e\", __elem.floatValue());";
+ break;
+ }
+ case Builtin::KindDouble:
+ {
+ out << nl << "java.lang.Double __elem = (java.lang.Double)" << it << ".next();";
+ out << nl << stream << ".writeDouble(\"e\", __elem.doubleValue());";
+ break;
+ }
+ case Builtin::KindString:
+ {
+ out << nl << "java.lang.String __elem = (java.lang.String)" << it << ".next();";
+ out << nl << stream << ".writeString(\"e\", __elem);";
+ break;
+ }
+ case Builtin::KindObject:
+ case Builtin::KindObjectProxy:
+ case Builtin::KindLocalObject:
+ {
+ assert(false);
+ break;
+ }
+ }
+ out << eb; // while
+ out << nl << stream << ".endWriteSequence();";
+ }
+ else
+ {
+ out << nl << v << " = new " << listType << "();";
+ ostringstream o;
+ o << origContentS << "[]";
+ int d = depth;
+ while (d--)
+ {
+ o << "[]";
+ }
+ switch (b->kind())
+ {
+ case Builtin::KindByte:
+ {
+ out << nl << o.str() << " __seq" << iter << " = " << stream << ".readByteSeq(" << name << ");";
+ out << nl << "for (int __i" << iter << " = 0; __i" << iter << " < __seq" << iter
+ << ".length; __i" << iter << "++)";
+ out << sb;
+ out << nl << v << ".add(new java.lang.Byte(__seq" << iter << "[__i" << iter << "]));";
+ out << eb;
+ iter++;
+ break;
+ }
+ case Builtin::KindBool:
+ {
+ out << nl << o.str() << " __seq" << iter << " = " << stream << ".readByteSeq(" << name << ");";
+ out << nl << "for (int __i" << iter << " = 0; __i" << iter << " < __seq" << iter
+ << ".length; __i" << iter << "++)";
+ out << sb;
+ out << nl << v << ".add(__seq" << iter << "[__i" << iter
+ << "] ? java.lang.Boolean.TRUE : java.lang.Boolean.FALSE);";
+ out << eb;
+ iter++;
+ break;
+ }
+ case Builtin::KindShort:
+ {
+ out << nl << o.str() << " __seq" << iter << " = " << stream << ".readShortSeq(" << name << ");";
+ out << nl << "for (int __i" << iter << " = 0; __i" << iter << " < __seq" << iter
+ << ".length; __i" << iter << "++)";
+ out << sb;
+ out << nl << v << ".add(new java.lang.Short(__seq" << iter << "[__i" << iter << "]));";
+ out << eb;
+ iter++;
+ break;
+ }
+ case Builtin::KindInt:
+ {
+ out << nl << o.str() << " __seq" << iter << " = " << stream << ".readIntSeq(" << name << ");";
+ out << nl << "for (int __i" << iter << " = 0; __i" << iter << " < __seq" << iter
+ << ".length; __i" << iter << "++)";
+ out << sb;
+ out << nl << v << ".add(new java.lang.Integer(__seq" << iter << "[__i" << iter << "]));";
+ out << eb;
+ iter++;
+ break;
+ }
+ case Builtin::KindLong:
+ {
+ out << nl << o.str() << " __seq" << iter << " = " << stream << ".readLongSeq(" << name << ");";
+ out << nl << "for (int __i" << iter << " = 0; __i" << iter << " < __seq" << iter
+ << ".length; __i" << iter << "++)";
+ out << sb;
+ out << nl << v << ".add(new java.lang.Long(__seq" << iter << "[__i" << iter << "]));";
+ out << eb;
+ iter++;
+ break;
+ }
+ case Builtin::KindFloat:
+ {
+ out << nl << o.str() << " __seq" << iter << " = " << stream << ".readFloatSeq(" << name << ");";
+ out << nl << "for (int __i" << iter << " = 0; __i" << iter << " < __seq" << iter
+ << ".length; __i" << iter << "++)";
+ out << sb;
+ out << nl << v << ".add(new java.lang.Float(__seq" << iter << "[__i" << iter << "]));";
+ out << eb;
+ iter++;
+ break;
+ }
+ case Builtin::KindDouble:
+ {
+ out << nl << o.str() << " __seq" << iter << " = " << stream << ".readDoubleSeq(" << name
+ << ");";
+ out << nl << "for (int __i" << iter << " = 0; __i" << iter << " < __seq" << iter
+ << ".length; __i" << iter << "++)";
+ out << sb;
+ out << nl << v << ".add(new java.lang.Double(__seq" << iter << "[__i" << iter << "]));";
+ out << eb;
+ iter++;
+ break;
+ }
+ case Builtin::KindString:
+ {
+ out << nl << o.str() << " __seq" << iter << " = " << stream << ".readStringSeq(" << name
+ << ");";
+ out << nl << "for (int __i" << iter << " = 0; __i" << iter << " < __seq" << iter
+ << ".length; __i" << iter << "++)";
+ out << sb;
+ out << nl << v << ".add(__seq" << iter << "[__i" << iter << "]);";
+ out << eb;
+ iter++;
+ break;
+ }
+ case Builtin::KindObject:
+ case Builtin::KindObjectProxy:
+ case Builtin::KindLocalObject:
+ {
+ assert(false);
+ break;
+ }
+ }
+ }
+ }
+ else
+ {
+ string typeS = getAbsolute(seq->scoped(), scope);
+ if (marshal)
+ {
+ out << nl << stream << ".startWriteSequence(" << name << ", " << v << ".size());";
+ ostringstream o;
+ o << "__i" << iter;
+ iter++;
+ string it = o.str();
+ out << nl << "java.util.Iterator " << it << " = " << v << ".iterator();";
+ out << nl << "while (" << it << ".hasNext())";
+ out << sb;
+ out << nl << origContentS << " __elem = (" << origContentS << ")" << it << ".next();";
+ writeGenericMarshalUnmarshalCode(out, scope, seq->type(), "\"e\"", "__elem", true, iter, false);
+ out << eb;
+ out << nl << stream << ".endWriteSequence();";
+ }
+ else
+ {
+ out << nl << v << " = new " << listType << "();";
+ out << nl << "int __len" << iter << " = " << stream << ".startReadSequence(" << name << ");";
+ out << nl << "for (int __i" << iter << " = 0; __i" << iter << " < __len" << iter << "; __i" << iter
+ << "++);";
+ out << sb;
+ out << nl << origContentS << " __elem;";
+ iter++;
+ writeGenericMarshalUnmarshalCode(out, scope, seq->type(), "\"e\"", "__elem", false, iter, false);
+ out << nl << v << ".add(__elem);";
+ out << eb;
+ }
+ }
+ }
+ else
+ {
BuiltinPtr b = BuiltinPtr::dynamicCast(seq->type());
- if (b)
+ if (b && b->kind() != Builtin::KindObject && b->kind() != Builtin::KindObjectProxy)
{
switch (b->kind())
{
@@ -1110,18 +1750,6 @@ Slice::JavaGenerator::writeGenericMarshalUnmarshalCode(Output& out,
}
case Builtin::KindObject:
case Builtin::KindObjectProxy:
- {
- string typeS = getAbsolute(seq->scoped(), scope);
- if (marshal)
- {
- out << nl << typeS << "Helper.ice_marshal(" << name << ", " << stream << ", " << v << ");";
- }
- else
- {
- out << nl << v << " = " << typeS << "Helper.ice_unmarshal(" << name << ", " << stream << ");";
- }
- break;
- }
case Builtin::KindLocalObject:
{
assert(false);
@@ -1131,31 +1759,41 @@ Slice::JavaGenerator::writeGenericMarshalUnmarshalCode(Output& out,
}
else
{
- ContainedPtr cont = ContainedPtr::dynamicCast(type);
- assert(cont);
- string typeS = getAbsolute(cont->scoped(), scope);
+ string typeS = getAbsolute(seq->scoped(), scope);
if (marshal)
{
- out << nl << typeS << "Helper.ice_marshal(" << name << ", " << stream << ", " << v << ");";
+ out << nl << stream << ".startWriteSequence(" << name << ", " << v << ".length);";
+ out << nl << "for (int __i" << iter << " = 0; __i" << iter << " < " << v << ".length; __i" << iter
+ << "++)";
+ out << sb;
+ ostringstream o;
+ o << v << "[__i" << iter << "]";
+ iter++;
+ writeGenericMarshalUnmarshalCode(out, scope, seq->type(), "\"e\"", o.str(), true, iter, false);
+ out << eb;
+ out << nl << stream << ".endWriteSequence();";
}
else
{
- out << nl << v << " = " << typeS << "Helper.ice_unmarshal(" << name << ", " << stream << ");";
+ out << nl << "int __len" << iter << " = " << stream << ".startReadSequence(" << name << ");";
+ out << nl << v << " = new " << origContentS << "[__len" << iter << "]";
+ int d = depth;
+ while (d--)
+ {
+ out << "[]";
+ }
+ out << ';';
+ out << nl << "for (int __i" << iter << " = 0; __i" << iter << " < " << v << ".length; __i" << iter
+ << "++)";
+ out << sb;
+ ostringstream o;
+ o << v << "[__i" << iter << "]";
+ iter++;
+ writeGenericMarshalUnmarshalCode(out, scope, seq->type(), "\"e\"", o.str(), false, iter, false);
+ out << eb;
+ out << nl << stream << ".endReadSequence();";
}
}
- return;
- }
-
- ConstructedPtr constructed = ConstructedPtr::dynamicCast(type);
- assert(constructed);
- string typeS = getAbsolute(constructed->scoped(), scope);
- if (marshal)
- {
- out << nl << typeS << "Helper.ice_marshal(" << name << ", " << stream << ", " << v << ");";
- }
- else
- {
- out << nl << v << " = " << typeS << "Helper.ice_unmarshal(" << name << ", " << stream << ");";
}
}
@@ -1178,3 +1816,18 @@ Slice::JavaGenerator::printHeader()
out << header;
out << "\n// Ice version " << ICE_STRING_VERSION;
}
+
+string
+Slice::JavaGenerator::findMetaData(const list<string>& metaData)
+{
+ static const string prefix = "java:";
+ for (list<string>::const_iterator q = metaData.begin(); q != metaData.end(); ++q)
+ {
+ if ((*q).find(prefix) == 0)
+ {
+ return (*q).substr(prefix.size());
+ }
+ }
+
+ return "";
+}
diff --git a/cpp/src/slice2java/Gen.cpp b/cpp/src/slice2java/Gen.cpp
index 18dc38809be..2312ecbcab9 100644
--- a/cpp/src/slice2java/Gen.cpp
+++ b/cpp/src/slice2java/Gen.cpp
@@ -172,8 +172,8 @@ Slice::JavaVisitor::writeDelegateThrowsClause(const string& scope,
}
void
-Slice::JavaVisitor::writeHashCode(Output& out, const TypePtr& type,
- const string& name, int& iter)
+Slice::JavaVisitor::writeHashCode(Output& out, const TypePtr& type, const string& name, int& iter,
+ const list<string>& metaData)
{
BuiltinPtr builtin = BuiltinPtr::dynamicCast(type);
if (builtin)
@@ -251,14 +251,28 @@ Slice::JavaVisitor::writeHashCode(Output& out, const TypePtr& type,
SequencePtr seq = SequencePtr::dynamicCast(type);
if (seq)
{
- out << nl << "for (int __i" << iter << " = 0; __i" << iter
- << " < " << name << ".length; __i" << iter << "++)";
- out << sb;
- ostringstream elem;
- elem << name << "[__i" << iter << ']';
- iter++;
- writeHashCode(out, seq->type(), elem.str(), iter);
- out << eb;
+ string listType = findMetaData(metaData);
+ if (listType.empty())
+ {
+ list<string> l = seq->getMetaData();
+ listType = findMetaData(l);
+ }
+
+ if (!listType.empty())
+ {
+ out << nl << "__h = 5 * __h + " << name << ".hashCode();";
+ }
+ else
+ {
+ out << nl << "for (int __i" << iter << " = 0; __i" << iter
+ << " < " << name << ".length; __i" << iter << "++)";
+ out << sb;
+ ostringstream elem;
+ elem << name << "[__i" << iter << ']';
+ iter++;
+ writeHashCode(out, seq->type(), elem.str(), iter);
+ out << eb;
+ }
return;
}
@@ -1030,7 +1044,8 @@ Slice::Gen::TypesVisitor::visitClassDefStart(const ClassDefPtr& p)
for (d = members.begin(); d != members.end(); ++d)
{
string memberName = fixKwd((*d)->name());
- writeHashCode(out, (*d)->type(), memberName, iter);
+ list<string> metaData = (*d)->getMetaData();
+ writeHashCode(out, (*d)->type(), memberName, iter, metaData);
}
if (baseHasDataMembers)
{
@@ -1088,7 +1103,8 @@ Slice::Gen::TypesVisitor::visitClassDefStart(const ClassDefPtr& p)
iter = 0;
for (d = members.begin(); d != members.end(); ++d)
{
- writeMarshalUnmarshalCode(out, scope, (*d)->type(), fixKwd((*d)->name()), true, iter, false);
+ list<string> metaData = (*d)->getMetaData();
+ writeMarshalUnmarshalCode(out, scope, (*d)->type(), fixKwd((*d)->name()), true, iter, false, metaData);
}
out << nl << "super.__write(__os);";
out << eb;
@@ -1102,7 +1118,8 @@ Slice::Gen::TypesVisitor::visitClassDefStart(const ClassDefPtr& p)
iter = 0;
for (d = members.begin(); d != members.end(); ++d)
{
- writeMarshalUnmarshalCode(out, scope, (*d)->type(), fixKwd((*d)->name()), false, iter, false);
+ list<string> metaData = (*d)->getMetaData();
+ writeMarshalUnmarshalCode(out, scope, (*d)->type(), fixKwd((*d)->name()), false, iter, false, metaData);
}
out << nl << "super.__read(__is);";
out << eb;
@@ -1117,7 +1134,9 @@ Slice::Gen::TypesVisitor::visitClassDefStart(const ClassDefPtr& p)
for (d = members.begin(); d != members.end(); ++d)
{
string s = (*d)->name();
- writeGenericMarshalUnmarshalCode(out, scope, (*d)->type(), "\"" + s + "\"", fixKwd(s), true, iter, false);
+ list<string> metaData = (*d)->getMetaData();
+ writeGenericMarshalUnmarshalCode(out, scope, (*d)->type(), "\"" + s + "\"", fixKwd(s), true, iter, false,
+ metaData);
}
out << eb;
@@ -1131,7 +1150,9 @@ Slice::Gen::TypesVisitor::visitClassDefStart(const ClassDefPtr& p)
for (d = members.begin(); d != members.end(); ++d)
{
string s = (*d)->name();
- writeGenericMarshalUnmarshalCode(out, scope, (*d)->type(), "\"" + s + "\"", fixKwd(s), false, iter, false);
+ list<string> metaData = (*d)->getMetaData();
+ writeGenericMarshalUnmarshalCode(out, scope, (*d)->type(), "\"" + s + "\"", fixKwd(s), false, iter, false,
+ metaData);
}
out << eb;
@@ -1256,8 +1277,8 @@ Slice::Gen::TypesVisitor::visitExceptionEnd(const ExceptionPtr& p)
iter = 0;
for (d = members.begin(); d != members.end(); ++d)
{
- writeMarshalUnmarshalCode(out, scope, (*d)->type(),
- fixKwd((*d)->name()), true, iter, false);
+ list<string> metaData = (*d)->getMetaData();
+ writeMarshalUnmarshalCode(out, scope, (*d)->type(), fixKwd((*d)->name()), true, iter, false, metaData);
}
if (base)
{
@@ -1274,9 +1295,8 @@ Slice::Gen::TypesVisitor::visitExceptionEnd(const ExceptionPtr& p)
iter = 0;
for (d = members.begin(); d != members.end(); ++d)
{
- writeMarshalUnmarshalCode(out, scope, (*d)->type(),
- fixKwd((*d)->name()), false, iter,
- false);
+ list<string> metaData = (*d)->getMetaData();
+ writeMarshalUnmarshalCode(out, scope, (*d)->type(), fixKwd((*d)->name()), false, iter, false, metaData);
}
if (base)
{
@@ -1298,7 +1318,9 @@ Slice::Gen::TypesVisitor::visitExceptionEnd(const ExceptionPtr& p)
for (d = members.begin(); d != members.end(); ++d)
{
string s = (*d)->name();
- writeGenericMarshalUnmarshalCode(out, scope, (*d)->type(), "\"" + s + "\"", fixKwd(s), true, iter, false);
+ list<string> metaData = (*d)->getMetaData();
+ writeGenericMarshalUnmarshalCode(out, scope, (*d)->type(), "\"" + s + "\"", fixKwd(s), true, iter, false,
+ metaData);
}
out << eb;
@@ -1316,7 +1338,9 @@ Slice::Gen::TypesVisitor::visitExceptionEnd(const ExceptionPtr& p)
for (d = members.begin(); d != members.end(); ++d)
{
string s = (*d)->name();
- writeGenericMarshalUnmarshalCode(out, scope, (*d)->type(), "\"" + s + "\"", fixKwd(s), false, iter, false);
+ list<string> metaData = (*d)->getMetaData();
+ writeGenericMarshalUnmarshalCode(out, scope, (*d)->type(), "\"" + s + "\"", fixKwd(s), false, iter, false,
+ metaData);
}
out << eb;
@@ -1402,8 +1426,7 @@ Slice::Gen::TypesVisitor::visitStructEnd(const StructPtr& p)
case Builtin::KindFloat:
case Builtin::KindDouble:
{
- out << nl << "if (" << memberName << " != _r."
- << memberName << ")";
+ out << nl << "if (" << memberName << " != _r." << memberName << ")";
out << sb;
out << nl << "return false;";
out << eb;
@@ -1415,8 +1438,7 @@ Slice::Gen::TypesVisitor::visitStructEnd(const StructPtr& p)
case Builtin::KindObjectProxy:
case Builtin::KindLocalObject:
{
- out << nl << "if (!" << memberName << ".equals(_r."
- << memberName << "))";
+ out << nl << "if (!" << memberName << ".equals(_r." << memberName << "))";
out << sb;
out << nl << "return false;";
out << eb;
@@ -1426,8 +1448,7 @@ Slice::Gen::TypesVisitor::visitStructEnd(const StructPtr& p)
}
else
{
- out << nl << "if (!" << memberName << ".equals(_r."
- << memberName << "))";
+ out << nl << "if (!" << memberName << ".equals(_r." << memberName << "))";
out << sb;
out << nl << "return false;";
out << eb;
@@ -1449,7 +1470,8 @@ Slice::Gen::TypesVisitor::visitStructEnd(const StructPtr& p)
for (d = members.begin(); d != members.end(); ++d)
{
string memberName = fixKwd((*d)->name());
- writeHashCode(out, (*d)->type(), memberName, iter);
+ list<string> metaData = (*d)->getMetaData();
+ writeHashCode(out, (*d)->type(), memberName, iter, metaData);
}
out << nl << "return __h;";
out << eb;
@@ -1465,8 +1487,8 @@ Slice::Gen::TypesVisitor::visitStructEnd(const StructPtr& p)
iter = 0;
for (d = members.begin(); d != members.end(); ++d)
{
- writeMarshalUnmarshalCode(out, scope, (*d)->type(),
- fixKwd((*d)->name()), true, iter, false);
+ list<string> metaData = (*d)->getMetaData();
+ writeMarshalUnmarshalCode(out, scope, (*d)->type(), fixKwd((*d)->name()), true, iter, false, metaData);
}
out << eb;
@@ -1478,9 +1500,8 @@ Slice::Gen::TypesVisitor::visitStructEnd(const StructPtr& p)
iter = 0;
for (d = members.begin(); d != members.end(); ++d)
{
- writeMarshalUnmarshalCode(out, scope, (*d)->type(),
- fixKwd((*d)->name()), false, iter,
- false);
+ list<string> metaData = (*d)->getMetaData();
+ writeMarshalUnmarshalCode(out, scope, (*d)->type(), fixKwd((*d)->name()), false, iter, false, metaData);
}
out << eb;
@@ -1495,7 +1516,9 @@ Slice::Gen::TypesVisitor::visitStructEnd(const StructPtr& p)
for (d = members.begin(); d != members.end(); ++d)
{
string s = (*d)->name();
- writeGenericMarshalUnmarshalCode(out, scope, (*d)->type(), "\"" + s + "\"", fixKwd(s), true, iter, false);
+ list<string> metaData = (*d)->getMetaData();
+ writeGenericMarshalUnmarshalCode(out, scope, (*d)->type(), "\"" + s + "\"", fixKwd(s), true, iter, false,
+ metaData);
}
out << nl << "__os.endWriteStruct();";
out << eb;
@@ -1511,7 +1534,9 @@ Slice::Gen::TypesVisitor::visitStructEnd(const StructPtr& p)
for (d = members.begin(); d != members.end(); ++d)
{
string s = (*d)->name();
- writeGenericMarshalUnmarshalCode(out, scope, (*d)->type(), "\"" + s + "\"", fixKwd(s), false, iter, false);
+ list<string> metaData = (*d)->getMetaData();
+ writeGenericMarshalUnmarshalCode(out, scope, (*d)->type(), "\"" + s + "\"", fixKwd(s), false, iter, false,
+ metaData);
}
out << nl << "__is.endReadStruct();";
out << eb;
@@ -1527,7 +1552,8 @@ Slice::Gen::TypesVisitor::visitDataMember(const DataMemberPtr& p)
string name = fixKwd(p->name());
ContainerPtr container = p->container();
ContainedPtr contained = ContainedPtr::dynamicCast(container);
- string s = typeToString(p->type(), TypeModeMember, contained->scope());
+ list<string> metaData = p->getMetaData();
+ string s = typeToString(p->type(), TypeModeMember, contained->scope(), metaData);
Output& out = output();
out << sp << nl << "public " << s << ' ' << name << ';';
}
@@ -2060,21 +2086,6 @@ Slice::Gen::HelperVisitor::visitClassDefStart(const ClassDefPtr& p)
void
Slice::Gen::HelperVisitor::visitSequence(const SequencePtr& p)
{
- static const char* builtinTable[] =
- {
- "Byte",
- "Bool",
- "Short",
- "Int",
- "Long",
- "Float",
- "Double",
- "String",
- "???", // Ice.Object
- "???", // Ice.ObjectPrx
- "???" // Ice.LocalObject
- };
-
//
// Don't generate helper for a sequence of a local type
//
@@ -2083,19 +2094,6 @@ Slice::Gen::HelperVisitor::visitSequence(const SequencePtr& p)
return;
}
- //
- // Determine sequence depth
- //
- int depth = 0;
- TypePtr origContent = p->type();
- SequencePtr s = SequencePtr::dynamicCast(origContent);
- while (s)
- {
- depth++;
- origContent = s->type();
- s = SequencePtr::dynamicCast(origContent);
- }
-
string name = fixKwd(p->name());
string absolute = getAbsolute(p->scoped());
string helper = absolute + "Helper";
@@ -2105,11 +2103,7 @@ Slice::Gen::HelperVisitor::visitSequence(const SequencePtr& p)
if (open(helper))
{
Output& out = output();
- int iter, d;
-
- BuiltinPtr b = BuiltinPtr::dynamicCast(p->type());
-
- string origContentS = typeToString(origContent, TypeModeIn, scope);
+ int iter;
out << sp << nl << "public final class " << name << "Helper";
out << sb;
@@ -2118,22 +2112,10 @@ Slice::Gen::HelperVisitor::visitSequence(const SequencePtr& p)
// write
//
out << nl << "public static void"
- << nl << "write(IceInternal.BasicStream __os, " << typeS
- << " __v)";
+ << nl << "write(IceInternal.BasicStream __os, " << typeS << " __v)";
out << sb;
- if (b && b->kind() != Builtin::KindObject && b->kind() != Builtin::KindObjectProxy)
- {
- out << nl << "__os.write" << builtinTable[b->kind()] << "Seq(__v);";
- }
- else
- {
- out << nl << "__os.writeSize(__v.length);";
- out << nl << "for (int __i = 0; __i < __v.length; __i++)";
- out << sb;
- iter = 0;
- writeMarshalUnmarshalCode(out, scope, p->type(), "__v[__i]", true, iter, false);
- out << eb;
- }
+ iter = 0;
+ writeSequenceMarshalUnmarshalCode(out, scope, p, "__v", true, iter, false);
out << eb;
//
@@ -2142,51 +2124,20 @@ Slice::Gen::HelperVisitor::visitSequence(const SequencePtr& p)
out << sp << nl << "public static " << typeS
<< nl << "read(IceInternal.BasicStream __is)";
out << sb;
- if (b && b->kind() != Builtin::KindObject && b->kind() != Builtin::KindObjectProxy)
- {
- out << nl << "return __is.read" << builtinTable[b->kind()] << "Seq();";
- }
- else
- {
- out << nl << "int __len = __is.readSize();";
- out << nl << typeS << " __v = new " << origContentS << "[__len]";
- d = depth;
- while (d--)
- {
- out << "[]";
- }
- out << ';';
- out << nl << "for (int __i = 0; __i < __len; __i++)";
- out << sb;
- iter = 0;
- writeMarshalUnmarshalCode(out, scope, p->type(), "__v[__i]", false,
- iter, false);
- out << eb;
- out << nl << "return __v;";
- }
+ out << nl << typeS << " __v;";
+ iter = 0;
+ writeSequenceMarshalUnmarshalCode(out, scope, p, "__v", false, iter, false);
+ out << nl << "return __v;";
out << eb;
//
// ice_marshal
//
out << sp << nl << "public static void"
- << nl << "ice_marshal(String __name, Ice.Stream __os, " << typeS
- << " __v)";
+ << nl << "ice_marshal(String __name, Ice.Stream __os, " << typeS << " __v)";
out << sb;
- if (b && b->kind() != Builtin::KindObject && b->kind() != Builtin::KindObjectProxy)
- {
- out << nl << "__os.write" << builtinTable[b->kind()] << "Seq(__name, __v);";
- }
- else
- {
- out << nl << "__os.startWriteSequence(__name, __v.length);";
- out << nl << "for (int __i = 0; __i < __v.length; __i++)";
- out << sb;
- iter = 0;
- writeGenericMarshalUnmarshalCode(out, scope, p->type(), "\"e\"", "__v[__i]", true, iter, false);
- out << eb;
- out << nl << "__os.endWriteSequence();";
- }
+ iter = 0;
+ writeGenericSequenceMarshalUnmarshalCode(out, scope, p, "__name", "__v", true, iter, false);
out << eb;
//
@@ -2195,28 +2146,10 @@ Slice::Gen::HelperVisitor::visitSequence(const SequencePtr& p)
out << sp << nl << "public static " << typeS
<< nl << "ice_unmarshal(String __name, Ice.Stream __is)";
out << sb;
- if (b && b->kind() != Builtin::KindObject && b->kind() != Builtin::KindObjectProxy)
- {
- out << nl << "return __is.read" << builtinTable[b->kind()] << "Seq(__name);";
- }
- else
- {
- out << nl << "int __len = __is.startReadSequence(__name);";
- out << nl << typeS << " __v = new " << origContentS << "[__len]";
- d = depth;
- while (d--)
- {
- out << "[]";
- }
- out << ';';
- out << nl << "for (int __i = 0; __i < __len; __i++)";
- out << sb;
- iter = 0;
- writeGenericMarshalUnmarshalCode(out, scope, p->type(), "\"e\"", "__v[__i]", false, iter, false);
- out << eb;
- out << nl << "__is.endReadSequence();";
- out << nl << "return __v;";
- }
+ out << nl << typeS << " __v;";
+ iter = 0;
+ writeGenericSequenceMarshalUnmarshalCode(out, scope, p, "__name", "__v", false, iter, false);
+ out << nl << "return __v;";
out << eb;
out << eb;
diff --git a/cpp/src/slice2java/Gen.h b/cpp/src/slice2java/Gen.h
index c7f84573388..a078444bba5 100644
--- a/cpp/src/slice2java/Gen.h
+++ b/cpp/src/slice2java/Gen.h
@@ -50,7 +50,8 @@ protected:
//
// Generate code to compute a hash code for a type
//
- void writeHashCode(::IceUtil::Output&, const TypePtr&, const std::string&, int&);
+ void writeHashCode(::IceUtil::Output&, const TypePtr&, const std::string&, int&,
+ const std::list<std::string>& = std::list<std::string>());
//
// Generate dispatch methods for a class or interface