diff options
Diffstat (limited to 'cpp/src')
-rw-r--r-- | cpp/src/Slice/JavaUtil.cpp | 787 | ||||
-rw-r--r-- | cpp/src/slice2java/Gen.cpp | 223 | ||||
-rw-r--r-- | cpp/src/slice2java/Gen.h | 3 |
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 |