summaryrefslogtreecommitdiff
path: root/cpp
diff options
context:
space:
mode:
Diffstat (limited to 'cpp')
-rw-r--r--cpp/include/Slice/CsUtil.h81
-rw-r--r--cpp/slice/Ice/BuiltinSequences.ice16
-rwxr-xr-xcpp/src/Slice/CsUtil.cpp174
-rwxr-xr-xcpp/src/slice2cs/Gen.cpp28
4 files changed, 228 insertions, 71 deletions
diff --git a/cpp/include/Slice/CsUtil.h b/cpp/include/Slice/CsUtil.h
index 371560d0a65..da08b104f0a 100644
--- a/cpp/include/Slice/CsUtil.h
+++ b/cpp/include/Slice/CsUtil.h
@@ -25,6 +25,14 @@ class SLICE_API CsGenerator : public ::IceUtil::noncopyable
{
public:
+ virtual ~CsGenerator() {};
+
+ //
+ // Validate all metadata in the unit with a "cs:" prefix.
+ //
+ static void validateMetaData(const UnitPtr&);
+
+protected:
static std::string fixId(const std::string&);
static std::string typeToString(const TypePtr&);
static bool isValueType(const TypePtr&);
@@ -35,60 +43,31 @@ public:
bool = false, const std::string& = "");
void writeSequenceMarshalUnmarshalCode(::IceUtil::Output&, const SequencePtr&, const std::string&, bool, bool);
-#if 0
-protected:
-
- //
- // Check a symbol against any of the Java keywords. If a
- // match is found, return the symbol with a leading underscore.
- //
-
- //
- // Convert a scoped name into a Java class name. If an optional
- // scope is provided, the scope will be removed from the result.
- //
- std::string getAbsolute(const std::string&,
- const std::string& = std::string(),
- const std::string& = std::string(),
- const std::string& = std::string()) const;
+private:
- //
- // Get the Java name for a type. If an optional scope is provided,
- // the scope will be removed from the result if possible.
- //
- enum TypeMode
+ class MetaDataVisitor : public ParserVisitor
{
- TypeModeIn,
- TypeModeOut,
- TypeModeMember,
- TypeModeReturn
+ public:
+
+ virtual bool visitModuleStart(const ModulePtr&);
+ virtual void visitClassDecl(const ClassDeclPtr&);
+ virtual bool visitClassDefStart(const ClassDefPtr&);
+ virtual bool visitExceptionStart(const ExceptionPtr&);
+ virtual bool visitStructStart(const StructPtr&);
+ virtual void visitOperation(const OperationPtr&);
+ virtual void visitParamDecl(const ParamDeclPtr&);
+ virtual void visitDataMember(const DataMemberPtr&);
+ virtual void visitSequence(const SequencePtr&);
+ virtual void visitDictionary(const DictionaryPtr&);
+ virtual void visitEnum(const EnumPtr&);
+ virtual void visitConst(const ConstPtr&);
+
+ private:
+
+ void validate(const ContainedPtr&);
+
+ StringSet _history;
};
- std::string typeToString(const TypePtr&, TypeMode mode,
- const std::string& = std::string(),
- const std::list<std::string>& = std::list<std::string>()) const;
-
- //
- // Generate code to marshal or unmarshal a type
- //
- void writeMarshalUnmarshalCode(::IceUtil::Output&, const std::string&, const TypePtr&, const std::string&,
- bool, int&, bool = false, const std::list<std::string>& = std::list<std::string>(),
- const std::string& patchParams = "");
-
- //
- // Generate code to marshal or unmarshal a sequence type
- //
- void writeSequenceMarshalUnmarshalCode(::IceUtil::Output&, const std::string&, const SequencePtr&,
- const std::string&, bool, int&, bool,
- const std::list<std::string>& = std::list<std::string>());
-
-protected:
-
- static std::string findMetaData(const std::list<std::string>&);
- IceUtil::Output& _out;
-
-private:
-#endif
-
};
}
diff --git a/cpp/slice/Ice/BuiltinSequences.ice b/cpp/slice/Ice/BuiltinSequences.ice
index 3b637b25e43..7ed77a475eb 100644
--- a/cpp/slice/Ice/BuiltinSequences.ice
+++ b/cpp/slice/Ice/BuiltinSequences.ice
@@ -19,28 +19,28 @@ module Ice
{
/** A sequence of bools. **/
-sequence<bool> BoolSeq;
+["cs:array"] sequence<bool> BoolSeq;
/** A sequence of bytes. **/
-sequence<byte> ByteSeq;
+["cs:array"] sequence<byte> ByteSeq;
/** A sequence of shorts. **/
-sequence<short> ShortSeq;
+["cs:array"] sequence<short> ShortSeq;
/** A sequence of ints. **/
-sequence<int> IntSeq;
+["cs:array"] sequence<int> IntSeq;
/** A sequence of longs. **/
-sequence<long> LongSeq;
+["cs:array"] sequence<long> LongSeq;
/** A sequence of floats. **/
-sequence<float> FloatSeq;
+["cs:array"] sequence<float> FloatSeq;
/** A sequence of doubles. **/
-sequence<double> DoubleSeq;
+["cs:array"] sequence<double> DoubleSeq;
/** A sequence of strings. **/
-sequence<string> StringSeq;
+["cs:array"] sequence<string> StringSeq;
/** A sequence of objects. **/
sequence<Object> ObjectSeq;
diff --git a/cpp/src/Slice/CsUtil.cpp b/cpp/src/Slice/CsUtil.cpp
index 4a29dc6cb94..58f33144159 100755
--- a/cpp/src/Slice/CsUtil.cpp
+++ b/cpp/src/Slice/CsUtil.cpp
@@ -172,6 +172,12 @@ Slice::CsGenerator::typeToString(const TypePtr& type)
return fixId(proxy->_class()->scoped() + "Prx");
}
+ SequencePtr seq = SequencePtr::dynamicCast(type);
+ if(seq && seq->hasMetaData("cs:array"))
+ {
+ return typeToString(seq->type()) + "[]";
+ }
+
ContainedPtr contained = ContainedPtr::dynamicCast(type);
if(contained)
{
@@ -487,10 +493,10 @@ Slice::CsGenerator::writeMarshalUnmarshalCode(Output &out,
void
Slice::CsGenerator::writeSequenceMarshalUnmarshalCode(Output& out,
- const SequencePtr& seq,
- const string& param,
- bool marshal,
- bool isSeq)
+ const SequencePtr& seq,
+ const string& param,
+ bool marshal,
+ bool isSeq)
{
string stream = marshal ? "__os" : "__is";
@@ -560,14 +566,28 @@ Slice::CsGenerator::writeSequenceMarshalUnmarshalCode(Output& out,
{
string typeS = typeToString(type);
typeS[0] = toupper(typeS[0]);
+ bool isArray = seq->hasMetaData("cs:array");
if(marshal)
{
- out << nl << stream << ".write" << typeS << "Seq(" << param << ".ToArray());";
+ out << nl << stream << ".write" << typeS << "Seq(" << param;
+ if(!isArray)
+ {
+ out << ".ToArray()";
+ }
+ out << ");";
}
else
{
- out << nl << param << startAssign << "new " << fixId(seq->scoped()) << "(" << stream
- << ".read" << typeS << "Seq())" << endAssign << ";";
+ out << nl << param << startAssign;
+ if(!isArray)
+ {
+ out << "new " << fixId(seq->scoped()) << "(" << stream << ".read" << typeS << "Seq())";
+ }
+ else
+ {
+ out << stream << ".read" << typeS << "Seq()";
+ }
+ out << endAssign << ";";
}
break;
}
@@ -673,3 +693,143 @@ Slice::CsGenerator::writeSequenceMarshalUnmarshalCode(Output& out,
return;
}
+
+void
+Slice::CsGenerator::validateMetaData(const UnitPtr& unit)
+{
+ MetaDataVisitor visitor;
+ unit->visit(&visitor);
+}
+
+bool
+Slice::CsGenerator::MetaDataVisitor::visitModuleStart(const ModulePtr& p)
+{
+ validate(p);
+ return false;
+}
+
+void
+Slice::CsGenerator::MetaDataVisitor::visitClassDecl(const ClassDeclPtr& p)
+{
+ validate(p);
+}
+
+bool
+Slice::CsGenerator::MetaDataVisitor::visitClassDefStart(const ClassDefPtr& p)
+{
+ validate(p);
+ return false;
+}
+
+bool
+Slice::CsGenerator::MetaDataVisitor::visitExceptionStart(const ExceptionPtr& p)
+{
+ validate(p);
+ return false;
+}
+
+bool
+Slice::CsGenerator::MetaDataVisitor::visitStructStart(const StructPtr& p)
+{
+ validate(p);
+ return false;
+}
+
+void
+Slice::CsGenerator::MetaDataVisitor::visitOperation(const OperationPtr& p)
+{
+ validate(p);
+}
+
+void
+Slice::CsGenerator::MetaDataVisitor::visitParamDecl(const ParamDeclPtr& p)
+{
+ validate(p);
+}
+
+void
+Slice::CsGenerator::MetaDataVisitor::visitDataMember(const DataMemberPtr& p)
+{
+ validate(p);
+}
+
+void
+Slice::CsGenerator::MetaDataVisitor::visitSequence(const SequencePtr& p)
+{
+ validate(p);
+}
+
+void
+Slice::CsGenerator::MetaDataVisitor::visitDictionary(const DictionaryPtr& p)
+{
+ validate(p);
+}
+
+void
+Slice::CsGenerator::MetaDataVisitor::visitEnum(const EnumPtr& p)
+{
+ validate(p);
+}
+
+void
+Slice::CsGenerator::MetaDataVisitor::visitConst(const ConstPtr& p)
+{
+ validate(p);
+}
+
+void
+Slice::CsGenerator::MetaDataVisitor::validate(const ContainedPtr& cont)
+{
+ DefinitionContextPtr dc = cont->definitionContext();
+ assert(dc);
+ StringList globalMetaData = dc->getMetaData();
+ string file = dc->filename();
+
+ StringList localMetaData = cont->getMetaData();
+
+ StringList::const_iterator p;
+ static const string prefix = "cs:";
+
+ for(p = globalMetaData.begin(); p != globalMetaData.end(); ++p)
+ {
+ string s = *p;
+ if(_history.count(s) == 0)
+ {
+ if(s.find(prefix) == 0)
+ {
+ cout << file << ": warning: ignoring invalid global metadata `" << s << "'" << endl;
+ }
+ _history.insert(s);
+ }
+ }
+
+ for(p = localMetaData.begin(); p != localMetaData.end(); ++p)
+ {
+ string s = *p;
+ if(_history.count(s) == 0)
+ {
+ bool valid = true;
+ if(s.find(prefix) == 0)
+ {
+ if(SequencePtr::dynamicCast(cont))
+ {
+ if(s.substr(prefix.size()) != "array")
+ {
+ cerr << "2" << endl;
+ valid = false;
+ }
+ }
+ else
+ {
+ cerr << "3" << endl;
+ valid = false;
+ }
+ }
+ if(!valid)
+ {
+ cout << file << ": warning: ignoring invalid metadata `" << s << "'" << endl;
+ }
+ _history.insert(s);
+ }
+ }
+}
diff --git a/cpp/src/slice2cs/Gen.cpp b/cpp/src/slice2cs/Gen.cpp
index 269352b25dc..b58ffb965dd 100755
--- a/cpp/src/slice2cs/Gen.cpp
+++ b/cpp/src/slice2cs/Gen.cpp
@@ -154,16 +154,14 @@ Slice::CsVisitor::writeDispatch(const ClassDefPtr& p)
}
_out << eb << ";";
- _out << sp << nl << "private static readonly Ice.StringSeq __idSeq = new Ice.StringSeq(__ids);";
-
_out << sp << nl << "public override bool ice_isA(string s, Ice.Current __current)";
_out << sb;
_out << nl << "return _System.Array.BinarySearch(__ids, s, _System.Collections.Comparer.DefaultInvariant) >= 0;";
_out << eb;
- _out << sp << nl << "public override Ice.StringSeq ice_ids(Ice.Current __current)";
+ _out << sp << nl << "public override string[] ice_ids(Ice.Current __current)";
_out << sb;
- _out << nl << "return __idSeq;";
+ _out << nl << "return __ids;";
_out << eb;
_out << sp << nl << "public override string ice_id(Ice.Current __current)";
@@ -550,6 +548,9 @@ Slice::Gen::operator!() const
void
Slice::Gen::generate(const UnitPtr& p)
{
+
+ CsGenerator::validateMetaData(p);
+
TypesVisitor typesVisitor(_out);
p->visit(&typesVisitor);
@@ -1059,6 +1060,14 @@ Slice::Gen::TypesVisitor::visitOperation(const OperationPtr& p)
void
Slice::Gen::TypesVisitor::visitSequence(const SequencePtr& p)
{
+ //
+ // No need to generate anything if the sequence is mapped as an array.
+ //
+ if(p->hasMetaData("cs:array"))
+ {
+ return;
+ }
+
string name = fixId(p->name());
string s = typeToString(p->type());
bool isValue = isValueType(p->type());
@@ -2527,7 +2536,16 @@ Slice::Gen::HelperVisitor::visitSequence(const SequencePtr& p)
_out << sp << nl << "public static " << typeS << " read(IceInternal.BasicStream __is)";
_out << sb;
- _out << nl << typeS << " __v = new " << typeS << "();";
+ bool isArray = p->hasMetaData("cs:array");
+ _out << nl << typeS << " __v";
+ if(!isArray)
+ {
+ _out << " = new " << typeS << "();";
+ }
+ else
+ {
+ _out << ";";
+ }
writeSequenceMarshalUnmarshalCode(_out, p, "__v", false, false);
_out << nl << "return __v;";
_out << eb;