summaryrefslogtreecommitdiff
path: root/cpp/src/Slice/CsUtil.cpp
diff options
context:
space:
mode:
authorMark Spruiell <mes@zeroc.com>2012-08-28 16:45:46 -0700
committerMark Spruiell <mes@zeroc.com>2012-08-28 16:45:46 -0700
commitb942ffebc2089adaa90233d69472c3289824a1c4 (patch)
treeae3c9e8c5af49b9c7800ae8f303ec8c723ed0d62 /cpp/src/Slice/CsUtil.cpp
parentmissing filter properties (diff)
downloadice-b942ffebc2089adaa90233d69472c3289824a1c4.tar.bz2
ice-b942ffebc2089adaa90233d69472c3289824a1c4.tar.xz
ice-b942ffebc2089adaa90233d69472c3289824a1c4.zip
initial support for optional params in C#
Diffstat (limited to 'cpp/src/Slice/CsUtil.cpp')
-rw-r--r--cpp/src/Slice/CsUtil.cpp684
1 files changed, 631 insertions, 53 deletions
diff --git a/cpp/src/Slice/CsUtil.cpp b/cpp/src/Slice/CsUtil.cpp
index 482ee8a11b1..05e50fc201c 100644
--- a/cpp/src/Slice/CsUtil.cpp
+++ b/cpp/src/Slice/CsUtil.cpp
@@ -138,7 +138,7 @@ Slice::CsGenerator::fixId(const ContainedPtr& cont, int baseTypes, bool mangleCa
ContainedPtr contained = ContainedPtr::dynamicCast(container);
if(contained && contained->hasMetaData("clr:property"))
{
- return cont->name() + "_prop";
+ return cont->name() + "__prop";
}
else
{
@@ -147,13 +147,123 @@ Slice::CsGenerator::fixId(const ContainedPtr& cont, int baseTypes, bool mangleCa
}
string
-Slice::CsGenerator::typeToString(const TypePtr& type)
+Slice::CsGenerator::getOptionalType(const TypePtr& type)
+{
+ BuiltinPtr bp = BuiltinPtr::dynamicCast(type);
+ if(bp)
+ {
+ switch(bp->kind())
+ {
+ case Builtin::KindByte:
+ case Builtin::KindBool:
+ {
+ return "Ice.OptionalType.F1";
+ }
+ case Builtin::KindShort:
+ {
+ return "Ice.OptionalType.F2";
+ }
+ case Builtin::KindInt:
+ case Builtin::KindFloat:
+ {
+ return "Ice.OptionalType.F4";
+ }
+ case Builtin::KindLong:
+ case Builtin::KindDouble:
+ {
+ return "Ice.OptionalType.F8";
+ }
+ case Builtin::KindString:
+ {
+ return "Ice.OptionalType.VSize";
+ }
+ case Builtin::KindObject:
+ {
+ return "Ice.OptionalType.Size";
+ }
+ case Builtin::KindObjectProxy:
+ {
+ return "Ice.OptionalType.FSize";
+ }
+ case Builtin::KindLocalObject:
+ {
+ assert(false);
+ break;
+ }
+ }
+ }
+
+ if(EnumPtr::dynamicCast(type))
+ {
+ return "Ice.OptionalType.Size";
+ }
+
+ SequencePtr seq = SequencePtr::dynamicCast(type);
+ if(seq)
+ {
+ return seq->type()->isVariableLength() ? "Ice.OptionalType.FSize" : "Ice.OptionalType.VSize";
+ }
+
+ DictionaryPtr d = DictionaryPtr::dynamicCast(type);
+ if(d)
+ {
+ return (d->keyType()->isVariableLength() || d->valueType()->isVariableLength()) ?
+ "Ice.OptionalType.FSize" : "Ice.OptionalType.VSize";
+ }
+
+ StructPtr st = StructPtr::dynamicCast(type);
+ if(st)
+ {
+ return st->isVariableLength() ? "Ice.OptionalType.FSize" : "Ice.OptionalType.VSize";
+ }
+
+ if(ProxyPtr::dynamicCast(type))
+ {
+ return "Ice.OptionalType.FSize";
+ }
+
+ ClassDeclPtr cl = ClassDeclPtr::dynamicCast(type);
+ assert(cl);
+ return "Ice.OptionalType.Size";
+}
+
+string
+Slice::CsGenerator::getStaticId(const TypePtr& type)
+{
+ BuiltinPtr b = BuiltinPtr::dynamicCast(type);
+ ClassDeclPtr cl = ClassDeclPtr::dynamicCast(type);
+
+ assert((b && b->kind() == Builtin::KindObject) || cl);
+
+ if(b)
+ {
+ return "Ice.ObjectImpl.ice_staticId()";
+ }
+ else if(cl->isInterface())
+ {
+ ContainedPtr cont = ContainedPtr::dynamicCast(cl->container());
+ assert(cont);
+ return fixId(cont->scoped(), DotNet::ICloneable) + "." + cl->name() + "Disp_.ice_staticId()";
+ }
+ else
+ {
+ return fixId(cl->scoped(), DotNet::ICloneable) + ".ice_staticId()";
+ }
+}
+
+string
+Slice::CsGenerator::typeToString(const TypePtr& type, bool optional)
{
if(!type)
{
return "void";
}
+ if(optional)
+ {
+ return "Ice.Optional<" + typeToString(type, false) + ">";
+ }
+
static const char* builtinTable[] =
{
"byte",
@@ -299,9 +409,7 @@ Slice::CsGenerator::writeMarshalUnmarshalCode(Output &out,
const string& param,
bool marshal,
bool streamingAPI,
- bool isOutParam,
- const string& patchParams,
- bool newAMI)
+ const string& patchParams)
{
string stream;
@@ -423,26 +531,7 @@ Slice::CsGenerator::writeMarshalUnmarshalCode(Output &out,
}
else
{
- if(isOutParam)
- {
- out << nl << "IceInternal.ParamPatcher<Ice.Object> " << param
- << "_PP = new IceInternal.ParamPatcher<Ice.Object>(\"::Ice::Object\");";
- out << nl << stream << ".readObject(";
- if(streamingAPI)
- {
- out << "(Ice.ReadObjectCallback)";
- }
- out << param << "_PP);";
- }
- else
- {
- out << nl << stream << ".readObject(";
- if(streamingAPI)
- {
- out << "(Ice.ReadObjectCallback)";
- }
- out << "new Patcher__(\"::Ice::Object\", " << patchParams << "));";
- }
+ out << nl << stream << ".readObject(" << patchParams << ");";
}
break;
}
@@ -502,27 +591,7 @@ Slice::CsGenerator::writeMarshalUnmarshalCode(Output &out,
}
else
{
- if(isOutParam)
- {
- out << nl << "IceInternal.ParamPatcher<" << typeToString(type) << ">" << param
- << "_PP = new IceInternal.ParamPatcher<" << typeToString(type) << ">(\""
- << cl->scoped() << "\");";
- out << nl << stream << ".readObject(";
- if(streamingAPI)
- {
- out << "(Ice.ReadObjectCallback)";
- }
- out << param << "_PP);";
- }
- else
- {
- out << nl << stream << ".readObject(";
- if(streamingAPI)
- {
- out << "(Ice.ReadObjectCallback)";
- }
- out << "new Patcher__(\"" << cl->scoped() << "\", " << patchParams << "));";
- }
+ out << nl << stream << ".readObject(" << patchParams << ");";
}
return;
}
@@ -611,7 +680,7 @@ Slice::CsGenerator::writeMarshalUnmarshalCode(Output &out,
SequencePtr seq = SequencePtr::dynamicCast(type);
if(seq)
{
- writeSequenceMarshalUnmarshalCode(out, seq, param, marshal, streamingAPI);
+ writeSequenceMarshalUnmarshalCode(out, seq, param, marshal, streamingAPI, true);
return;
}
@@ -637,11 +706,324 @@ Slice::CsGenerator::writeMarshalUnmarshalCode(Output &out,
}
void
+Slice::CsGenerator::writeOptionalMarshalUnmarshalCode(Output &out,
+ const TypePtr& type,
+ const string& param,
+ int tag,
+ bool marshal,
+ bool streamingAPI,
+ const string& patchParams)
+{
+ string stream;
+
+ if(marshal)
+ {
+ stream = streamingAPI ? "outS__" : "os__";
+ }
+ else
+ {
+ stream = streamingAPI ? "inS__" : "is__";
+ }
+
+ BuiltinPtr builtin = BuiltinPtr::dynamicCast(type);
+ if(builtin)
+ {
+ switch(builtin->kind())
+ {
+ case Builtin::KindByte:
+ {
+ if(marshal)
+ {
+ out << nl << stream << ".writeByte(" << tag << ", " << param << ");";
+ }
+ else
+ {
+ out << nl << param << " = " << stream << ".readByte(" << tag << ");";
+ }
+ break;
+ }
+ case Builtin::KindBool:
+ {
+ if(marshal)
+ {
+ out << nl << stream << ".writeBool(" << tag << ", " << param << ");";
+ }
+ else
+ {
+ out << nl << param << " = " << stream << ".readBool(" << tag << ");";
+ }
+ break;
+ }
+ case Builtin::KindShort:
+ {
+ if(marshal)
+ {
+ out << nl << stream << ".writeShort(" << tag << ", " << param << ");";
+ }
+ else
+ {
+ out << nl << param << " = " << stream << ".readShort(" << tag << ");";
+ }
+ break;
+ }
+ case Builtin::KindInt:
+ {
+ if(marshal)
+ {
+ out << nl << stream << ".writeInt(" << tag << ", " << param << ");";
+ }
+ else
+ {
+ out << nl << param << " = " << stream << ".readInt(" << tag << ");";
+ }
+ break;
+ }
+ case Builtin::KindLong:
+ {
+ if(marshal)
+ {
+ out << nl << stream << ".writeLong(" << tag << ", " << param << ");";
+ }
+ else
+ {
+ out << nl << param << " = " << stream << ".readLong(" << tag << ");";
+ }
+ break;
+ }
+ case Builtin::KindFloat:
+ {
+ if(marshal)
+ {
+ out << nl << stream << ".writeFloat(" << tag << ", " << param << ");";
+ }
+ else
+ {
+ out << nl << param << " = " << stream << ".readFloat(" << tag << ");";
+ }
+ break;
+ }
+ case Builtin::KindDouble:
+ {
+ if(marshal)
+ {
+ out << nl << stream << ".writeDouble(" << tag << ", " << param << ");";
+ }
+ else
+ {
+ out << nl << param << " = " << stream << ".readDouble(" << tag << ");";
+ }
+ break;
+ }
+ case Builtin::KindString:
+ {
+ if(marshal)
+ {
+ out << nl << stream << ".writeString(" << tag << ", " << param << ");";
+ }
+ else
+ {
+ out << nl << param << " = " << stream << ".readString(" << tag << ");";
+ }
+ break;
+ }
+ case Builtin::KindObject:
+ {
+ if(marshal)
+ {
+ out << nl << stream << ".writeObject(" << tag << ", " << param << ");";
+ }
+ else
+ {
+ out << nl << param << " = new Ice.Optional<Ice.Object>();";
+ out << nl << stream << ".readObject(" << tag << ", " << param
+ << ", Ice.ObjectImpl.ice_staticId());";
+ }
+ break;
+ }
+ case Builtin::KindObjectProxy:
+ {
+ string typeS = typeToString(type);
+ if(marshal)
+ {
+ out << nl << stream << ".writeProxy(" << tag << ", " << param << ");";
+ }
+ else
+ {
+ out << nl << param << " = " << stream << ".readProxy(" << tag << ");";
+ }
+ break;
+ }
+ case Builtin::KindLocalObject:
+ {
+ assert(false);
+ break;
+ }
+ }
+ return;
+ }
+
+ ProxyPtr prx = ProxyPtr::dynamicCast(type);
+ if(prx)
+ {
+ if(marshal)
+ {
+ out << nl << "if(" << param << " != null && " << param << ".HasValue && " << stream << ".writeOpt(" << tag
+ << ", Ice.OptionalType.FSize))";
+ out << sb;
+ out << nl << stream << ".startSize();";
+ writeMarshalUnmarshalCode(out, type, param + ".Value", marshal, streamingAPI, patchParams);
+ out << nl << stream << ".endSize();";
+ out << eb;
+ }
+ else
+ {
+ out << nl << "if(" << stream << ".readOpt(" << tag << ", Ice.OptionalType.FSize))";
+ out << sb;
+ out << nl << stream << ".skip(4);";
+ writeMarshalUnmarshalCode(out, type, param + ".Value", marshal, streamingAPI, patchParams);
+ out << eb;
+ }
+ return;
+ }
+
+ ClassDeclPtr cl = ClassDeclPtr::dynamicCast(type);
+ if(cl)
+ {
+ if(marshal)
+ {
+ out << nl << stream << ".writeObject(" << tag << ", " << param << ");";
+ }
+ else
+ {
+ out << nl << param << " = new Ice.Optional<" << typeToString(type) << ">();";
+ out << nl << stream << ".readObject(" << tag << ", " << param << ", " << getStaticId(cl) << ");";
+ }
+ return;
+ }
+
+ StructPtr st = StructPtr::dynamicCast(type);
+ if(st)
+ {
+ if(marshal)
+ {
+ out << nl << "if(" << param << " != null && " << param << ".HasValue && " << stream << ".writeOpt(" << tag
+ << ", " << getOptionalType(st) << "))";
+ out << sb;
+ if(st->isVariableLength())
+ {
+ out << nl << stream << ".startSize();";
+ }
+ else
+ {
+ out << nl << stream << ".writeSize(" << st->minWireSize() << ");";
+ }
+ writeMarshalUnmarshalCode(out, type, param + ".Value", marshal, streamingAPI, patchParams);
+ if(st->isVariableLength())
+ {
+ out << nl << stream << ".endSize();";
+ }
+ out << eb;
+ }
+ else
+ {
+ out << nl << "if(" << stream << ".readOpt(" << tag << ", " << getOptionalType(st) << "))";
+ out << sb;
+ if(st->isVariableLength())
+ {
+ out << nl << stream << ".skip(4);";
+ }
+ else
+ {
+ out << nl << stream << ".skipSize();";
+ }
+ string typeS = typeToString(type);
+ string tmp = "tmp__" + param;
+ out << nl << typeS << ' ' << tmp << " = new " << typeS << "();";
+ writeMarshalUnmarshalCode(out, type, tmp, marshal, streamingAPI, patchParams);
+ out << nl << param << " = " << tmp << ';';
+ out << eb;
+ }
+ return;
+ }
+
+ EnumPtr en = EnumPtr::dynamicCast(type);
+ if(en)
+ {
+ size_t sz = en->getEnumerators().size();
+ if(marshal)
+ {
+ out << nl << "if(" << param << " != null && " << param << ".HasValue)";
+ out << sb;
+ out << nl << stream << ".writeEnum(" << tag << ", (int)" << param << ".Value, " << sz << ");";
+ out << eb;
+ }
+ else
+ {
+ out << nl << "if(" << stream << ".readOpt(" << tag << ", Ice.OptionalType.Size))";
+ out << sb;
+ writeMarshalUnmarshalCode(out, type, param, marshal, streamingAPI, patchParams);
+ out << eb;
+ }
+ return;
+ }
+
+ SequencePtr seq = SequencePtr::dynamicCast(type);
+ if(seq)
+ {
+ writeOptionalSequenceMarshalUnmarshalCode(out, seq, param, tag, marshal, streamingAPI);
+ return;
+ }
+
+ DictionaryPtr d = DictionaryPtr::dynamicCast(type);
+ assert(d);
+ TypePtr keyType = d->keyType();
+ TypePtr valueType = d->valueType();
+ if(marshal)
+ {
+ out << nl << "if(" << param << " != null && " << param << ".HasValue && " << stream << ".writeOpt(" << tag
+ << ", " << getOptionalType(d) << "))";
+ out << sb;
+ if(keyType->isVariableLength() || valueType->isVariableLength())
+ {
+ out << nl << stream << ".startSize();";
+ }
+ else
+ {
+ out << nl << stream << ".writeSize(" << param << ".Value == null ? 1 : " << param << ".Value.Count * "
+ << (keyType->minWireSize() + valueType->minWireSize()) << " + (" << param
+ << ".Value.Count > 254 ? 5 : 1));";
+ }
+ writeMarshalUnmarshalCode(out, type, param + ".Value", marshal, streamingAPI, patchParams);
+ if(keyType->isVariableLength() || valueType->isVariableLength())
+ {
+ out << nl << stream << ".endSize();";
+ }
+ out << eb;
+ }
+ else
+ {
+ out << nl << "if(" << stream << ".readOpt(" << tag << ", " << getOptionalType(d) << "))";
+ out << sb;
+ if(keyType->isVariableLength() || valueType->isVariableLength())
+ {
+ out << nl << stream << ".skip(4);";
+ }
+ else
+ {
+ out << nl << stream << ".skipSize();";
+ }
+ writeMarshalUnmarshalCode(out, type, param + ".Value", marshal, streamingAPI, patchParams);
+ out << eb;
+ }
+}
+
+void
Slice::CsGenerator::writeSequenceMarshalUnmarshalCode(Output& out,
const SequencePtr& seq,
const string& param,
bool marshal,
- bool streamingAPI)
+ bool streamingAPI,
+ bool useHelper)
{
string stream;
if(marshal)
@@ -653,13 +1035,29 @@ Slice::CsGenerator::writeSequenceMarshalUnmarshalCode(Output& out,
stream = streamingAPI ? "inS__" : "is__";
}
+ if(useHelper)
+ {
+ ContainedPtr cont = ContainedPtr::dynamicCast(seq->container());
+ assert(cont);
+ string helperName = fixId(cont->scoped(), DotNet::ICloneable) + "." + seq->name() + "Helper";
+ if(marshal)
+ {
+ out << nl << helperName << ".write(" << stream << ", " << param << ");";
+ }
+ else
+ {
+ out << nl << param << " = " << helperName << ".read(" << stream << ");";
+ }
+ return;
+ }
+
TypePtr type = seq->type();
string typeS = typeToString(type);
- string genericPrefix = "clr:generic:";
+ const string genericPrefix = "clr:generic:";
string genericType;
string addMethod = "Add";
- bool isGeneric = seq->findMetaData(genericPrefix, genericType);
+ const bool isGeneric = seq->findMetaData(genericPrefix, genericType);
bool isStack = false;
bool isList = false;
bool isLinkedList = false;
@@ -690,9 +1088,9 @@ Slice::CsGenerator::writeSequenceMarshalUnmarshalCode(Output& out,
isCustom = true;
}
}
- bool isCollection = seq->hasMetaData("clr:collection");
- bool isArray = !isGeneric && !isCollection;
- string limitID = isArray ? "Length" : "Count";
+ const bool isCollection = seq->hasMetaData("clr:collection");
+ const bool isArray = !isGeneric && !isCollection;
+ const string limitID = isArray ? "Length" : "Count";
BuiltinPtr builtin = BuiltinPtr::dynamicCast(type);
if(builtin)
@@ -1404,6 +1802,186 @@ Slice::CsGenerator::writeSequenceMarshalUnmarshalCode(Output& out,
return;
}
+void
+Slice::CsGenerator::writeOptionalSequenceMarshalUnmarshalCode(Output& out,
+ const SequencePtr& seq,
+ const string& param,
+ int tag,
+ bool marshal,
+ bool streamingAPI)
+{
+ string stream;
+ if(marshal)
+ {
+ stream = streamingAPI ? "outS__" : "os__";
+ }
+ else
+ {
+ stream = streamingAPI ? "inS__" : "is__";
+ }
+
+ const TypePtr type = seq->type();
+ const string typeS = typeToString(type);
+
+ string meta;
+ const bool isArray = !seq->findMetaData("clr:generic:", meta) && !seq->hasMetaData("clr:collection");
+ const string length = isArray ? param + ".Value.Length" : param + ".Value.Count";
+
+ BuiltinPtr builtin = BuiltinPtr::dynamicCast(type);
+ if(builtin)
+ {
+ switch(builtin->kind())
+ {
+ case Builtin::KindByte:
+ case Builtin::KindBool:
+ case Builtin::KindShort:
+ case Builtin::KindInt:
+ case Builtin::KindFloat:
+ case Builtin::KindLong:
+ case Builtin::KindDouble:
+ case Builtin::KindString:
+ {
+ string func = typeS;
+ func[0] = toupper(static_cast<unsigned char>(typeS[0]));
+ const bool isSerializable = seq->findMetaData("clr:serializable:", meta);
+
+ if(marshal)
+ {
+ if(isSerializable)
+ {
+ out << nl << "if(" << param << " != null && " << param << ".HasValue && " << stream << ".writeOpt("
+ << tag << ", Ice.OptionalType.VSize))";
+ out << sb;
+ out << nl << stream << ".writeSerializable(" << param << ".Value);";
+ out << eb;
+ }
+ else if(isArray)
+ {
+ out << nl << stream << ".write" << func << "Seq(" << tag << ", " << param << ");";
+ }
+ else
+ {
+ out << nl << "if(" << param << " != null && " << param << ".HasValue)";
+ out << sb;
+ out << nl << stream << ".write" << func << "Seq(" << tag << ", " << param
+ << ".Value == null ? 0 : " << param << ".Value.Count, " << param << ".Value);";
+ out << eb;
+ }
+ }
+ else
+ {
+ out << nl << "if(" << stream << ".readOpt(" << tag << ", " << getOptionalType(seq) << "))";
+ out << sb;
+ if(builtin->isVariableLength())
+ {
+ out << nl << stream << ".skip(4);";
+ }
+ else if(builtin->kind() != Builtin::KindByte && builtin->kind() != Builtin::KindBool)
+ {
+ out << nl << stream << ".skipSize();";
+ }
+ writeSequenceMarshalUnmarshalCode(out, seq, param + ".Value", marshal, streamingAPI, true);
+ out << eb;
+ }
+ break;
+ }
+
+ case Builtin::KindObject:
+ case Builtin::KindObjectProxy:
+ {
+ if(marshal)
+ {
+ out << nl << "if(" << param << " != null && " << param << ".HasValue && "
+ << stream << ".writeOpt(" << tag << ", " << getOptionalType(seq) << "))";
+ out << sb;
+ out << nl << stream << ".startSize();";
+ writeSequenceMarshalUnmarshalCode(out, seq, param + ".Value", marshal, streamingAPI, true);
+ out << nl << stream << ".endSize();";
+ out << eb;
+ }
+ else
+ {
+ out << nl << "if(" << stream << ".readOpt(" << tag << ", " << getOptionalType(seq) << "))";
+ out << sb;
+ out << nl << stream << ".skip(4);";
+ writeSequenceMarshalUnmarshalCode(out, seq, param + ".Value", marshal, streamingAPI, true);
+ out << eb;
+ }
+ break;
+ }
+
+ case Builtin::KindLocalObject:
+ assert(false);
+ }
+
+ return;
+ }
+
+ StructPtr st = StructPtr::dynamicCast(type);
+ if(st)
+ {
+ if(marshal)
+ {
+ out << nl << "if(" << param << " != null && " << param << ".HasValue && "
+ << stream << ".writeOpt(" << tag << ", " << getOptionalType(seq) << "))";
+ out << sb;
+ if(st->isVariableLength())
+ {
+ out << nl << stream << ".startSize();";
+ }
+ else
+ {
+ out << nl << stream << ".writeSize(" << param << ".Value == null ? 1 : " << length << " * "
+ << st->minWireSize() << " + (" << length << " > 254 ? 5 : 1));";
+ }
+ writeSequenceMarshalUnmarshalCode(out, seq, param + ".Value", marshal, streamingAPI, true);
+ if(st->isVariableLength())
+ {
+ out << nl << stream << ".endSize();";
+ }
+ out << eb;
+ }
+ else
+ {
+ out << nl << "if(" << stream << ".readOpt(" << tag << ", " << getOptionalType(seq) << "))";
+ out << sb;
+ if(st->isVariableLength())
+ {
+ out << nl << stream << ".skip(4);";
+ }
+ else
+ {
+ out << nl << stream << ".skipSize();";
+ }
+ writeSequenceMarshalUnmarshalCode(out, seq, param + ".Value", marshal, streamingAPI, true);
+ out << eb;
+ }
+ return;
+ }
+
+ //
+ // At this point, all remaining element types have variable size.
+ //
+ if(marshal)
+ {
+ out << nl << "if(" << param << " != null && " << param << ".HasValue && "
+ << stream << ".writeOpt(" << tag << ", " << getOptionalType(seq) << "))";
+ out << sb;
+ out << nl << stream << ".startSize();";
+ writeSequenceMarshalUnmarshalCode(out, seq, param + ".Value", marshal, streamingAPI, true);
+ out << nl << stream << ".endSize();";
+ out << eb;
+ }
+ else
+ {
+ out << nl << "if(" << stream << ".readOpt(" << tag << ", " << getOptionalType(seq) << "))";
+ out << sb;
+ out << nl << stream << ".skip(4);";
+ writeSequenceMarshalUnmarshalCode(out, seq, param + ".Value", marshal, streamingAPI, true);
+ out << eb;
+ }
+}
+
string
Slice::CsGenerator::toArrayAlloc(const string& decl, const string& sz)
{