summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Spruiell <mes@zeroc.com>2017-09-04 14:40:47 -0700
committerMark Spruiell <mes@zeroc.com>2017-09-04 14:40:47 -0700
commitcdfd2cbb48cccc460541d21f604834975fe05720 (patch)
tree6e1277a7ecbe091098ae4e2c8e3c87c44799f7ad
parentFix PHP build warnings (diff)
downloadice-cdfd2cbb48cccc460541d21f604834975fe05720.tar.bz2
ice-cdfd2cbb48cccc460541d21f604834975fe05720.tar.xz
ice-cdfd2cbb48cccc460541d21f604834975fe05720.zip
Initial commit of MATLAB prototype
-rw-r--r--cpp/msbuild/ice.v120.sln13
-rw-r--r--cpp/msbuild/ice.v140.sln14
-rw-r--r--cpp/msbuild/ice.v141.sln14
-rw-r--r--cpp/src/Slice/StringLiteralUtil.cpp114
-rw-r--r--cpp/src/Slice/Util.h7
-rw-r--r--cpp/src/slice2matlab/Main.cpp2993
-rw-r--r--cpp/src/slice2matlab/Slice2Matlab.rc33
-rw-r--r--cpp/src/slice2matlab/msbuild/packages.config7
-rw-r--r--cpp/src/slice2matlab/msbuild/slice2matlab.vcxproj138
-rw-r--r--cpp/src/slice2matlab/msbuild/slice2matlab.vcxproj.filters30
-rw-r--r--matlab/.gitignore1
-rw-r--r--matlab/README.md92
-rw-r--r--matlab/lib/+Ice/Communicator.m31
-rwxr-xr-xmatlab/lib/+Ice/Connection.m76
-rw-r--r--matlab/lib/+Ice/Exception.m21
-rw-r--r--matlab/lib/+Ice/Future.m67
-rw-r--r--matlab/lib/+Ice/InitializationData.m28
-rw-r--r--matlab/lib/+Ice/InputStream.m197
-rw-r--r--matlab/lib/+Ice/LocalException.m18
-rw-r--r--matlab/lib/+Ice/ObjectPrx.m763
-rw-r--r--matlab/lib/+Ice/Optional.m48
-rw-r--r--matlab/lib/+Ice/OutputStream.m161
-rw-r--r--matlab/lib/+Ice/Properties.m63
-rw-r--r--matlab/lib/+Ice/UserException.m29
-rw-r--r--matlab/lib/+Ice/Util.m116
-rw-r--r--matlab/lib/+Ice/Value.m41
-rw-r--r--matlab/lib/+Ice/WrapperObject.m26
-rw-r--r--matlab/lib/+Ice/createProperties.m29
-rw-r--r--matlab/lib/+Ice/identityToString.m14
-rw-r--r--matlab/lib/+Ice/initialize.m47
-rw-r--r--matlab/lib/+Ice/proxyIdentityAndFacetCompare.m45
-rw-r--r--matlab/lib/+Ice/proxyIdentityCompare.m29
-rw-r--r--matlab/lib/+Ice/stringToIdentity.m14
-rw-r--r--matlab/lib/generated/.gitignore1
-rw-r--r--matlab/msbuild/ice.proj49
-rw-r--r--matlab/src/IceMatlab/Communicator.cpp86
-rw-r--r--matlab/src/IceMatlab/Connection.cpp286
-rw-r--r--matlab/src/IceMatlab/Future.cpp166
-rw-r--r--matlab/src/IceMatlab/Future.h58
-rw-r--r--matlab/src/IceMatlab/IceMatlab.rc38
-rw-r--r--matlab/src/IceMatlab/Init.cpp94
-rw-r--r--matlab/src/IceMatlab/InputStream.cpp830
-rw-r--r--matlab/src/IceMatlab/InputStream.h27
-rw-r--r--matlab/src/IceMatlab/ObjectPrx.cpp1144
-rw-r--r--matlab/src/IceMatlab/OutputStream.cpp716
-rw-r--r--matlab/src/IceMatlab/Properties.cpp254
-rw-r--r--matlab/src/IceMatlab/Util.cpp648
-rw-r--r--matlab/src/IceMatlab/Util.h47
-rw-r--r--matlab/src/IceMatlab/icematlab.h280
-rw-r--r--matlab/test/Ice/operations/AllTests.m53
-rw-r--r--matlab/test/Ice/operations/Application.m157
-rw-r--r--matlab/test/Ice/operations/BatchOneways.m114
-rw-r--r--matlab/test/Ice/operations/BatchOnewaysAMI.m70
-rw-r--r--matlab/test/Ice/operations/Client.m52
-rw-r--r--matlab/test/Ice/operations/Oneways.m33
-rw-r--r--matlab/test/Ice/operations/OnewaysAMI.m63
-rw-r--r--matlab/test/Ice/operations/Test.ice377
-rw-r--r--matlab/test/Ice/operations/Twoways.m1407
-rw-r--r--matlab/test/Ice/operations/TwowaysAMI.m1266
-rw-r--r--matlab/test/Ice/operations/generated/.gitignore1
-rw-r--r--slice/Ice/Connection.ice2
61 files changed, 13618 insertions, 20 deletions
diff --git a/cpp/msbuild/ice.v120.sln b/cpp/msbuild/ice.v120.sln
index 7bc262fd716..3e71b6c7a3d 100644
--- a/cpp/msbuild/ice.v120.sln
+++ b/cpp/msbuild/ice.v120.sln
@@ -35,6 +35,11 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "slice2js", "..\src\slice2js
{57CD6AC2-0C9D-4648-9E9D-5DF60C90F18A} = {57CD6AC2-0C9D-4648-9E9D-5DF60C90F18A}
EndProjectSection
EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "slice2matlab", "..\src\slice2matlab\msbuild\slice2matlab.vcxproj", "{FBDCD48E-57DB-4CC1-A9D6-7D9F1C97D0E1}"
+ ProjectSection(ProjectDependencies) = postProject
+ {57CD6AC2-0C9D-4648-9E9D-5DF60C90F18A} = {57CD6AC2-0C9D-4648-9E9D-5DF60C90F18A}
+ EndProjectSection
+EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "slice2php", "..\src\slice2php\msbuild\slice2php.vcxproj", "{55A6E595-EFE4-47B9-957C-E4CFF2E75FD6}"
ProjectSection(ProjectDependencies) = postProject
{57CD6AC2-0C9D-4648-9E9D-5DF60C90F18A} = {57CD6AC2-0C9D-4648-9E9D-5DF60C90F18A}
@@ -292,6 +297,14 @@ Global
{8DF85304-2A53-4C36-804F-5C6FA2F75ACF}.Release|Win32.Build.0 = Release|Win32
{8DF85304-2A53-4C36-804F-5C6FA2F75ACF}.Release|x64.ActiveCfg = Release|x64
{8DF85304-2A53-4C36-804F-5C6FA2F75ACF}.Release|x64.Build.0 = Release|x64
+ {FBDCD48E-57DB-4CC1-A9D6-7D9F1C97D0E1}.Debug|Win32.ActiveCfg = Debug|Win32
+ {FBDCD48E-57DB-4CC1-A9D6-7D9F1C97D0E1}.Debug|Win32.Build.0 = Debug|Win32
+ {FBDCD48E-57DB-4CC1-A9D6-7D9F1C97D0E1}.Debug|x64.ActiveCfg = Debug|x64
+ {FBDCD48E-57DB-4CC1-A9D6-7D9F1C97D0E1}.Debug|x64.Build.0 = Debug|x64
+ {FBDCD48E-57DB-4CC1-A9D6-7D9F1C97D0E1}.Release|Win32.ActiveCfg = Release|Win32
+ {FBDCD48E-57DB-4CC1-A9D6-7D9F1C97D0E1}.Release|Win32.Build.0 = Release|Win32
+ {FBDCD48E-57DB-4CC1-A9D6-7D9F1C97D0E1}.Release|x64.ActiveCfg = Release|x64
+ {FBDCD48E-57DB-4CC1-A9D6-7D9F1C97D0E1}.Release|x64.Build.0 = Release|x64
{55A6E595-EFE4-47B9-957C-E4CFF2E75FD6}.Debug|Win32.ActiveCfg = Debug|Win32
{55A6E595-EFE4-47B9-957C-E4CFF2E75FD6}.Debug|Win32.Build.0 = Debug|Win32
{55A6E595-EFE4-47B9-957C-E4CFF2E75FD6}.Debug|x64.ActiveCfg = Debug|x64
diff --git a/cpp/msbuild/ice.v140.sln b/cpp/msbuild/ice.v140.sln
index b860db8ea68..09e620ae497 100644
--- a/cpp/msbuild/ice.v140.sln
+++ b/cpp/msbuild/ice.v140.sln
@@ -35,6 +35,11 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "slice2js", "..\src\slice2js
{57CD6AC2-0C9D-4648-9E9D-5DF60C90F18A} = {57CD6AC2-0C9D-4648-9E9D-5DF60C90F18A}
EndProjectSection
EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "slice2matlab", "..\src\slice2matlab\msbuild\slice2matlab.vcxproj", "{FBDCD48E-57DB-4CC1-A9D6-7D9F1C97D0E1}"
+ ProjectSection(ProjectDependencies) = postProject
+ {57CD6AC2-0C9D-4648-9E9D-5DF60C90F18A} = {57CD6AC2-0C9D-4648-9E9D-5DF60C90F18A}
+ EndProjectSection
+EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "slice2php", "..\src\slice2php\msbuild\slice2php.vcxproj", "{55A6E595-EFE4-47B9-957C-E4CFF2E75FD6}"
ProjectSection(ProjectDependencies) = postProject
{57CD6AC2-0C9D-4648-9E9D-5DF60C90F18A} = {57CD6AC2-0C9D-4648-9E9D-5DF60C90F18A}
@@ -346,6 +351,14 @@ Global
{8DF85304-2A53-4C36-804F-5C6FA2F75ACF}.Release|Win32.Build.0 = Release|Win32
{8DF85304-2A53-4C36-804F-5C6FA2F75ACF}.Release|x64.ActiveCfg = Release|x64
{8DF85304-2A53-4C36-804F-5C6FA2F75ACF}.Release|x64.Build.0 = Release|x64
+ {FBDCD48E-57DB-4CC1-A9D6-7D9F1C97D0E1}.Debug|Win32.ActiveCfg = Debug|Win32
+ {FBDCD48E-57DB-4CC1-A9D6-7D9F1C97D0E1}.Debug|Win32.Build.0 = Debug|Win32
+ {FBDCD48E-57DB-4CC1-A9D6-7D9F1C97D0E1}.Debug|x64.ActiveCfg = Debug|x64
+ {FBDCD48E-57DB-4CC1-A9D6-7D9F1C97D0E1}.Debug|x64.Build.0 = Debug|x64
+ {FBDCD48E-57DB-4CC1-A9D6-7D9F1C97D0E1}.Release|Win32.ActiveCfg = Release|Win32
+ {FBDCD48E-57DB-4CC1-A9D6-7D9F1C97D0E1}.Release|Win32.Build.0 = Release|Win32
+ {FBDCD48E-57DB-4CC1-A9D6-7D9F1C97D0E1}.Release|x64.ActiveCfg = Release|x64
+ {FBDCD48E-57DB-4CC1-A9D6-7D9F1C97D0E1}.Release|x64.Build.0 = Release|x64
{55A6E595-EFE4-47B9-957C-E4CFF2E75FD6}.Debug|Win32.ActiveCfg = Debug|Win32
{55A6E595-EFE4-47B9-957C-E4CFF2E75FD6}.Debug|Win32.Build.0 = Debug|Win32
{55A6E595-EFE4-47B9-957C-E4CFF2E75FD6}.Debug|x64.ActiveCfg = Debug|x64
@@ -694,6 +707,7 @@ Global
{B8E063CB-1481-42CA-92F3-E96770EDD70E} = {2DC2B270-B7AE-48CF-8FB0-41A55A9747E9}
{A503D0D4-22BB-4BDB-B996-862D14DA3349} = {2DC2B270-B7AE-48CF-8FB0-41A55A9747E9}
{8DF85304-2A53-4C36-804F-5C6FA2F75ACF} = {2DC2B270-B7AE-48CF-8FB0-41A55A9747E9}
+ {FBDCD48E-57DB-4CC1-A9D6-7D9F1C97D0E1} = {2DC2B270-B7AE-48CF-8FB0-41A55A9747E9}
{55A6E595-EFE4-47B9-957C-E4CFF2E75FD6} = {2DC2B270-B7AE-48CF-8FB0-41A55A9747E9}
{ACAF39D3-B4BD-426B-98DE-D95944B0D3F6} = {2DC2B270-B7AE-48CF-8FB0-41A55A9747E9}
{3AB9772C-6113-4F1C-90FB-5368E7486C11} = {F48CC091-6F26-4EC8-A2FB-485975E7C908}
diff --git a/cpp/msbuild/ice.v141.sln b/cpp/msbuild/ice.v141.sln
index 33079688681..c856ad5fb02 100644
--- a/cpp/msbuild/ice.v141.sln
+++ b/cpp/msbuild/ice.v141.sln
@@ -35,6 +35,11 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "slice2js", "..\src\slice2js
{57CD6AC2-0C9D-4648-9E9D-5DF60C90F18A} = {57CD6AC2-0C9D-4648-9E9D-5DF60C90F18A}
EndProjectSection
EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "slice2matlab", "..\src\slice2matlab\msbuild\slice2matlab.vcxproj", "{FBDCD48E-57DB-4CC1-A9D6-7D9F1C97D0E1}"
+ ProjectSection(ProjectDependencies) = postProject
+ {57CD6AC2-0C9D-4648-9E9D-5DF60C90F18A} = {57CD6AC2-0C9D-4648-9E9D-5DF60C90F18A}
+ EndProjectSection
+EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "slice2php", "..\src\slice2php\msbuild\slice2php.vcxproj", "{55A6E595-EFE4-47B9-957C-E4CFF2E75FD6}"
ProjectSection(ProjectDependencies) = postProject
{57CD6AC2-0C9D-4648-9E9D-5DF60C90F18A} = {57CD6AC2-0C9D-4648-9E9D-5DF60C90F18A}
@@ -336,6 +341,14 @@ Global
{8DF85304-2A53-4C36-804F-5C6FA2F75ACF}.Release|Win32.Build.0 = Release|Win32
{8DF85304-2A53-4C36-804F-5C6FA2F75ACF}.Release|x64.ActiveCfg = Release|x64
{8DF85304-2A53-4C36-804F-5C6FA2F75ACF}.Release|x64.Build.0 = Release|x64
+ {FBDCD48E-57DB-4CC1-A9D6-7D9F1C97D0E1}.Debug|Win32.ActiveCfg = Debug|Win32
+ {FBDCD48E-57DB-4CC1-A9D6-7D9F1C97D0E1}.Debug|Win32.Build.0 = Debug|Win32
+ {FBDCD48E-57DB-4CC1-A9D6-7D9F1C97D0E1}.Debug|x64.ActiveCfg = Debug|x64
+ {FBDCD48E-57DB-4CC1-A9D6-7D9F1C97D0E1}.Debug|x64.Build.0 = Debug|x64
+ {FBDCD48E-57DB-4CC1-A9D6-7D9F1C97D0E1}.Release|Win32.ActiveCfg = Release|Win32
+ {FBDCD48E-57DB-4CC1-A9D6-7D9F1C97D0E1}.Release|Win32.Build.0 = Release|Win32
+ {FBDCD48E-57DB-4CC1-A9D6-7D9F1C97D0E1}.Release|x64.ActiveCfg = Release|x64
+ {FBDCD48E-57DB-4CC1-A9D6-7D9F1C97D0E1}.Release|x64.Build.0 = Release|x64
{55A6E595-EFE4-47B9-957C-E4CFF2E75FD6}.Debug|Win32.ActiveCfg = Debug|Win32
{55A6E595-EFE4-47B9-957C-E4CFF2E75FD6}.Debug|Win32.Build.0 = Debug|Win32
{55A6E595-EFE4-47B9-957C-E4CFF2E75FD6}.Debug|x64.ActiveCfg = Debug|x64
@@ -668,6 +681,7 @@ Global
{B8E063CB-1481-42CA-92F3-E96770EDD70E} = {2DC2B270-B7AE-48CF-8FB0-41A55A9747E9}
{A503D0D4-22BB-4BDB-B996-862D14DA3349} = {2DC2B270-B7AE-48CF-8FB0-41A55A9747E9}
{8DF85304-2A53-4C36-804F-5C6FA2F75ACF} = {2DC2B270-B7AE-48CF-8FB0-41A55A9747E9}
+ {FBDCD48E-57DB-4CC1-A9D6-7D9F1C97D0E1} = {2DC2B270-B7AE-48CF-8FB0-41A55A9747E9}
{55A6E595-EFE4-47B9-957C-E4CFF2E75FD6} = {2DC2B270-B7AE-48CF-8FB0-41A55A9747E9}
{ACAF39D3-B4BD-426B-98DE-D95944B0D3F6} = {2DC2B270-B7AE-48CF-8FB0-41A55A9747E9}
{3AB9772C-6113-4F1C-90FB-5368E7486C11} = {F48CC091-6F26-4EC8-A2FB-485975E7C908}
diff --git a/cpp/src/Slice/StringLiteralUtil.cpp b/cpp/src/Slice/StringLiteralUtil.cpp
index ce3351f7de1..80c322b4d7f 100644
--- a/cpp/src/Slice/StringLiteralUtil.cpp
+++ b/cpp/src/Slice/StringLiteralUtil.cpp
@@ -29,9 +29,12 @@ public:
StringLiteralGenerator(const string&, const string&, EscapeMode, unsigned char);
- string escapeASCIIChar(char) const;
- string escapeCodePoint(unsigned int) const;
- string flushU8Buffer(vector<unsigned char>&) const;
+ string escapeASCIIChar(char);
+ string escapeCodePoint(unsigned int);
+ string flushU8Buffer(vector<unsigned char>&);
+
+ enum Format { NoFormat, OctalFormat, HexFormat };
+ void format(Format);
private:
@@ -39,6 +42,11 @@ private:
const string _printableEscaped;
const EscapeMode _escapeMode;
const unsigned char _cutOff;
+ const string _shortUCNPrefix;
+ const string _octalChars;
+ const string _hexChars;
+
+ Format _format; // The last format used for an escape.
};
StringLiteralGenerator::StringLiteralGenerator(const string& nonPrintableEscaped,
@@ -46,19 +54,33 @@ StringLiteralGenerator::StringLiteralGenerator(const string& nonPrintableEscaped
EscapeMode escapeMode,
unsigned char cutOff) :
_nonPrintableEscaped(nonPrintableEscaped),
- _printableEscaped(printableEscaped + "\\\""),
+ _printableEscaped(printableEscaped + "\\"),
_escapeMode(escapeMode),
- _cutOff(cutOff)
+ _cutOff(cutOff),
+ _shortUCNPrefix(escapeMode == Matlab ? "\\x" : "\\u"),
+ _octalChars("01234567"),
+ _hexChars("01234567890ABCDEFabcdef"),
+ _format(NoFormat)
{
+ //
+ // Double quotes don't need to be escaped in Matlab because the string delimiter is a single quote.
+ //
+ if(_escapeMode != Matlab)
+ {
+ const_cast<string&>(_printableEscaped) += '"';
+ }
}
string
-StringLiteralGenerator::escapeASCIIChar(char c) const
+StringLiteralGenerator::escapeASCIIChar(char c)
{
assert(static_cast<unsigned char>(c) < 128);
string result;
+ Format lastFormat = _format;
+ _format = NoFormat;
+
if(_nonPrintableEscaped.find(c) != string::npos)
{
switch(c)
@@ -125,10 +147,51 @@ StringLiteralGenerator::escapeASCIIChar(char c) const
result = '\\';
result += c;
}
+ else if(_escapeMode == Matlab && c == '\'')
+ {
+ //
+ // Matlab strings are converted by sprintf(), and sprintf() requires a single quote to be escaped
+ // with another single quote.
+ //
+ result = "''";
+ }
+ else if(_escapeMode == Matlab && c == '%')
+ {
+ //
+ // Matlab strings are converted by sprintf(), and sprintf() requires a percent to be escaped
+ // with another percent.
+ //
+ result = "%%";
+ }
else if(c >= 32 && c <= 126)
{
- // Other printable ASCII
- result = c;
+ //
+ // Other printable ASCII.
+ //
+ if(_escapeMode == Matlab)
+ {
+ //
+ // While interpreting an octal or hex escape, the Matlab parser will continue to consume adjacent
+ // legal characters. If the trailing character after an escaped value could be consumed, we escape it
+ // as well to terminate the original escape.
+ //
+ if((lastFormat == OctalFormat && _octalChars.find(c) != string::npos) ||
+ (lastFormat == HexFormat && _hexChars.find(c) != string::npos))
+ {
+ ostringstream os;
+ os << "\\" << oct << setfill('0') << setw(3) << static_cast<unsigned int>(c & 0xFF);
+ result = os.str();
+ _format = OctalFormat;
+ }
+ else
+ {
+ result = c;
+ }
+ }
+ else
+ {
+ result = c;
+ }
}
else
{
@@ -137,10 +200,12 @@ StringLiteralGenerator::escapeASCIIChar(char c) const
if((static_cast<unsigned char>(c) < _cutOff) || (_escapeMode == Octal))
{
os << "\\" << oct << setfill('0') << setw(3) << static_cast<unsigned int>(c & 0xFF);
+ _format = OctalFormat;
}
else
{
- os << "\\u" << hex << setfill('0') << setw(4) << static_cast<unsigned int>(c & 0xFF);
+ os << _shortUCNPrefix << hex << setfill('0') << setw(4) << static_cast<unsigned int>(c & 0xFF);
+ _format = HexFormat;
}
result = os.str();
}
@@ -148,7 +213,7 @@ StringLiteralGenerator::escapeASCIIChar(char c) const
}
string
-StringLiteralGenerator::escapeCodePoint(unsigned int codePoint) const
+StringLiteralGenerator::escapeCodePoint(unsigned int codePoint)
{
if(codePoint < 128)
{
@@ -165,6 +230,7 @@ StringLiteralGenerator::escapeCodePoint(unsigned int codePoint) const
{
os << "\\" << setfill('0') << setw(3) << oct << static_cast<unsigned int>(*q);
}
+ _format = OctalFormat;
return os.str();
}
else
@@ -176,20 +242,23 @@ StringLiteralGenerator::escapeCodePoint(unsigned int codePoint) const
// Output octal escape
//
os << "\\" << setfill('0') << setw(3) << oct << codePoint;
+ _format = OctalFormat;
}
else if(codePoint <= 0xFFFF)
{
- os << "\\u" << setfill('0') << setw(4) << hex << codePoint;
+ os << _shortUCNPrefix << setfill('0') << setw(4) << hex << codePoint;
+ _format = HexFormat;
}
- else if(_escapeMode == ShortUCN)
+ else if(_escapeMode == ShortUCN || _escapeMode == Matlab)
{
//
// Convert to surrogate pair
//
unsigned int highSurrogate = ((codePoint - 0x10000) / 0x400) + 0xD800;
unsigned int lowSurrogate = ((codePoint - 0x10000) % 0x400) + 0xDC00;
- os << "\\u" << setfill('0') << setw(4) << hex << highSurrogate;
- os << "\\u" << setfill('0') << setw(4) << hex << lowSurrogate;
+ os << _shortUCNPrefix << setfill('0') << setw(4) << hex << highSurrogate;
+ os << _shortUCNPrefix << setfill('0') << setw(4) << hex << lowSurrogate;
+ _format = HexFormat;
}
else if(_escapeMode == EC6UCN)
{
@@ -204,7 +273,7 @@ StringLiteralGenerator::escapeCodePoint(unsigned int codePoint) const
}
string
-StringLiteralGenerator::flushU8Buffer(vector<unsigned char>& u8buffer) const
+StringLiteralGenerator::flushU8Buffer(vector<unsigned char>& u8buffer)
{
if(u8buffer.empty())
{
@@ -224,6 +293,12 @@ StringLiteralGenerator::flushU8Buffer(vector<unsigned char>& u8buffer) const
}
}
+void
+StringLiteralGenerator::format(Format f)
+{
+ _format = f;
+}
+
}
string
@@ -271,6 +346,7 @@ Slice::toStringLiteral(const string& value,
if(c == '\\')
{
os << "\\\\";
+ generator.format(StringLiteralGenerator::NoFormat);
}
else if(c == 'u' || c == 'U')
{
@@ -284,11 +360,16 @@ Slice::toStringLiteral(const string& value,
// ASCII character that may need to escaped in languages such as Java
os << generator.escapeASCIIChar(static_cast<char>(v));
}
- else if(escapeMode == UCN || c == 'u')
+ else if(escapeMode == UCN)
{
// keep this escape as is
os << "\\" << c << codePointStr;
}
+ else if(c == 'u')
+ {
+ os << (escapeMode == Matlab ? "\\x" : "\\u") << codePointStr;
+ generator.format(StringLiteralGenerator::HexFormat);
+ }
else
{
os << generator.escapeCodePoint(static_cast<unsigned int>(v));
@@ -298,6 +379,7 @@ Slice::toStringLiteral(const string& value,
else
{
// unescaped backslash: escape it!
+ generator.format(StringLiteralGenerator::NoFormat);
os << "\\\\";
os << generator.escapeASCIIChar(c);
}
diff --git a/cpp/src/Slice/Util.h b/cpp/src/Slice/Util.h
index a31536a6ed8..33c52fe5035 100644
--- a/cpp/src/Slice/Util.h
+++ b/cpp/src/Slice/Util.h
@@ -31,16 +31,17 @@ std::vector<std::string> argvToArgs(int argc, wchar_t* argv[]);
std::vector<std::string> argvToArgs(int argc, char* argv[]);
#endif
-enum EscapeMode { UCN, Octal, ShortUCN, EC6UCN };
+enum EscapeMode { UCN, Octal, ShortUCN, Matlab, EC6UCN };
// Parameters:
// const string& value: input string provided by Slice Parser
// const string& nonPrintableEscaped: which of \a, \b, \f, \n, \r, \t, \v, \0 (null), \x20 (\s), \x1b (\e) are
// escaped in the target language
// Warning: don't include \0 if the target language recognizes octal escapes
-// const string& printableEscaped: additional printable ASCII characters other than \ and " that need to be escaped
+// const string& printableEscaped: additional printable ASCII characters other than \ and the string delimiter
+// that need to be escaped
// EscapeMode escapeMode: whether we generate both UCNs, octal escape sequences, only short UCNs (\unnnn),
-// or ECMAScript 6-style UCNs with \u{...} for astral characters
+// Matlab syntax, or ECMAScript 6-style UCNs with \u{...} for astral characters.
// unsigned char cutOff: characters < cutOff other than the nonPrintableEscaped are generated as
// octal escape sequences, regardless of escapeMode.
std::string
diff --git a/cpp/src/slice2matlab/Main.cpp b/cpp/src/slice2matlab/Main.cpp
new file mode 100644
index 00000000000..26ee9ae092c
--- /dev/null
+++ b/cpp/src/slice2matlab/Main.cpp
@@ -0,0 +1,2993 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2017 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#include <IceUtil/DisableWarnings.h>
+#include <IceUtil/CtrlCHandler.h>
+#include <IceUtil/IceUtil.h>
+#include <IceUtil/InputUtil.h>
+#include <IceUtil/Options.h>
+#include <IceUtil/OutputUtil.h>
+#include <IceUtil/StringUtil.h>
+#include <IceUtil/Mutex.h>
+#include <IceUtil/MutexPtrLock.h>
+#include <IceUtil/ConsoleUtil.h>
+#include <IceUtil/FileUtil.h>
+#include <Slice/Checksum.h>
+#include <Slice/Preprocessor.h>
+#include <Slice/FileTracker.h>
+#include <Slice/Parser.h>
+#include <Slice/Util.h>
+#include <cstring>
+#include <climits>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#ifdef _WIN32
+# include <direct.h>
+#else
+# include <unistd.h>
+#endif
+
+using namespace std;
+using namespace Slice;
+using namespace IceUtilInternal;
+
+namespace
+{
+
+string
+lowerCase(const string& s)
+{
+ string result(s);
+ transform(result.begin(), result.end(), result.begin(), ::tolower);
+ return result;
+}
+
+string
+lookupKwd(const string& name)
+{
+ //
+ // Keyword list. *Must* be kept in alphabetical order.
+ //
+ static const string keywordList[] =
+ {
+ "break", "case", "catch", "classdef", "continue", "else", "elseif", "end", "for", "function", "global",
+ "if", "otherwise", "parfor", "persistent", "return", "spmd", "switch", "try", "while"
+ };
+ bool found = binary_search(&keywordList[0],
+ &keywordList[sizeof(keywordList) / sizeof(*keywordList)],
+ name);
+ return found ? "slice_" + name : name;
+}
+
+//
+// Split a scoped name into its components and return the components as a list of (unscoped) identifiers.
+//
+vector<string>
+splitScopedName(const string& scoped)
+{
+ assert(scoped[0] == ':');
+ vector<string> ids;
+ string::size_type next = 0;
+ string::size_type pos;
+ while((pos = scoped.find("::", next)) != string::npos)
+ {
+ pos += 2;
+ if(pos != scoped.size())
+ {
+ string::size_type endpos = scoped.find("::", pos);
+ if(endpos != string::npos)
+ {
+ ids.push_back(scoped.substr(pos, endpos - pos));
+ }
+ }
+ next = pos;
+ }
+ if(next != scoped.size())
+ {
+ ids.push_back(scoped.substr(next));
+ }
+ else
+ {
+ ids.push_back("");
+ }
+
+ return ids;
+}
+
+string
+fixIdent(const string& ident)
+{
+ if(ident[0] != ':')
+ {
+ return lookupKwd(ident);
+ }
+ vector<string> ids = splitScopedName(ident);
+ transform(ids.begin(), ids.end(), ids.begin(), ptr_fun(lookupKwd));
+ stringstream result;
+ for(vector<string>::const_iterator i = ids.begin(); i != ids.end(); ++i)
+ {
+ result << "::" + *i;
+ }
+ return result.str();
+}
+
+string
+replace(string s, string patt, string val)
+{
+ string r = s;
+ string::size_type pos = r.find(patt);
+ while(pos != string::npos)
+ {
+ r.replace(pos, patt.size(), val);
+ pos += val.size();
+ pos = r.find(patt, pos);
+ }
+ return r;
+}
+
+string
+scopedToName(const string& scoped)
+{
+ string str = scoped;
+ if(str.find("::") == 0)
+ {
+ str.erase(0, 2);
+ }
+
+ str = replace(str, "::", ".");
+
+ return fixIdent(str);
+}
+
+//
+// Get the fully-qualified name of the given definition. If a suffix is provided,
+// it is prepended to the definition's unqualified name. If the nameSuffix
+// is provided, it is appended to the container's name.
+//
+string
+getAbsolute(const ContainedPtr& cont, const string& pfx = std::string(), const string& suffix = std::string())
+{
+ return scopedToName(cont->scope() + pfx + cont->name() + suffix);
+}
+
+void
+printHeader(IceUtilInternal::Output& out)
+{
+ static const char* header =
+ "%{\n"
+ "**********************************************************************\n"
+ "\n"
+ "Copyright (c) 2003-2017 ZeroC, Inc. All rights reserved.\n"
+ "\n"
+ "This copy of Ice is licensed to you under the terms described in the\n"
+ "ICE_LICENSE file included in this distribution.\n"
+ "\n"
+ "**********************************************************************\n"
+ "%}\n"
+ ;
+
+ out << header;
+ out << "%\n";
+ out << "% Ice version " << ICE_STRING_VERSION << "\n";
+ out << "%\n";
+}
+
+string
+typeToString(const TypePtr& type)
+{
+ static const char* builtinTable[] =
+ {
+ "uint8",
+ "logical",
+ "int16",
+ "int32",
+ "int64",
+ "single",
+ "double",
+ "char",
+ "Ice.Object",
+ "Ice.ObjectPrx",
+ "",
+ "Ice.Value"
+ };
+
+ if(!type)
+ {
+ return "void";
+ }
+
+ BuiltinPtr builtin = BuiltinPtr::dynamicCast(type);
+ if(builtin)
+ {
+ return builtinTable[builtin->kind()];
+ }
+
+ ClassDeclPtr cl = ClassDeclPtr::dynamicCast(type);
+ if(cl)
+ {
+ return getAbsolute(cl);
+ }
+
+ ProxyPtr proxy = ProxyPtr::dynamicCast(type);
+ if(proxy)
+ {
+ return getAbsolute(proxy->_class(), "", "Prx");
+ }
+
+ DictionaryPtr dict = DictionaryPtr::dynamicCast(type);
+ if(dict)
+ {
+ return "containers.Map";
+ }
+
+ SequencePtr seq = SequencePtr::dynamicCast(type);
+ if(seq)
+ {
+ return "???";
+ }
+
+ ContainedPtr contained = ContainedPtr::dynamicCast(type);
+ if(contained)
+ {
+ return getAbsolute(contained);
+ }
+
+ return "???";
+}
+
+string
+dictionaryTypeToString(const TypePtr& type, bool key)
+{
+ assert(type);
+
+ BuiltinPtr builtin = BuiltinPtr::dynamicCast(type);
+ if(builtin)
+ {
+ switch(builtin->kind())
+ {
+ case Builtin::KindBool:
+ case Builtin::KindByte:
+ case Builtin::KindShort:
+ {
+ //
+ // containers.Map supports a limited number of key types.
+ //
+ return key ? "int32" : typeToString(type);
+ }
+ case Builtin::KindInt:
+ case Builtin::KindLong:
+ case Builtin::KindString:
+ {
+ return typeToString(type);
+ }
+ case Builtin::KindFloat:
+ case Builtin::KindDouble:
+ {
+ assert(!key);
+ return typeToString(type);
+ }
+ case Builtin::KindObject:
+ case Builtin::KindObjectProxy:
+ case Builtin::KindLocalObject:
+ case Builtin::KindValue:
+ {
+ assert(!key);
+ return "any";
+ }
+ default:
+ {
+ return "???";
+ }
+ }
+ }
+
+ EnumPtr en = EnumPtr::dynamicCast(type);
+ if(en)
+ {
+ //
+ // containers.Map doesn't natively support enumerators as keys but we can work around it using int32.
+ //
+ return key ? "int32" : "any";
+ }
+
+ return "any";
+}
+
+bool
+declarePropertyType(const TypePtr& type, bool optional)
+{
+ return !optional && !SequencePtr::dynamicCast(type) && !ProxyPtr::dynamicCast(type) &&
+ !ClassDefPtr::dynamicCast(type);
+}
+
+string
+constantValue(const TypePtr& type, const SyntaxTreeBasePtr& valueType, const string& value)
+{
+ ConstPtr constant = ConstPtr::dynamicCast(valueType);
+ if(constant)
+ {
+ return getAbsolute(constant) + ".value";
+ }
+ else
+ {
+ BuiltinPtr bp;
+ if((bp = BuiltinPtr::dynamicCast(type)))
+ {
+ switch(bp->kind())
+ {
+ case Builtin::KindString:
+ {
+ return "sprintf('" + toStringLiteral(value, "\a\b\f\n\r\t\v", "", Matlab, 255) + "')";
+ }
+ case Builtin::KindBool:
+ case Builtin::KindByte:
+ case Builtin::KindShort:
+ case Builtin::KindInt:
+ case Builtin::KindLong:
+ case Builtin::KindFloat:
+ case Builtin::KindDouble:
+ case Builtin::KindObject:
+ case Builtin::KindObjectProxy:
+ case Builtin::KindLocalObject:
+ case Builtin::KindValue:
+ {
+ return value;
+ }
+
+ default:
+ {
+ return "???";
+ }
+ }
+
+ }
+ else if(EnumPtr::dynamicCast(type))
+ {
+ EnumeratorPtr e = EnumeratorPtr::dynamicCast(valueType);
+ assert(e);
+ return getAbsolute(e);
+ }
+ else
+ {
+ return value;
+ }
+ }
+}
+
+string
+defaultValue(const DataMemberPtr& m)
+{
+ if(m->defaultValueType())
+ {
+ return constantValue(m->type(), m->defaultValueType(), m->defaultValue());
+ }
+ else if(m->optional())
+ {
+ return "[]";
+ }
+ else
+ {
+ BuiltinPtr builtin = BuiltinPtr::dynamicCast(m->type());
+ if(builtin)
+ {
+ switch(builtin->kind())
+ {
+ case Builtin::KindString:
+ return "''";
+ case Builtin::KindBool:
+ return "false";
+ case Builtin::KindByte:
+ case Builtin::KindShort:
+ case Builtin::KindInt:
+ case Builtin::KindLong:
+ case Builtin::KindFloat:
+ case Builtin::KindDouble:
+ return "0";
+ case Builtin::KindObject:
+ case Builtin::KindObjectProxy:
+ case Builtin::KindLocalObject:
+ case Builtin::KindValue:
+ return "[]";
+ }
+ }
+
+ DictionaryPtr dict = DictionaryPtr::dynamicCast(m->type());
+ if(dict)
+ {
+ return "containers.Map('KeyType', '" + typeToString(dict->keyType()) + "', 'ValueType', '" +
+ typeToString(dict->valueType()) + "')";
+ }
+
+ return "[]";
+ }
+}
+
+}
+
+//
+// CodeVisitor generates the Matlab mapping for a translation unit.
+//
+class CodeVisitor : public ParserVisitor
+{
+public:
+
+ CodeVisitor(const string&);
+
+ virtual bool visitClassDefStart(const ClassDefPtr&);
+ virtual bool visitExceptionStart(const ExceptionPtr&);
+ virtual bool visitStructStart(const StructPtr&);
+ virtual void visitSequence(const SequencePtr&);
+ virtual void visitDictionary(const DictionaryPtr&);
+ virtual void visitEnum(const EnumPtr&);
+ virtual void visitConst(const ConstPtr&);
+
+private:
+
+ void openClass(const string&, IceUtilInternal::Output&);
+
+ struct MemberInfo
+ {
+ string fixedName;
+ bool inherited;
+ DataMemberPtr dataMember;
+ };
+ typedef list<MemberInfo> MemberInfoList;
+
+ //
+ // Convert an operation mode into a string.
+ //
+ string getOperationMode(Slice::Operation::Mode);
+
+ void collectClassMembers(const ClassDefPtr&, MemberInfoList&, bool);
+ void collectExceptionMembers(const ExceptionPtr&, MemberInfoList&, bool);
+
+ struct ParamInfo
+ {
+ string fixedName;
+ TypePtr type;
+ bool optional;
+ int tag;
+ ParamDeclPtr param; // 0 == return value
+ };
+ typedef list<ParamInfo> ParamInfoList;
+
+ ParamInfoList getInParams(const OperationPtr&);
+ ParamInfoList getOutParams(const OperationPtr&);
+
+ string getOptionalFormat(const TypePtr&);
+ string getFormatType(FormatType);
+
+ void marshal(IceUtilInternal::Output&, const string&, const string&, const TypePtr&, bool, int, int&);
+ void unmarshal(IceUtilInternal::Output&, const string&, const string&, const TypePtr&, bool, int, int&);
+
+ const string _dir;
+};
+
+//
+// CodeVisitor implementation.
+//
+CodeVisitor::CodeVisitor(const string& dir) :
+ _dir(dir)
+{
+}
+
+bool
+CodeVisitor::visitClassDefStart(const ClassDefPtr& p)
+{
+ const string name = fixIdent(p->name());
+ const string scoped = p->scoped();
+ const ClassList bases = p->bases();
+ const string self = name == "obj" ? "this" : "obj";
+
+ if(p->hasMetaData("matlab:internal"))
+ {
+ return false;
+ }
+
+ if(!p->isInterface())
+ {
+ ClassDefPtr base;
+ if(!bases.empty() && !bases.front()->isInterface())
+ {
+ base = bases.front();
+ }
+
+ IceUtilInternal::Output out;
+ openClass(scoped, out);
+
+ out << nl << "classdef " << name;
+ if(base)
+ {
+ out << " < " << getAbsolute(base);
+ }
+ else if(!p->isLocal())
+ {
+ out << " < Ice.Value";
+ }
+
+ const DataMemberList members = p->dataMembers();
+ if(!members.empty())
+ {
+ out.inc();
+ out << nl << "properties";
+ out.inc();
+ for(DataMemberList::const_iterator q = members.begin(); q != members.end(); ++q)
+ {
+ out << nl << fixIdent((*q)->name());
+ if(declarePropertyType((*q)->type(), (*q)->optional()))
+ {
+ out << " " << typeToString((*q)->type());
+ }
+ }
+ out.dec();
+ out << nl << "end";
+ }
+
+ MemberInfoList allMembers;
+ collectClassMembers(p, allMembers, false);
+
+ if(!allMembers.empty() || !p->isLocal())
+ {
+ out << nl << "methods";
+ out.inc();
+ }
+
+ if(!allMembers.empty())
+ {
+ vector<string> allNames;
+ for(MemberInfoList::const_iterator q = allMembers.begin(); q != allMembers.end(); ++q)
+ {
+ allNames.push_back(q->fixedName);
+ }
+ //
+ // Constructor
+ //
+ out << nl << "function " << self << " = " << name << spar << allNames << epar;
+ out.inc();
+ out << nl << "if nargin == 0";
+ out.inc();
+ for(MemberInfoList::const_iterator q = allMembers.begin(); q != allMembers.end(); ++q)
+ {
+ out << nl << q->fixedName << " = " << defaultValue(q->dataMember) << ';';
+ }
+ out.dec();
+ out << nl << "end";
+ if(base || !p->isLocal())
+ {
+ out << nl << self << " = " << self << "@" << (base ? getAbsolute(base) : "Ice.Value") << spar;
+ for(MemberInfoList::const_iterator q = allMembers.begin(); q != allMembers.end(); ++q)
+ {
+ if(q->inherited)
+ {
+ out << q->fixedName;
+ }
+ }
+ out << epar << ';';
+ }
+ for(MemberInfoList::const_iterator q = allMembers.begin(); q != allMembers.end(); ++q)
+ {
+ if(!q->inherited)
+ {
+ out << nl << self << "." << q->fixedName << " = " << q->fixedName << ';';
+ }
+ }
+ out.dec();
+ out << nl << "end";
+ }
+
+ if(!p->isLocal())
+ {
+ const DataMemberList optionalMembers = p->orderedOptionalDataMembers();
+
+ out << nl << "function id = ice_id(obj)";
+ out.inc();
+ out << nl << "id = obj.ice_staticId();";
+ out.dec();
+ out << nl << "end";
+ out << nl << "function iceWriteImpl_(obj, os)";
+ out.inc();
+ out << nl << "os.startSlice(obj.ice_staticId(), " << p->compactId() << (!base ? ", true" : ", false")
+ << ");";
+ for(DataMemberList::const_iterator d = members.begin(); d != members.end(); ++d)
+ {
+ if(!(*d)->optional())
+ {
+ int idx = 0;
+ marshal(out, "os", "obj." + fixIdent((*d)->name()), (*d)->type(), false, 0, idx);
+ }
+ }
+ for(DataMemberList::const_iterator d = optionalMembers.begin(); d != optionalMembers.end(); ++d)
+ {
+ int idx = 0;
+ marshal(out, "os", "obj." + fixIdent((*d)->name()), (*d)->type(), true, (*d)->tag(), idx);
+ }
+ out << nl << "os.endSlice();";
+ if(base)
+ {
+ out << nl << "iceWriteImpl_@" << getAbsolute(base) << "(obj);";
+ }
+ out.dec();
+ out << nl << "end";
+ out << nl << "function obj = iceReadImpl_(obj, is)";
+ out.inc();
+ out << nl << "is.startSlice();";
+ for(DataMemberList::const_iterator d = members.begin(); d != members.end(); ++d)
+ {
+ if(!(*d)->optional())
+ {
+ int idx = 0;
+ unmarshal(out, "is", "obj." + fixIdent((*d)->name()), (*d)->type(), false, 0, idx);
+ }
+ }
+ for(DataMemberList::const_iterator d = optionalMembers.begin(); d != optionalMembers.end(); ++d)
+ {
+ int idx = 0;
+ unmarshal(out, "is", "obj." + fixIdent((*d)->name()), (*d)->type(), true, (*d)->tag(), idx);
+ }
+ out << nl << "os.endSlice();";
+ if(base)
+ {
+ out << nl << "obj = iceReadImpl_@" << getAbsolute(base) << "(obj);";
+ }
+ out.dec();
+ out << nl << "end";
+ }
+
+ if(!allMembers.empty() || !p->isLocal())
+ {
+ out.dec();
+ out << nl << "end";
+ }
+
+ if(!p->isLocal())
+ {
+ out << nl << "methods(Static)";
+ out.inc();
+ out << nl << "function id = ice_staticId()";
+ out.inc();
+ out << nl << "id = '" << scoped << "';";
+ out.dec();
+ out << nl << "end";
+ out.dec();
+ out << nl << "end";
+ out.dec();
+ }
+
+ out.dec();
+ out << nl << "end";
+ out << nl;
+
+ out.close();
+ }
+ else if(!p->isLocal())
+ {
+ //
+ // Generate proxy class.
+ //
+
+ IceUtilInternal::Output out;
+ openClass(scoped + "Prx", out);
+
+ const string prxName = name + "Prx";
+ const string abs = getAbsolute(p, "", "Prx");
+
+ out << nl << "classdef " << prxName << " < ";
+ if(!bases.empty())
+ {
+ for(ClassList::const_iterator q = bases.begin(); q != bases.end(); ++q)
+ {
+ if(q != bases.begin())
+ {
+ out << " & ";
+ }
+ out << getAbsolute(*q, "", "Prx");
+ }
+ }
+ else
+ {
+ out << "Ice.ObjectPrx";
+ }
+
+ out.inc();
+
+ out << nl << "methods";
+ out.inc();
+
+ //
+ // Constructor.
+ //
+ out << nl << "function obj = " << prxName << "(impl)";
+ out.inc();
+ if(!bases.empty())
+ {
+ for(ClassList::const_iterator q = bases.begin(); q != bases.end(); ++q)
+ {
+ out << nl << "obj = obj@" << getAbsolute(*q, "", "Prx") << "(impl);";
+ }
+ }
+ else
+ {
+ out << nl << "obj = obj@Ice.ObjectPrx(impl);";
+ }
+ out.dec();
+ out << nl << "end";
+
+ //
+ // Operations.
+ //
+ const OperationList ops = p->operations();
+ for(OperationList::const_iterator q = ops.begin(); q != ops.end(); ++q)
+ {
+ OperationPtr op = *q;
+ const ParamInfoList inParams = getInParams(op);
+ const ParamInfoList outParams = getOutParams(op);
+ const bool twowayOnly = !outParams.empty();
+
+ ExceptionList exceptions = op->throws();
+ exceptions.sort();
+ exceptions.unique();
+
+ //
+ // Arrange exceptions into most-derived to least-derived order. If we don't
+ // do this, a base exception handler can appear before a derived exception
+ // handler, causing compiler warnings and resulting in the base exception
+ // being marshaled instead of the derived exception.
+ //
+#if defined(__SUNPRO_CC)
+ exceptions.sort(Slice::derivedToBaseCompare);
+#else
+ exceptions.sort(Slice::DerivedToBaseCompare());
+#endif
+
+ //
+ // Ensure no parameter is named "obj".
+ //
+ string self = "obj";
+ for(ParamInfoList::const_iterator r = outParams.begin(); r != outParams.end(); ++r)
+ {
+ if(r->fixedName == "obj")
+ {
+ self = "obj_";
+ }
+ }
+ for(ParamInfoList::const_iterator r = inParams.begin(); r != inParams.end(); ++r)
+ {
+ if(r->fixedName == "obj")
+ {
+ self = "obj_";
+ }
+ }
+
+ //
+ // Synchronous method.
+ //
+ out << nl << "function ";
+ if(outParams.size() > 1)
+ {
+ out << "[";
+ for(ParamInfoList::const_iterator r = outParams.begin(); r != outParams.end(); ++r)
+ {
+ if(r != outParams.begin())
+ {
+ out << ", ";
+ }
+ out << r->fixedName;
+ }
+ out << "] = ";
+ }
+ else if(outParams.size() == 1)
+ {
+ out << outParams.begin()->fixedName << " = ";
+ }
+ out << fixIdent(op->name()) << spar;
+
+ out << self;
+ for(ParamInfoList::const_iterator r = inParams.begin(); r != inParams.end(); ++r)
+ {
+ out << r->fixedName;
+ }
+ out << "varargin"; // For the optional context
+ out << epar;
+ out.inc();
+
+ if(!inParams.empty())
+ {
+ if(op->format() == DefaultFormat)
+ {
+ out << nl << "os_ = " << self << ".startWriteParams_();";
+ }
+ else
+ {
+ out << nl << "os_ = " << self << ".startWriteParamsWithFormat_(" << getFormatType(op->format())
+ << ");";
+ }
+ for(ParamInfoList::const_iterator r = inParams.begin(); r != inParams.end(); ++r)
+ {
+ int idx = 0;
+ marshal(out, "os_", r->fixedName, r->type, r->optional, r->tag, idx);
+ }
+ out << nl << self << ".endWriteParams_(os_);";
+ }
+
+ out << nl << "[ok_, is_] = " << self << ".invoke_('" << op->name() << "', '"
+ << getOperationMode(op->sendMode()) << "', " << (twowayOnly ? "true" : "false")
+ << ", " << (inParams.empty() ? "[]" : "os_") << ", varargin{:});";
+
+ if(outParams.empty() && exceptions.empty())
+ {
+ out << nl << self << ".checkNoResponse_(ok_, is_);";
+ }
+ else
+ {
+ out << nl << "if ok_";
+ out.inc();
+ if(outParams.empty())
+ {
+ out << nl << "is_.skipEmptyEncapsulation();";
+ }
+ else
+ {
+ out << nl << "is_.startEncapsulation();";
+ //
+ // The return value (if any) appears first. We have to unmarshal any out parameters
+ // before the return value.
+ //
+ for(ParamInfoList::const_iterator r = outParams.begin(); r != outParams.end(); ++r)
+ {
+ if(r->param)
+ {
+ int idx = 0;
+ unmarshal(out, "is_", r->fixedName, r->type, r->optional, r->tag, idx);
+ }
+ }
+ //
+ // Now do the return value if necessary.
+ //
+ if(!outParams.begin()->param)
+ {
+ ParamInfoList::const_iterator r = outParams.begin();
+ int idx = 0;
+ unmarshal(out, "is_", r->fixedName, r->type, r->optional, r->tag, idx);
+ }
+ out << nl << "is_.endEncapsulation();";
+ }
+ out.dec();
+ out << nl << "else";
+ out.inc();
+ out << nl << self << ".throwUserException_" << spar << "is_";
+ for(ExceptionList::const_iterator e = exceptions.begin(); e != exceptions.end(); ++e)
+ {
+ out << "'" + getAbsolute(*e) + "'";
+ }
+ out << epar << ';';
+ out.dec();
+ out << nl << "end";
+ }
+
+ out.dec();
+ out << nl << "end";
+
+ //
+ // Asynchronous method.
+ //
+ out << nl << "function r_ = " << fixIdent(op->name()) << "Async" << spar;
+ out << self;
+ for(ParamInfoList::const_iterator r = inParams.begin(); r != inParams.end(); ++r)
+ {
+ out << r->fixedName;
+ }
+ out << "varargin"; // For the optional context
+ out << epar;
+ out.inc();
+
+ if(!inParams.empty())
+ {
+ if(op->format() == DefaultFormat)
+ {
+ out << nl << "os_ = " << self << ".startWriteParams_();";
+ }
+ else
+ {
+ out << nl << "os_ = " << self << ".startWriteParamsWithFormat_(" << getFormatType(op->format())
+ << ");";
+ }
+ for(ParamInfoList::const_iterator r = inParams.begin(); r != inParams.end(); ++r)
+ {
+ int idx = 0;
+ marshal(out, "os_", r->fixedName, r->type, r->optional, r->tag, idx);
+ }
+ out << nl << self << ".endWriteParams_(os_);";
+ }
+
+ if(!outParams.empty() || !exceptions.empty())
+ {
+ out << nl << "function varargout = unmarshal(ok_, is_)";
+ out.inc();
+ out << nl << "if ok_";
+ out.inc();
+ if(outParams.empty())
+ {
+ out << nl << "is_.skipEmptyEncapsulation();";
+ }
+ else
+ {
+ out << nl << "is_.startEncapsulation();";
+ int pos = op->returnType() ? 2 : 1;
+ //
+ // The return value (if any) appears first. We have to unmarshal any out parameters
+ // before the return value.
+ //
+ for(ParamInfoList::const_iterator r = outParams.begin(); r != outParams.end(); ++r)
+ {
+ if(r->param)
+ {
+ int idx = 0;
+ unmarshal(out, "is_", r->fixedName, r->type, r->optional, r->tag, idx);
+ out << nl << "varargout{" << pos++ << "} = " << r->fixedName << ';';
+ }
+ }
+ //
+ // Now do the return value if necessary.
+ //
+ if(!outParams.begin()->param)
+ {
+ ParamInfoList::const_iterator r = outParams.begin();
+ int idx = 0;
+ unmarshal(out, "is_", r->fixedName, r->type, r->optional, r->tag, idx);
+ out << nl << "varargout{1} = " << r->fixedName << ';';
+ }
+ out << nl << "is_.endEncapsulation();";
+ }
+ out.dec();
+ out << nl << "else";
+ out.inc();
+ out << nl << self << ".throwUserException_" << spar << "is_";
+ for(ExceptionList::const_iterator e = exceptions.begin(); e != exceptions.end(); ++e)
+ {
+ out << "'" + getAbsolute(*e) + "'";
+ }
+ out << epar << ';';
+ out.dec();
+ out << nl << "end";
+ out.dec();
+ out << nl << "end";
+ }
+
+ out << nl << "r_ = " << self << ".invokeAsync_('" << op->name() << "', '"
+ << getOperationMode(op->sendMode()) << "', " << (twowayOnly ? "true" : "false") << ", "
+ << (inParams.empty() ? "[]" : "os_") << ", " << outParams.size() << ", ";
+ if(!outParams.empty() || !exceptions.empty())
+ {
+ out << "@unmarshal";
+ }
+ else
+ {
+ out << "[]";
+ }
+ out << ", varargin{:});";
+
+ out.dec();
+ out << nl << "end";
+ }
+
+ out.dec();
+ out << nl << "end";
+
+ out << nl << "methods(Static)";
+ out.inc();
+ out << nl << "function id = ice_staticId()";
+ out.inc();
+ out << nl << "id = '" << scoped << "';";
+ out.dec();
+ out << nl << "end";
+ out << nl << "function r = ice_read(is_)";
+ out.inc();
+ out << nl << "r = Ice.ObjectPrx.read_(is_, '" << abs << "');";
+ out.dec();
+ out << nl << "end";
+ out << nl << "function r = checkedCast(p, varargin)";
+ out.inc();
+ out << nl << "r = Ice.ObjectPrx.checkedCast_(p, " << abs << ".ice_staticId(), '" << abs << "', varargin{:});";
+ out.dec();
+ out << nl << "end";
+ out << nl << "function r = uncheckedCast(p, varargin)";
+ out.inc();
+ out << nl << "r = Ice.ObjectPrx.uncheckedCast_(p, '" << abs << "', varargin{:});";
+ out.dec();
+ out << nl << "end";
+ out.dec();
+ out << nl << "end";
+
+ out.dec();
+ out << nl << "end";
+ out << nl;
+
+ out.close();
+ }
+ else
+ {
+ //
+ // Generate local abstract class.
+ //
+
+ IceUtilInternal::Output out;
+ openClass(scoped, out);
+
+ out << nl << "classdef (Abstract) " << name;
+ if(!bases.empty())
+ {
+ out << " < ";
+ for(ClassList::const_iterator q = bases.begin(); q != bases.end(); ++q)
+ {
+ if(q != bases.begin())
+ {
+ out << " & ";
+ }
+ out << " < " << getAbsolute(*q);
+ }
+ }
+
+ const OperationList ops = p->operations();
+ if(!ops.empty())
+ {
+ out.inc();
+ out << nl << "methods(Abstract)";
+ out.inc();
+ for(OperationList::const_iterator q = ops.begin(); q != ops.end(); ++q)
+ {
+ OperationPtr op = *q;
+ const ParamInfoList outParams = getOutParams(op);
+ out << nl;
+ if(outParams.size() > 1)
+ {
+ out << "[";
+ for(ParamInfoList::const_iterator r = outParams.begin(); r != outParams.end(); ++r)
+ {
+ if(r != outParams.begin())
+ {
+ out << ", ";
+ }
+ out << r->fixedName;
+ }
+ out << "] = ";
+ }
+ else if(outParams.size() == 1)
+ {
+ out << outParams.begin()->fixedName << " = ";
+ }
+ out << fixIdent(op->name()) << spar;
+ string self = "obj";
+ const ParamInfoList inParams = getInParams(op);
+ for(ParamInfoList::const_iterator r = outParams.begin(); r != outParams.end(); ++r)
+ {
+ if(r->fixedName == "obj")
+ {
+ self = "obj_";
+ }
+ }
+ for(ParamInfoList::const_iterator r = inParams.begin(); r != inParams.end(); ++r)
+ {
+ if(r->fixedName == "obj")
+ {
+ self = "obj_";
+ }
+ }
+ out << self;
+ for(ParamInfoList::const_iterator r = inParams.begin(); r != inParams.end(); ++r)
+ {
+ out << r->fixedName;
+ }
+ out << epar;
+ }
+ out.dec();
+ out << nl << "end";
+ out.dec();
+ }
+
+ out << nl << "end";
+ out << nl;
+
+ out.close();
+ }
+
+ return false;
+}
+
+bool
+CodeVisitor::visitExceptionStart(const ExceptionPtr& p)
+{
+ const string name = fixIdent(p->name());
+ const string scoped = p->scoped();
+
+ IceUtilInternal::Output out;
+ openClass(scoped, out);
+
+ ExceptionPtr base = p->base();
+
+ out << nl << "classdef " << name;
+ if(base)
+ {
+ out << " < " << getAbsolute(base);
+ }
+ else if(p->isLocal())
+ {
+ out << " < Ice.LocalException";
+ }
+ else
+ {
+ out << " < Ice.UserException";
+ }
+
+ const DataMemberList members = p->dataMembers();
+ if(!members.empty())
+ {
+ out.inc();
+ out << nl << "properties";
+ out.inc();
+ for(DataMemberList::const_iterator q = members.begin(); q != members.end(); ++q)
+ {
+ out << nl << fixIdent((*q)->name());
+ if(declarePropertyType((*q)->type(), (*q)->optional()))
+ {
+ out << " " << typeToString((*q)->type());
+ }
+ }
+ out.dec();
+ out << nl << "end";
+ }
+
+ MemberInfoList allMembers;
+ collectExceptionMembers(p, allMembers, false);
+
+ vector<string> allNames;
+ for(MemberInfoList::const_iterator q = allMembers.begin(); q != allMembers.end(); ++q)
+ {
+ allNames.push_back(q->fixedName);
+ }
+ out << nl << "methods";
+ out.inc();
+
+ const string self = name == "obj" ? "this" : "obj";
+
+ //
+ // Constructor
+ //
+ out << nl << "function " << self << " = " << name << spar << "ice_exid" << "ice_exmsg" << allNames << epar;
+ out.inc();
+ string exid = getAbsolute(p);
+ const string exmsg = getAbsolute(p); // TODO: Allow a message to be specified via metadata?
+ //
+ // The ID argument must use colon separators.
+ //
+ string::size_type pos = exid.find('.');
+ assert(pos != string::npos);
+ while(pos != string::npos)
+ {
+ exid[pos] = ':';
+ pos = exid.find('.', pos);
+ }
+
+ if(!allMembers.empty())
+ {
+ out << nl << "if nargin <= 2";
+ out.inc();
+ for(MemberInfoList::const_iterator q = allMembers.begin(); q != allMembers.end(); ++q)
+ {
+ out << nl << q->fixedName << " = " << defaultValue(q->dataMember) << ';';
+ }
+ out.dec();
+ out << nl << "end";
+ }
+
+ out << nl << "if nargin == 0 || isempty(ice_exid)";
+ out.inc();
+ out << nl << "ice_exid = '" << exid << "';";
+ out.dec();
+ out << nl << "end";
+
+ out << nl << "if nargin < 2 || isempty(ice_exmsg)";
+ out.inc();
+ out << nl << "ice_exmsg = '" << exmsg << "';";
+ out.dec();
+ out << nl << "end";
+
+ if(!base)
+ {
+ out << nl << self << " = " << self << "@" << (p->isLocal() ? "Ice.LocalException" : "Ice.UserException")
+ << spar << "ice_exid" << "ice_exmsg" << epar << ';';
+ }
+ else
+ {
+ out << nl << self << " = " << self << "@" << getAbsolute(base) << spar << "ice_exid" << "ice_exmsg";
+ for(MemberInfoList::const_iterator q = allMembers.begin(); q != allMembers.end(); ++q)
+ {
+ if(q->inherited)
+ {
+ out << q->fixedName;
+ }
+ }
+ out << epar << ';';
+ }
+ for(MemberInfoList::const_iterator q = allMembers.begin(); q != allMembers.end(); ++q)
+ {
+ if(!q->inherited)
+ {
+ out << nl << self << "." << q->fixedName << " = " << q->fixedName << ';';
+ }
+ }
+ out.dec();
+ out << nl << "end";
+
+ out << nl << "function id = ice_id(obj)";
+ out.inc();
+ out << nl << "id = '" << scoped << "';";
+ out.dec();
+ out << nl << "end";
+
+ out << nl << "function obj = readImpl_(obj, is_)";
+ out.inc();
+ out << nl << "is_.startSlice();";
+ for(DataMemberList::const_iterator q = members.begin(); q != members.end(); ++q)
+ {
+ int idx = 0;
+ unmarshal(out, "is_", "obj." + fixIdent((*q)->name()), (*q)->type(), false, 0, idx);
+ }
+ out << nl << "is_.endSlice();";
+ if(base)
+ {
+ out << nl << "obj = readImpl_@" << getAbsolute(base) << "(obj);";
+ }
+ out.dec();
+ out << nl << "end";
+
+ if(p->usesClasses(false))
+ {
+ if(!base || (base && !base->usesClasses(false)))
+ {
+ out << nl << "function r = usesClasses_(obj)";
+ out.inc();
+ out << nl << "r = true;";
+ out.dec();
+ out << nl << "end";
+ }
+ }
+
+ out.dec();
+ out << nl << "end";
+
+ out.dec();
+ out << nl << "end";
+ out << nl;
+
+ out.close();
+
+ return false;
+}
+
+bool
+CodeVisitor::visitStructStart(const StructPtr& p)
+{
+ const string name = fixIdent(p->name());
+ const string scoped = p->scoped();
+ const string abs = getAbsolute(p);
+
+ IceUtilInternal::Output out;
+ openClass(scoped, out);
+
+ out << nl << "classdef " << name;
+
+ const DataMemberList members = p->dataMembers();
+ out.inc();
+ out << nl << "properties";
+ out.inc();
+ vector<string> memberNames;
+ for(DataMemberList::const_iterator q = members.begin(); q != members.end(); ++q)
+ {
+ const string m = fixIdent((*q)->name());
+ memberNames.push_back(m);
+ out << nl << m;
+ if(declarePropertyType((*q)->type(), false))
+ {
+ out << " " << typeToString((*q)->type());
+ }
+ }
+ out.dec();
+ out << nl << "end";
+
+ out << nl << "methods";
+ out.inc();
+ string self = name == "obj" ? "this" : "obj";
+ out << nl << "function " << self << " = " << name << spar << memberNames << epar;
+ out.inc();
+ out << nl << "if nargin > 0";
+ out.inc();
+ for(vector<string>::const_iterator q = memberNames.begin(); q != memberNames.end(); ++q)
+ {
+ out << nl << self << "." << *q << " = " << *q << ';';
+ }
+ out.dec();
+ out << nl << "else";
+ out.inc();
+ for(DataMemberList::const_iterator q = members.begin(); q != members.end(); ++q)
+ {
+ out << nl << self << "." << fixIdent((*q)->name()) << " = " << defaultValue(*q) << ';';
+ }
+ out.dec();
+ out << nl << "end";
+ out.dec();
+ out << nl << "end";
+
+ out.dec();
+ out << nl << "end";
+
+ if(!p->isLocal())
+ {
+ out << nl << "methods(Static)";
+ out.inc();
+ out << nl << "function r = ice_read(is_)";
+ out.inc();
+ out << nl << "r = " << abs << "();";
+ for(DataMemberList::const_iterator q = members.begin(); q != members.end(); ++q)
+ {
+ int idx = 0;
+ unmarshal(out, "is_", "r." + fixIdent((*q)->name()), (*q)->type(), false, 0, idx);
+ }
+ out.dec();
+ out << nl << "end";
+ out << nl << "function ice_write(os_, v_)";
+ out.inc();
+ out << nl << "if isempty(v_)";
+ out.inc();
+ out << nl << "v_ = " << abs << "();";
+ out.dec();
+ out << nl << "end";
+ for(DataMemberList::const_iterator q = members.begin(); q != members.end(); ++q)
+ {
+ int idx = 0;
+ marshal(out, "os_", "v_." + fixIdent((*q)->name()), (*q)->type(), false, 0, idx);
+ }
+ out.dec();
+ out << nl << "end";
+ out.dec();
+ out << nl << "end";
+ }
+
+ out.dec();
+ out << nl << "end";
+ out << nl;
+
+ out.close();
+
+ return false;
+}
+
+void
+CodeVisitor::visitSequence(const SequencePtr& p)
+{
+ if(p->isLocal())
+ {
+ return;
+ }
+
+ const TypePtr content = p->type();
+
+ const BuiltinPtr bp = BuiltinPtr::dynamicCast(content);
+ if(bp)
+ {
+ switch(bp->kind())
+ {
+ case Builtin::KindBool:
+ case Builtin::KindByte:
+ case Builtin::KindShort:
+ case Builtin::KindInt:
+ case Builtin::KindLong:
+ case Builtin::KindFloat:
+ case Builtin::KindDouble:
+ case Builtin::KindString:
+ {
+ return;
+ }
+ case Builtin::KindObject:
+ case Builtin::KindObjectProxy:
+ case Builtin::KindValue:
+ {
+ break;
+ }
+ case Builtin::KindLocalObject:
+ {
+ assert(false);
+ }
+ }
+ }
+
+ const string name = fixIdent(p->name());
+ const string scoped = p->scoped();
+
+ IceUtilInternal::Output out;
+ openClass(scoped, out);
+
+ out << nl << "classdef " << name;
+ out.inc();
+ out << nl << "methods(Static)";
+ out.inc();
+
+ out << nl << "function write(os, seq)";
+ out.inc();
+ out << nl << "sz = length(seq);";
+ out << nl << "os.writeSize(sz);";
+ out << nl << "for i = 1:sz";
+ out.inc();
+ int idx = 0;
+ marshal(out, "os", "seq{i}", content, false, 0, idx);
+ out.dec();
+ out << nl << "end";
+ out.dec();
+ out << nl << "end";
+
+ out << nl << "function r = read(is)";
+ out.inc();
+ out << nl << "sz = is.readSize();";
+ out << nl << "r = {};";
+ out << nl << "for i = 1:sz";
+ out.inc();
+ idx = 0;
+ unmarshal(out, "is", "r{i}", content, false, 0, idx);
+ out.dec();
+ out << nl << "end";
+
+ out.dec();
+ out << nl << "end";
+ out.dec();
+ out << nl << "end";
+ out.dec();
+ out << nl << "end";
+ out << nl;
+
+ out.close();
+}
+
+void
+CodeVisitor::visitDictionary(const DictionaryPtr& p)
+{
+ const TypePtr key = p->keyType();
+ const TypePtr value = p->valueType();
+
+ const StructPtr st = StructPtr::dynamicCast(key);
+
+ const string name = fixIdent(p->name());
+ const string scoped = p->scoped();
+ const string abs = getAbsolute(p);
+ const string self = name == "obj" ? "this" : "obj";
+
+ IceUtilInternal::Output out;
+ openClass(scoped, out);
+
+ out << nl << "classdef " << name;
+ out.inc();
+ out << nl << "methods(Access=private)";
+ out.inc();
+ //
+ // Declare a private constructor so that programs can't instantiate this type. They need to use new().
+ //
+ out << nl << "function " << self << " = " << name << "()";
+ out.inc();
+ out << nl << "% Use new()";
+ out.dec();
+ out << nl << "end";
+ out.dec();
+ out << nl << "end";
+ out << nl << "methods(Static)";
+ out.inc();
+ out << nl << "function r = new()";
+ out.inc();
+ if(st)
+ {
+ out << nl << "r = struct();";
+ }
+ else
+ {
+ out << nl << "r = containers.Map('KeyType', '" << dictionaryTypeToString(key, true) << "', 'ValueType', '"
+ << dictionaryTypeToString(value, false) << "');";
+ }
+ out.dec();
+ out << nl << "end";
+
+ if(!p->isLocal())
+ {
+ out << nl << "function write(os, d)";
+ out.inc();
+ out << nl << "if isempty(d)";
+ out.inc();
+ out << nl << "os.writeSize(0);";
+ out.dec();
+ out << nl << "else";
+ out.inc();
+ if(st)
+ {
+ out << nl << "sz = length(d);";
+ out << nl << "os.writeSize(sz);";
+ out << nl << "for i = 1:sz";
+ out.inc();
+ int idx = 0;
+ marshal(out, "os", "d(i).key", key, false, 0, idx);
+ marshal(out, "os", "d(i).value", value, false, 0, idx);
+ out.dec();
+ out << nl << "end";
+ }
+ else
+ {
+ out << nl << "sz = d.Count;";
+ out << nl << "os.writeSize(sz);";
+ out << nl << "keys = d.keys();";
+ out << nl << "values = d.values();";
+ out << nl << "for i = 1:sz";
+ out.inc();
+ int idx = 0;
+ out << nl << "k = keys{i};";
+ out << nl << "v = values{i};";
+ marshal(out, "os", "k", key, false, 0, idx);
+ marshal(out, "os", "v", value, false, 0, idx);
+ out.dec();
+ out << nl << "end";
+ }
+ out.dec();
+ out << nl << "end";
+ out.dec();
+ out << nl << "end";
+
+ out << nl << "function r = read(is)";
+ out.inc();
+ out << nl << "sz = is.readSize();";
+ out << nl << "r = " << abs << ".new();";
+ out << nl << "for i = 1:sz";
+ out.inc();
+ int idx = 0;
+ unmarshal(out, "is", "k", key, false, 0, idx);
+ unmarshal(out, "is", "v", value, false, 0, idx);
+ if(st)
+ {
+ out << nl << "r(i).key = k;";
+ out << nl << "r(i).value = v;";
+ }
+ else if(EnumPtr::dynamicCast(key))
+ {
+ out << nl << "r(int32(k)) = v;";
+ }
+ else
+ {
+ out << nl << "r(k) = v;";
+ }
+ out.dec();
+ out << nl << "end";
+ out.dec();
+ out << nl << "end";
+ }
+
+ out.dec();
+ out << nl << "end";
+
+ out.dec();
+ out << nl << "end";
+ out << nl;
+
+ out.close();
+}
+
+void
+CodeVisitor::visitEnum(const EnumPtr& p)
+{
+ const string name = fixIdent(p->name());
+ const string scoped = p->scoped();
+ const string abs = getAbsolute(p);
+
+ IceUtilInternal::Output out;
+ openClass(scoped, out);
+
+ out << nl << "classdef " << name << " < int32";
+
+ const EnumeratorList enumerators = p->enumerators();
+ out.inc();
+ out << nl << "enumeration";
+ out.inc();
+ for(EnumeratorList::const_iterator q = enumerators.begin(); q != enumerators.end(); ++q)
+ {
+ out << nl << fixIdent((*q)->name()) << " (" << (*q)->value() << ")";
+ }
+ out.dec();
+ out << nl << "end";
+
+ out << nl << "methods(Static)";
+ out.inc();
+ if(!p->isLocal())
+ {
+ out << nl << "function ice_write(os, v)";
+ out.inc();
+ out << nl << "if isempty(v)";
+ out.inc();
+ string firstEnum = fixIdent(enumerators.front()->name());
+ out << nl << "os.writeEnum(int32(" << abs << "." << firstEnum << "), " << p->maxValue() << ");";
+ out.dec();
+ out << nl << "else";
+ out.inc();
+ out << nl << "os.writeEnum(int32(v), " << p->maxValue() << ");";
+ out.dec();
+ out << nl << "end";
+ out.dec();
+ out << nl << "end";
+ out << nl << "function r = ice_read(is)";
+ out.inc();
+ out << nl << "v = is.readEnum(" << p->maxValue() << ");";
+ out << nl << "r = " << abs << ".ice_getValue(v);";
+ out.dec();
+ out << nl << "end";
+ }
+ out << nl << "function r = ice_getValue(v)";
+ out.inc();
+ out << nl << "switch v";
+ out.inc();
+ for(EnumeratorList::const_iterator q = enumerators.begin(); q != enumerators.end(); ++q)
+ {
+ out << nl << "case " << (*q)->value();
+ out.inc();
+ out << nl << "r = " << abs << "." << fixIdent((*q)->name()) << ";";
+ out.dec();
+ }
+ out << nl << "otherwise";
+ out.inc();
+ out << nl << "throw(Ice.MarshalException('', '', sprintf('enumerator value %d is out of range', v)));";
+ out.dec();
+ out.dec();
+ out << nl << "end";
+ out.dec();
+ out << nl << "end";
+
+ out.dec();
+ out << nl << "end";
+
+ out.dec();
+ out << nl << "end";
+ out << nl;
+ out.close();
+}
+
+void
+CodeVisitor::visitConst(const ConstPtr& p)
+{
+ const string name = fixIdent(p->name());
+ const string scoped = p->scoped();
+
+ IceUtilInternal::Output out;
+ openClass(scoped, out);
+
+ out << nl << "classdef " << name;
+
+ out.inc();
+ out << nl << "properties(Constant)";
+ out.inc();
+ out << nl << "value " << typeToString(p->type()) << " = "
+ << constantValue(p->type(), p->valueType(), p->value());
+ out.dec();
+ out << nl << "end";
+
+ out.dec();
+ out << nl << "end";
+ out << nl;
+ out.close();
+ out.close();
+}
+
+void
+CodeVisitor::openClass(const string& scoped, IceUtilInternal::Output& out)
+{
+ vector<string> v = splitScopedName(scoped);
+ assert(v.size() > 1);
+
+ string path;
+ if(!_dir.empty())
+ {
+ path = _dir + "/";
+ }
+
+ //
+ // Create a package directory corresponding to each Slice module.
+ //
+ for(vector<string>::size_type i = 0; i < v.size() - 1; i++)
+ {
+ path += "+" + lookupKwd(v[i]);
+ if(!IceUtilInternal::directoryExists(path))
+ {
+ if(IceUtilInternal::mkdir(path, 0777) != 0)
+ {
+ ostringstream os;
+ os << "cannot create directory `" << path << "': " << strerror(errno);
+ throw FileException(__FILE__, __LINE__, os.str());
+ }
+ FileTracker::instance()->addDirectory(path);
+ }
+ path += "/";
+ }
+
+ //
+ // There are two options:
+ //
+ // 1) Create a subdirectory named "@ClassName" containing a file "ClassName.m".
+ // 2) Create a file named "ClassName.m".
+ //
+ // The class directory is useful if you want to add additional supporting files for the class. We only
+ // generate a single file for a class so we use option 2.
+ //
+ const string cls = lookupKwd(v[v.size() - 1]);
+ path += "/" + cls + ".m";
+
+ out.open(path);
+ printHeader(out);
+ FileTracker::instance()->addFile(path);
+}
+
+string
+CodeVisitor::getOperationMode(Slice::Operation::Mode mode)
+{
+ switch(mode)
+ {
+ case Operation::Normal:
+ return "Normal";
+ case Operation::Nonmutating:
+ return "Nonmutating";
+ case Operation::Idempotent:
+ return "Idempotent";
+ default:
+ return "???";
+ }
+}
+
+void
+CodeVisitor::collectClassMembers(const ClassDefPtr& p, MemberInfoList& allMembers, bool inherited)
+{
+ ClassList bases = p->bases();
+ if(!bases.empty() && !bases.front()->isInterface())
+ {
+ collectClassMembers(bases.front(), allMembers, true);
+ }
+
+ DataMemberList members = p->dataMembers();
+
+ for(DataMemberList::iterator q = members.begin(); q != members.end(); ++q)
+ {
+ MemberInfo m;
+ m.fixedName = fixIdent((*q)->name());
+ m.inherited = inherited;
+ m.dataMember = *q;
+ allMembers.push_back(m);
+ }
+}
+
+void
+CodeVisitor::collectExceptionMembers(const ExceptionPtr& p, MemberInfoList& allMembers, bool inherited)
+{
+ ExceptionPtr base = p->base();
+ if(base)
+ {
+ collectExceptionMembers(base, allMembers, true);
+ }
+
+ DataMemberList members = p->dataMembers();
+
+ for(DataMemberList::iterator q = members.begin(); q != members.end(); ++q)
+ {
+ MemberInfo m;
+ m.fixedName = fixIdent((*q)->name());
+ m.inherited = inherited;
+ m.dataMember = *q;
+ allMembers.push_back(m);
+ }
+}
+
+CodeVisitor::ParamInfoList
+CodeVisitor::getInParams(const OperationPtr& op)
+{
+ const ParamDeclList l = op->inParameters();
+ ParamInfoList r;
+ for(ParamDeclList::const_iterator p = l.begin(); p != l.end(); ++p)
+ {
+ ParamInfo info;
+ info.fixedName = fixIdent((*p)->name());
+ info.type = (*p)->type();
+ info.optional = (*p)->optional();
+ info.tag = (*p)->tag();
+ info.param = *p;
+ r.push_back(info);
+ }
+ return r;
+}
+
+CodeVisitor::ParamInfoList
+CodeVisitor::getOutParams(const OperationPtr& op)
+{
+ const ParamDeclList l = op->outParameters();
+ ParamInfoList r;
+
+ if(op->returnType())
+ {
+ ParamInfo info;
+ info.fixedName = "result";
+ for(ParamDeclList::const_iterator p = l.begin(); p != l.end(); ++p)
+ {
+ if((*p)->name() == "result")
+ {
+ info.fixedName = "result_";
+ break;
+ }
+ }
+ info.type = op->returnType();
+ info.optional = op->returnIsOptional();
+ info.tag = op->returnTag();
+ r.push_back(info);
+ }
+
+ for(ParamDeclList::const_iterator p = l.begin(); p != l.end(); ++p)
+ {
+ ParamInfo info;
+ info.fixedName = fixIdent((*p)->name());
+ info.type = (*p)->type();
+ info.optional = (*p)->optional();
+ info.tag = (*p)->tag();
+ info.param = *p;
+ r.push_back(info);
+ }
+
+ return r;
+}
+
+string
+CodeVisitor::getOptionalFormat(const TypePtr& type)
+{
+ BuiltinPtr bp = BuiltinPtr::dynamicCast(type);
+ if(bp)
+ {
+ switch(bp->kind())
+ {
+ case Builtin::KindByte:
+ case Builtin::KindBool:
+ {
+ return "'OptionalFormatF1'";
+ }
+ case Builtin::KindShort:
+ {
+ return "'OptionalFormatF2'";
+ }
+ case Builtin::KindInt:
+ case Builtin::KindFloat:
+ {
+ return "'OptionalFormatF4'";
+ }
+ case Builtin::KindLong:
+ case Builtin::KindDouble:
+ {
+ return "'OptionalFormatF8'";
+ }
+ case Builtin::KindString:
+ {
+ return "'OptionalFormatVSize'";
+ }
+ case Builtin::KindObject:
+ {
+ return "'OptionalFormatClass'";
+ }
+ case Builtin::KindObjectProxy:
+ {
+ return "'OptionalFormatFSize'";
+ }
+ case Builtin::KindLocalObject:
+ {
+ assert(false);
+ break;
+ }
+ case Builtin::KindValue:
+ {
+ return "'OptionalFormatClass'";
+ }
+ }
+ }
+
+ if(EnumPtr::dynamicCast(type))
+ {
+ return "'OptionalFormatSize'";
+ }
+
+ SequencePtr seq = SequencePtr::dynamicCast(type);
+ if(seq)
+ {
+ return seq->type()->isVariableLength() ? "'OptionalFormatFSize'" : "'OptionalFormatVSize'";
+ }
+
+ DictionaryPtr d = DictionaryPtr::dynamicCast(type);
+ if(d)
+ {
+ return (d->keyType()->isVariableLength() || d->valueType()->isVariableLength()) ?
+ "'OptionalFormatFSize'" : "'OptionalFormatVSize'";
+ }
+
+ StructPtr st = StructPtr::dynamicCast(type);
+ if(st)
+ {
+ return st->isVariableLength() ? "'OptionalFormatFSize'" : "'OptionalFormatVSize'";
+ }
+
+ if(ProxyPtr::dynamicCast(type))
+ {
+ return "'OptionalFormatFSize'";
+ }
+
+ ClassDeclPtr cl = ClassDeclPtr::dynamicCast(type);
+ assert(cl);
+ return "'OptionalFormatClass'";
+}
+
+string
+CodeVisitor::getFormatType(FormatType type)
+{
+ switch(type)
+ {
+ case DefaultFormat:
+ return "Ice.FormatType.DefaultFormat";
+ case CompactFormat:
+ return "Ice.FormatType.CompactFormat";
+ case SlicedFormat:
+ return "Ice.FormatType.SlicedFormat";
+ default:
+ assert(false);
+ }
+
+ return "???";
+}
+
+void
+CodeVisitor::marshal(IceUtilInternal::Output& out, const string& stream, const string& v, const TypePtr& type,
+ bool optional, int tag, int& idx)
+{
+ BuiltinPtr builtin = BuiltinPtr::dynamicCast(type);
+ if(builtin)
+ {
+ switch(builtin->kind())
+ {
+ case Builtin::KindByte:
+ {
+ if(optional)
+ {
+ out << nl << stream << ".writeByteOpt(" << tag << ", " << v << ");";
+ }
+ else
+ {
+ out << nl << stream << ".writeByte(" << v << ");";
+ }
+ break;
+ }
+ case Builtin::KindBool:
+ {
+ if(optional)
+ {
+ out << nl << stream << ".writeBoolOpt(" << tag << ", " << v << ");";
+ }
+ else
+ {
+ out << nl << stream << ".writeBool(" << v << ");";
+ }
+ break;
+ }
+ case Builtin::KindShort:
+ {
+ if(optional)
+ {
+ out << nl << stream << ".writeShortOpt(" << tag << ", " << v << ");";
+ }
+ else
+ {
+ out << nl << stream << ".writeShort(" << v << ");";
+ }
+ break;
+ }
+ case Builtin::KindInt:
+ {
+ if(optional)
+ {
+ out << nl << stream << ".writeIntOpt(" << tag << ", " << v << ");";
+ }
+ else
+ {
+ out << nl << stream << ".writeInt(" << v << ");";
+ }
+ break;
+ }
+ case Builtin::KindLong:
+ {
+ if(optional)
+ {
+ out << nl << stream << ".writeLongOpt(" << tag << ", " << v << ");";
+ }
+ else
+ {
+ out << nl << stream << ".writeLong(" << v << ");";
+ }
+ break;
+ }
+ case Builtin::KindFloat:
+ {
+ if(optional)
+ {
+ out << nl << stream << ".writeFloatOpt(" << tag << ", " << v << ");";
+ }
+ else
+ {
+ out << nl << stream << ".writeFloat(" << v << ");";
+ }
+ break;
+ }
+ case Builtin::KindDouble:
+ {
+ if(optional)
+ {
+ out << nl << stream << ".writeDoubleOpt(" << tag << ", " << v << ");";
+ }
+ else
+ {
+ out << nl << stream << ".writeDouble(" << v << ");";
+ }
+ break;
+ }
+ case Builtin::KindString:
+ {
+ if(optional)
+ {
+ out << nl << stream << ".writeStringOpt(" << tag << ", " << v << ");";
+ }
+ else
+ {
+ out << nl << stream << ".writeString(" << v << ");";
+ }
+ break;
+ }
+ case Builtin::KindObject:
+ case Builtin::KindValue:
+ {
+ if(optional)
+ {
+ out << nl << stream << ".writeValueOpt(" << tag << ", " << v << ");";
+ }
+ else
+ {
+ out << nl << stream << ".writeValue(" << v << ");";
+ }
+ break;
+ }
+ case Builtin::KindObjectProxy:
+ {
+ if(optional)
+ {
+ out << nl << stream << ".writeProxyOpt(" << tag << ", " << v << ");";
+ }
+ else
+ {
+ out << nl << stream << ".writeProxy(" << v << ");";
+ }
+ break;
+ }
+ case Builtin::KindLocalObject:
+ {
+ assert(false);
+ break;
+ }
+ }
+ return;
+ }
+
+ ProxyPtr prx = ProxyPtr::dynamicCast(type);
+ if(prx)
+ {
+ if(optional)
+ {
+ out << nl << stream << ".writeProxyOpt(" << tag << ", " << v << ");";
+ }
+ else
+ {
+ out << nl << stream << ".writeProxy(" << v << ");";
+ }
+ return;
+ }
+
+ ClassDeclPtr cl = ClassDeclPtr::dynamicCast(type);
+ if(cl)
+ {
+ if(optional)
+ {
+ out << nl << stream << ".writeValueOpt(" << tag << ", " << v << ");";
+ }
+ else
+ {
+ out << nl << stream << ".writeValue(" << v << ");";
+ }
+ return;
+ }
+
+ StructPtr st = StructPtr::dynamicCast(type);
+ if(st)
+ {
+ const string typeS = getAbsolute(st);
+ if(optional)
+ {
+ if(optional)
+ {
+ out << nl << "if ~isempty(" << v << ") && " << stream << ".writeOptional(" << tag << ", "
+ << getOptionalFormat(type) << ")";
+ out.inc();
+ }
+
+ if(st->isVariableLength())
+ {
+ out << nl << "pos = " << stream << ".startSize();";
+ out << nl << typeS << ".ice_write(" << stream << ", " << v << ");";
+ out << nl << stream << ".endSize(pos);";
+ }
+ else
+ {
+ out << nl << stream << ".writeSize(" << st->minWireSize() << ");";
+ out << nl << typeS << ".ice_write(" << stream << ", " << v << ");";
+ }
+ if(optional)
+ {
+ out.dec();
+ out << nl << "end";
+ }
+ }
+ else
+ {
+ out << nl << typeS << ".ice_write(" << stream << ", " << v << ");";
+ }
+ return;
+ }
+
+ EnumPtr en = EnumPtr::dynamicCast(type);
+ if(en)
+ {
+ const string typeS = getAbsolute(en);
+ if(optional)
+ {
+ out << nl << "if " << stream << ".writeOptional(" << tag << ", " << getOptionalFormat(type) << ")";
+ out.inc();
+ out << nl << typeS << ".ice_write(" << stream << ", " << v << ");";
+ out.dec();
+ out << nl << "end";
+ }
+ else
+ {
+ out << nl << typeS << ".ice_write(" << stream << ", " << v << ");";
+ }
+ return;
+ }
+
+ DictionaryPtr dict = DictionaryPtr::dynamicCast(type);
+ if(dict)
+ {
+ if(optional)
+ {
+ out << nl << "if " << stream << ".writeOptional(" << tag << ", " << getOptionalFormat(dict) << "))";
+ out.inc();
+ out << nl << getAbsolute(dict) << ".write(" << stream << ", " << v << ");";
+ out.dec();
+ out << nl << "end";
+ }
+ else
+ {
+ out << nl << getAbsolute(dict) << ".write(" << stream << ", " << v << ");";
+ }
+ return;
+ }
+
+ SequencePtr seq = SequencePtr::dynamicCast(type);
+ if(seq)
+ {
+ const TypePtr content = seq->type();
+ const BuiltinPtr b = BuiltinPtr::dynamicCast(content);
+
+ if(b && b->kind() != Builtin::KindObject && b->kind() != Builtin::KindObjectProxy &&
+ b->kind() != Builtin::KindValue)
+ {
+ static const char* builtinTable[] =
+ {
+ "Byte",
+ "Bool",
+ "Short",
+ "Int",
+ "Long",
+ "Float",
+ "Double",
+ "String",
+ "???",
+ "???",
+ "???",
+ "???"
+ };
+ string bs = builtinTable[b->kind()];
+ out << nl << stream << ".write" << builtinTable[b->kind()] << "Seq";
+ if(optional)
+ {
+ out << "Opt(" << tag << ", ";
+ }
+ else
+ {
+ out << "(";
+ }
+ out << v << ");";
+ return;
+ }
+
+ if(optional)
+ {
+ out << nl << "if " << stream << ".writeOptional(" << tag << ", " << getOptionalFormat(seq) << "))";
+ out.inc();
+ out << nl << getAbsolute(seq) << ".write(" << stream << ", " << v << ");";
+ out.dec();
+ out << nl << "end";
+ }
+ else
+ {
+ out << nl << getAbsolute(seq) << ".write(" << stream << ", " << v << ");";
+ }
+ return;
+ }
+
+ assert(false);
+}
+
+
+void
+CodeVisitor::unmarshal(IceUtilInternal::Output& out, const string& stream, const string& v, const TypePtr& type,
+ bool optional, int tag, int& idx)
+{
+ BuiltinPtr builtin = BuiltinPtr::dynamicCast(type);
+ if(builtin)
+ {
+ switch(builtin->kind())
+ {
+ case Builtin::KindByte:
+ {
+ if(optional)
+ {
+ out << nl << v << " = " << stream << ".readByteOpt(" << tag << ");";
+ }
+ else
+ {
+ out << nl << v << " = " << stream << ".readByte();";
+ }
+ break;
+ }
+ case Builtin::KindBool:
+ {
+ if(optional)
+ {
+ out << nl << v << " = " << stream << ".readBoolOpt(" << tag << ");";
+ }
+ else
+ {
+ out << nl << v << " = " << stream << ".readBool();";
+ }
+ break;
+ }
+ case Builtin::KindShort:
+ {
+ if(optional)
+ {
+ out << nl << v << " = " << stream << ".readShortOpt(" << tag << ");";
+ }
+ else
+ {
+ out << nl << v << " = " << stream << ".readShort();";
+ }
+ break;
+ }
+ case Builtin::KindInt:
+ {
+ if(optional)
+ {
+ out << nl << v << " = " << stream << ".readIntOpt(" << tag << ");";
+ }
+ else
+ {
+ out << nl << v << " = " << stream << ".readInt();";
+ }
+ break;
+ }
+ case Builtin::KindLong:
+ {
+ if(optional)
+ {
+ out << nl << v << " = " << stream << ".readLongOpt(" << tag << ");";
+ }
+ else
+ {
+ out << nl << v << " = " << stream << ".readLong();";
+ }
+ break;
+ }
+ case Builtin::KindFloat:
+ {
+ if(optional)
+ {
+ out << nl << v << " = " << stream << ".readFloatOpt(" << tag << ");";
+ }
+ else
+ {
+ out << nl << v << " = " << stream << ".readFloat();";
+ }
+ break;
+ }
+ case Builtin::KindDouble:
+ {
+ if(optional)
+ {
+ out << nl << v << " = " << stream << ".readDoubleOpt(" << tag << ");";
+ }
+ else
+ {
+ out << nl << v << " = " << stream << ".readDouble();";
+ }
+ break;
+ }
+ case Builtin::KindString:
+ {
+ if(optional)
+ {
+ out << nl << v << " = " << stream << ".readStringOpt(" << tag << ");";
+ }
+ else
+ {
+ out << nl << v << " = " << stream << ".readString();";
+ }
+ break;
+ }
+ case Builtin::KindObject:
+ case Builtin::KindValue:
+ {
+#if 0 // TBD
+ if(optional)
+ {
+ out << nl << stream << ".readValue(" << tag << ", " << param << ");";
+ }
+ else if(holder && mode == OptionalNone)
+ {
+ out << nl << stream << ".readValue(" << param << ");";
+ }
+ else
+ {
+ if(patchParams.empty())
+ {
+ out << nl << stream << ".readValue(new Patcher());";
+ }
+ else
+ {
+ out << nl << stream << ".readValue(" << patchParams << ");";
+ }
+ }
+#endif
+ break;
+ }
+ case Builtin::KindObjectProxy:
+ {
+ if(optional)
+ {
+ out << nl << v << " = " << stream << ".readProxyOpt(" << tag << ");";
+ }
+ else
+ {
+ out << nl << v << " = " << stream << ".readProxy();";
+ }
+ break;
+ }
+ case Builtin::KindLocalObject:
+ {
+ assert(false);
+ break;
+ }
+ }
+ return;
+ }
+
+ ProxyPtr prx = ProxyPtr::dynamicCast(type);
+ if(prx)
+ {
+ const string typeS = getAbsolute(prx->_class(), "", "Prx");
+ if(optional)
+ {
+ out << nl << "if " << stream << ".readOptional(" << tag << ", " << getOptionalFormat(type) << ")";
+ out.inc();
+ out << nl << stream << ".skip(4);";
+ out << nl << v << " = " << typeS << ".ice_read(" << stream << ");";
+ out.dec();
+ out << nl << "end";
+ }
+ else
+ {
+ out << nl << v << " = " << typeS << ".ice_read(" << stream << ");";
+ }
+ return;
+ }
+
+ ClassDeclPtr cl = ClassDeclPtr::dynamicCast(type);
+ if(cl)
+ {
+#if 0 // TBD
+ if(optional)
+ {
+ const string typeS = typeToString(type, TypeModeIn, package);
+ out << nl << "if(" << stream << ".readOptional(" << tag << ", " << getOptionalFormat(type) << "))";
+ out << sb;
+ out << nl << stream << ".readValue(new Ice.OptionalObject(" << v << ", " << typeS << ".class, "
+ << getStaticId(type, package) << "));";
+ out << eb;
+ if(mode == OptionalOutParam)
+ {
+ out << nl << "else";
+ out << sb;
+ out << nl << v << ".clear();";
+ out << eb;
+ }
+ }
+ else
+ {
+ if(holder && mode == OptionalNone)
+ {
+ out << nl << stream << ".readValue(" << param << ");";
+ }
+ else
+ {
+ if(patchParams.empty())
+ {
+ out << nl << stream << ".readValue(new Patcher());";
+ }
+ else
+ {
+ out << nl << stream << ".readValue(" << patchParams << ");";
+ }
+ }
+ }
+#endif
+ return;
+ }
+
+ StructPtr st = StructPtr::dynamicCast(type);
+ if(st)
+ {
+ const string typeS = getAbsolute(st);
+ if(optional)
+ {
+ out << nl << "if " << stream << ".readOptional(" << tag << ", " << getOptionalFormat(type) << ")";
+ out.inc();
+
+ if(st->isVariableLength())
+ {
+ out << nl << stream << ".skip(4);";
+ }
+ else
+ {
+ out << nl << stream << ".skipSize();";
+ }
+
+ out << nl << v << " = " << typeS << ".ice_read(" << stream << ");";
+
+ out.dec();
+ out << nl << "end";
+ }
+ else
+ {
+ out << nl << v << " = " << typeS << ".ice_read(" << stream << ");";
+ }
+ return;
+ }
+
+ EnumPtr en = EnumPtr::dynamicCast(type);
+ if(en)
+ {
+ const string typeS = getAbsolute(en);
+ if(optional)
+ {
+ out << nl << "if " << stream << ".readOptional(" << tag << ", " << getOptionalFormat(type) << ")";
+ out.inc();
+ out << nl << v << " = " << typeS << ".ice_read(" << stream << ");";
+ out.dec();
+ out << nl << "end";
+ }
+ else
+ {
+ out << nl << v << " = " << typeS << ".ice_read(" << stream << ");";
+ }
+ return;
+ }
+
+ DictionaryPtr dict = DictionaryPtr::dynamicCast(type);
+ if(dict)
+ {
+ if(optional)
+ {
+ out << nl << "if " << stream << ".readOptional(" << tag << ", " << getOptionalFormat(dict) << "))";
+ out.inc();
+ out << nl << v << " = " << getAbsolute(dict) << ".read(" << stream << ");";
+ out.dec();
+ out << nl << "end";
+ }
+ else
+ {
+ out << nl << v << " = " << getAbsolute(dict) << ".read(" << stream << ");";
+ }
+ return;
+ }
+
+ SequencePtr seq = SequencePtr::dynamicCast(type);
+ if(seq)
+ {
+ const TypePtr content = seq->type();
+ const BuiltinPtr b = BuiltinPtr::dynamicCast(content);
+
+ if(b && b->kind() != Builtin::KindObject && b->kind() != Builtin::KindObjectProxy &&
+ b->kind() != Builtin::KindValue)
+ {
+ static const char* builtinTable[] =
+ {
+ "Byte",
+ "Bool",
+ "Short",
+ "Int",
+ "Long",
+ "Float",
+ "Double",
+ "String",
+ "???",
+ "???",
+ "???",
+ "???"
+ };
+ string bs = builtinTable[b->kind()];
+ out << nl << v << " = " << stream << ".read" << builtinTable[b->kind()] << "Seq";
+ if(optional)
+ {
+ out << "Opt(" << tag << ");";
+ }
+ else
+ {
+ out << "();";
+ }
+ return;
+ }
+
+ if(optional)
+ {
+ out << nl << "if " << stream << ".readOptional(" << tag << ", " << getOptionalFormat(seq) << "))";
+ out.inc();
+ out << nl << v << " = " << getAbsolute(seq) << ".read(" << stream << ");";
+ out.dec();
+ out << nl << "end";
+ }
+ else
+ {
+ out << nl << v << " = " << getAbsolute(seq) << ".read(" << stream << ");";
+ }
+ return;
+ }
+
+ assert(false);
+}
+
+static void
+generate(const UnitPtr& un, const string& dir, bool all, bool checksum, const vector<string>& includePaths)
+{
+ CodeVisitor codeVisitor(dir);
+ un->visit(&codeVisitor, false);
+
+#if 0
+ if(checksum)
+ {
+ ChecksumMap checksums = createChecksums(un);
+ if(!checksums.empty())
+ {
+ out << sp;
+ if(ns)
+ {
+ out << "namespace"; // Global namespace.
+ out << sb;
+ out << "new Ice\\SliceChecksumInit(array(";
+ for(ChecksumMap::const_iterator p = checksums.begin(); p != checksums.end();)
+ {
+ out << nl << "\"" << p->first << "\" => \"";
+ ostringstream str;
+ str.flags(ios_base::hex);
+ str.fill('0');
+ for(vector<unsigned char>::const_iterator q = p->second.begin(); q != p->second.end(); ++q)
+ {
+ str << static_cast<int>(*q);
+ }
+ out << str.str() << "\"";
+ if(++p != checksums.end())
+ {
+ out << ",";
+ }
+ }
+ out << "));";
+ out << eb;
+ }
+ else
+ {
+ for(ChecksumMap::const_iterator p = checksums.begin(); p != checksums.end(); ++p)
+ {
+ out << nl << "$Ice_sliceChecksums[\"" << p->first << "\"] = \"";
+ ostringstream str;
+ str.flags(ios_base::hex);
+ str.fill('0');
+ for(vector<unsigned char>::const_iterator q = p->second.begin(); q != p->second.end(); ++q)
+ {
+ str << static_cast<int>(*q);
+ }
+ out << str.str() << "\";";
+ }
+ }
+ }
+ }
+
+ out << nl; // Trailing newline.
+#endif
+}
+
+namespace
+{
+
+IceUtil::Mutex* globalMutex = 0;
+bool interrupted = false;
+
+class Init
+{
+public:
+
+ Init()
+ {
+ globalMutex = new IceUtil::Mutex;
+ }
+
+ ~Init()
+ {
+ delete globalMutex;
+ globalMutex = 0;
+ }
+};
+
+Init init;
+
+}
+
+static void
+interruptedCallback(int /*signal*/)
+{
+ IceUtilInternal::MutexPtrLock<IceUtil::Mutex> sync(globalMutex);
+
+ interrupted = true;
+}
+
+static void
+usage(const string& n)
+{
+ consoleErr << "Usage: " << n << " [options] slice-files...\n";
+ consoleErr <<
+ "Options:\n"
+ "-h, --help Show this message.\n"
+ "-v, --version Display the Ice version.\n"
+ "-DNAME Define NAME as 1.\n"
+ "-DNAME=DEF Define NAME as DEF.\n"
+ "-UNAME Remove any definition for NAME.\n"
+ "-IDIR Put DIR in the include file search path.\n"
+ "-E Print preprocessor output on stdout.\n"
+ "--output-dir DIR Create files in the directory DIR.\n"
+ "-d, --debug Print debug messages.\n"
+ "--depend Generate Makefile dependencies.\n"
+ "--depend-xml Generate dependencies in XML format.\n"
+ "--depend-file FILE Write dependencies to FILE instead of standard output.\n"
+ "--validate Validate command line options.\n"
+ "--all Generate code for Slice definitions in included files.\n"
+ "--checksum Generate checksums for Slice definitions.\n"
+ ;
+}
+
+int
+compile(const vector<string>& argv)
+{
+ IceUtilInternal::Options opts;
+ opts.addOpt("h", "help");
+ opts.addOpt("v", "version");
+ opts.addOpt("", "validate");
+ opts.addOpt("D", "", IceUtilInternal::Options::NeedArg, "", IceUtilInternal::Options::Repeat);
+ opts.addOpt("U", "", IceUtilInternal::Options::NeedArg, "", IceUtilInternal::Options::Repeat);
+ opts.addOpt("I", "", IceUtilInternal::Options::NeedArg, "", IceUtilInternal::Options::Repeat);
+ opts.addOpt("E");
+ opts.addOpt("", "output-dir", IceUtilInternal::Options::NeedArg);
+ opts.addOpt("", "depend");
+ opts.addOpt("", "depend-xml");
+ opts.addOpt("", "depend-file", IceUtilInternal::Options::NeedArg, "");
+ opts.addOpt("d", "debug");
+ opts.addOpt("", "all");
+ opts.addOpt("", "checksum");
+
+ bool validate = find(argv.begin(), argv.end(), "--validate") != argv.end();
+
+ vector<string> args;
+ try
+ {
+ args = opts.parse(argv);
+ }
+ catch(const IceUtilInternal::BadOptException& e)
+ {
+ consoleErr << argv[0] << ": error: " << e.reason << endl;
+ if(!validate)
+ {
+ usage(argv[0]);
+ }
+ return EXIT_FAILURE;
+ }
+
+ if(opts.isSet("help"))
+ {
+ usage(argv[0]);
+ return EXIT_SUCCESS;
+ }
+
+ if(opts.isSet("version"))
+ {
+ consoleErr << ICE_STRING_VERSION << endl;
+ return EXIT_SUCCESS;
+ }
+
+ vector<string> cppArgs;
+ vector<string> optargs = opts.argVec("D");
+ for(vector<string>::const_iterator i = optargs.begin(); i != optargs.end(); ++i)
+ {
+ cppArgs.push_back("-D" + *i);
+ }
+
+ optargs = opts.argVec("U");
+ for(vector<string>::const_iterator i = optargs.begin(); i != optargs.end(); ++i)
+ {
+ cppArgs.push_back("-U" + *i);
+ }
+
+ vector<string> includePaths = opts.argVec("I");
+ for(vector<string>::const_iterator i = includePaths.begin(); i != includePaths.end(); ++i)
+ {
+ cppArgs.push_back("-I" + Preprocessor::normalizeIncludePath(*i));
+ }
+
+ bool preprocess = opts.isSet("E");
+
+ string output = opts.optArg("output-dir");
+
+ bool depend = opts.isSet("depend");
+
+ bool dependxml = opts.isSet("depend-xml");
+
+ string dependFile = opts.optArg("depend-file");
+
+ bool debug = opts.isSet("debug");
+
+ bool all = opts.isSet("all");
+
+ bool checksum = opts.isSet("checksum");
+
+ if(args.empty())
+ {
+ consoleErr << argv[0] << ": error: no input file" << endl;
+ if(!validate)
+ {
+ usage(argv[0]);
+ }
+ return EXIT_FAILURE;
+ }
+
+ if(depend && dependxml)
+ {
+ consoleErr << argv[0] << ": error: cannot specify both --depend and --depend-xml" << endl;
+ if(!validate)
+ {
+ usage(argv[0]);
+ }
+ return EXIT_FAILURE;
+ }
+
+ if(validate)
+ {
+ return EXIT_SUCCESS;
+ }
+
+ int status = EXIT_SUCCESS;
+
+ IceUtil::CtrlCHandler ctrlCHandler;
+ ctrlCHandler.setCallback(interruptedCallback);
+
+ ostringstream os;
+ if(dependxml)
+ {
+ os << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<dependencies>" << endl;
+ }
+
+ for(vector<string>::const_iterator i = args.begin(); i != args.end(); ++i)
+ {
+ //
+ // Ignore duplicates.
+ //
+ vector<string>::iterator p = find(args.begin(), args.end(), *i);
+ if(p != i)
+ {
+ continue;
+ }
+
+ if(depend || dependxml)
+ {
+ PreprocessorPtr icecpp = Preprocessor::create(argv[0], *i, cppArgs);
+ FILE* cppHandle = icecpp->preprocess(false, "-D__SLICE2PHP__");
+
+ if(cppHandle == 0)
+ {
+ return EXIT_FAILURE;
+ }
+
+ UnitPtr u = Unit::createUnit(false, false, false, false);
+ int parseStatus = u->parse(*i, cppHandle, debug);
+ u->destroy();
+
+ if(parseStatus == EXIT_FAILURE)
+ {
+ return EXIT_FAILURE;
+ }
+
+ if(!icecpp->printMakefileDependencies(os, depend ? Preprocessor::PHP : Preprocessor::SliceXML,
+ includePaths, "-D__SLICE2PHP__"))
+ {
+ return EXIT_FAILURE;
+ }
+
+ if(!icecpp->close())
+ {
+ return EXIT_FAILURE;
+ }
+ }
+ else
+ {
+ PreprocessorPtr icecpp = Preprocessor::create(argv[0], *i, cppArgs);
+ FILE* cppHandle = icecpp->preprocess(false, "-D__SLICE2PHP__");
+
+ if(cppHandle == 0)
+ {
+ return EXIT_FAILURE;
+ }
+
+ if(preprocess)
+ {
+ char buf[4096];
+ while(fgets(buf, static_cast<int>(sizeof(buf)), cppHandle) != ICE_NULLPTR)
+ {
+ if(fputs(buf, stdout) == EOF)
+ {
+ return EXIT_FAILURE;
+ }
+ }
+ if(!icecpp->close())
+ {
+ return EXIT_FAILURE;
+ }
+ }
+ else
+ {
+ UnitPtr u = Unit::createUnit(false, all, false, false);
+ int parseStatus = u->parse(*i, cppHandle, debug);
+
+ if(!icecpp->close())
+ {
+ u->destroy();
+ return EXIT_FAILURE;
+ }
+
+ if(parseStatus == EXIT_FAILURE)
+ {
+ status = EXIT_FAILURE;
+ }
+ else
+ {
+ string base = icecpp->getBaseName();
+ string::size_type pos = base.find_last_of("/\\");
+ if(pos != string::npos)
+ {
+ base.erase(0, pos + 1);
+ }
+
+ try
+ {
+ generate(u, output, all, checksum, includePaths);
+ }
+ catch(const Slice::FileException& ex)
+ {
+ //
+ // If a file could not be created, then cleanup any created files.
+ //
+ FileTracker::instance()->cleanup();
+ u->destroy();
+ consoleErr << argv[0] << ": error: " << ex.reason() << endl;
+ return EXIT_FAILURE;
+ }
+ catch(const string& err)
+ {
+ FileTracker::instance()->cleanup();
+ consoleErr << argv[0] << ": error: " << err << endl;
+ status = EXIT_FAILURE;
+ }
+ }
+
+ u->destroy();
+ }
+ }
+
+ {
+ IceUtilInternal::MutexPtrLock<IceUtil::Mutex> sync(globalMutex);
+
+ if(interrupted)
+ {
+ FileTracker::instance()->cleanup();
+ return EXIT_FAILURE;
+ }
+ }
+ }
+
+ if(dependxml)
+ {
+ os << "</dependencies>\n";
+ }
+
+ if(depend || dependxml)
+ {
+ writeDependencies(os.str(), dependFile);
+ }
+
+ return status;
+}
+
+#ifdef _WIN32
+int wmain(int argc, wchar_t* argv[])
+#else
+int main(int argc, char* argv[])
+#endif
+{
+ vector<string> args = Slice::argvToArgs(argc, argv);
+ try
+ {
+ return compile(args);
+ }
+ catch(const std::exception& ex)
+ {
+ consoleErr << args[0] << ": error:" << ex.what() << endl;
+ return EXIT_FAILURE;
+ }
+ catch(const std::string& msg)
+ {
+ consoleErr << args[0] << ": error:" << msg << endl;
+ return EXIT_FAILURE;
+ }
+ catch(const char* msg)
+ {
+ consoleErr << args[0] << ": error:" << msg << endl;
+ return EXIT_FAILURE;
+ }
+ catch(...)
+ {
+ consoleErr << args[0] << ": error:" << "unknown exception" << endl;
+ return EXIT_FAILURE;
+ }
+}
diff --git a/cpp/src/slice2matlab/Slice2Matlab.rc b/cpp/src/slice2matlab/Slice2Matlab.rc
new file mode 100644
index 00000000000..605db23d085
--- /dev/null
+++ b/cpp/src/slice2matlab/Slice2Matlab.rc
@@ -0,0 +1,33 @@
+#include<IceUtil/ResourceConfig.h>
+
+#define ICE_INTERNALNAME "slice2matlab\0"
+#define ICE_ORIGINALFILENAME "slice2matlab.exe\0"
+
+VS_VERSION_INFO VERSIONINFO
+FILEVERSION ICE_VERSION
+PRODUCTVERSION ICE_VERSION
+FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
+FILEOS VOS_NT_WINDOWS32
+FILETYPE VFT_APP
+FILESUBTYPE VFT2_UNKNOWN
+FILEFLAGS VER_DEBUG
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904e4"
+ BEGIN
+ VALUE "CompanyName", ICE_COMPANY_NAME
+ VALUE "FileDescription", "Slice to Matlab Compiler\0"
+ VALUE "FileVersion", ICE_STRING_VERSION
+ VALUE "InternalName", ICE_INTERNALNAME
+ VALUE "LegalCopyright", ICE_COPYRIGHT
+ VALUE "OriginalFilename", ICE_ORIGINALFILENAME
+ VALUE "ProductName", ICE_PRODUCT_NAME
+ VALUE "ProductVersion", ICE_STRING_VERSION
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1252
+ END
+END
diff --git a/cpp/src/slice2matlab/msbuild/packages.config b/cpp/src/slice2matlab/msbuild/packages.config
new file mode 100644
index 00000000000..8386dfda383
--- /dev/null
+++ b/cpp/src/slice2matlab/msbuild/packages.config
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<packages>
+ <package id="mcpp.v100" version="2.7.2.17" targetFramework="native" />
+ <package id="mcpp.v120" version="2.7.2.17" targetFramework="native" />
+ <package id="mcpp.v140" version="2.7.2.17" targetFramework="native" />
+ <package id="mcpp.v141" version="2.7.2.17" targetFramework="native" />
+</packages> \ No newline at end of file
diff --git a/cpp/src/slice2matlab/msbuild/slice2matlab.vcxproj b/cpp/src/slice2matlab/msbuild/slice2matlab.vcxproj
new file mode 100644
index 00000000000..47bf883da36
--- /dev/null
+++ b/cpp/src/slice2matlab/msbuild/slice2matlab.vcxproj
@@ -0,0 +1,138 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{FBDCD48E-57DB-4CC1-A9D6-7D9F1C97D0E1}</ProjectGuid>
+ <RootNamespace>slice2matlab</RootNamespace>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup>
+ <DefaultPlatformToolset Condition="'$(VisualStudioVersion)' == '10.0' And '$(DefaultPlatformToolset)' == ''">v100</DefaultPlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <Import Project="$(MSBuildThisFileDirectory)\..\..\..\msbuild\ice.cpp98.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Label="Shared">
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <PreprocessorDefinitions>ICE_STATIC_LIBS;ICE_BUILDING_SLICE_COMPILERS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>rpcrt4.lib;advapi32.lib;DbgHelp.lib;Shlwapi.lib</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <PreprocessorDefinitions>ICE_STATIC_LIBS;ICE_BUILDING_SLICE_COMPILERS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>rpcrt4.lib;advapi32.lib;DbgHelp.lib;Shlwapi.lib</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <PreprocessorDefinitions>ICE_STATIC_LIBS;ICE_BUILDING_SLICE_COMPILERS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>rpcrt4.lib;advapi32.lib;DbgHelp.lib;Shlwapi.lib</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <PreprocessorDefinitions>ICE_STATIC_LIBS;ICE_BUILDING_SLICE_COMPILERS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>rpcrt4.lib;advapi32.lib;DbgHelp.lib;Shlwapi.lib</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="..\Main.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <ResourceCompile Include="..\Slice2Matlab.rc" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\..\IceUtil\msbuild\iceutil\iceutil.vcxproj">
+ <Project>{4d1a5110-3176-44ba-8bbb-57bf56519b9f}</Project>
+ </ProjectReference>
+ <ProjectReference Include="..\..\Slice\msbuild\slice.vcxproj">
+ <Project>{57cd6ac2-0c9d-4648-9e9d-5df60c90f18a}</Project>
+ </ProjectReference>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="packages.config" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ <Import Project="..\..\..\msbuild\packages\mcpp.v100.2.7.2.17\build\native\mcpp.v100.targets" Condition="Exists('..\..\..\msbuild\packages\mcpp.v100.2.7.2.17\build\native\mcpp.v100.targets')" />
+ <Import Project="..\..\..\msbuild\packages\mcpp.v120.2.7.2.17\build\native\mcpp.v120.targets" Condition="Exists('..\..\..\msbuild\packages\mcpp.v120.2.7.2.17\build\native\mcpp.v120.targets')" />
+ <Import Project="..\..\..\msbuild\packages\mcpp.v140.2.7.2.17\build\native\mcpp.v140.targets" Condition="Exists('..\..\..\msbuild\packages\mcpp.v140.2.7.2.17\build\native\mcpp.v140.targets')" />
+ <Import Project="..\..\..\msbuild\packages\mcpp.v141.2.7.2.17\build\native\mcpp.v141.targets" Condition="Exists('..\..\..\msbuild\packages\mcpp.v141.2.7.2.17\build\native\mcpp.v141.targets')" />
+ </ImportGroup>
+ <Import Project="$(MSBuildThisFileDirectory)..\..\..\msbuild\ice.sign.targets" />
+ <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
+ <PropertyGroup>
+ <ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
+ </PropertyGroup>
+ <Error Condition="!Exists('..\..\..\msbuild\packages\mcpp.v100.2.7.2.17\build\native\mcpp.v100.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\msbuild\packages\mcpp.v100.2.7.2.17\build\native\mcpp.v100.targets'))" />
+ <Error Condition="!Exists('..\..\..\msbuild\packages\mcpp.v120.2.7.2.17\build\native\mcpp.v120.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\msbuild\packages\mcpp.v120.2.7.2.17\build\native\mcpp.v120.targets'))" />
+ <Error Condition="!Exists('..\..\..\msbuild\packages\mcpp.v140.2.7.2.17\build\native\mcpp.v140.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\msbuild\packages\mcpp.v140.2.7.2.17\build\native\mcpp.v140.targets'))" />
+ <Error Condition="!Exists('..\..\..\msbuild\packages\mcpp.v141.2.7.2.17\build\native\mcpp.v141.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\msbuild\packages\mcpp.v141.2.7.2.17\build\native\mcpp.v141.targets'))" />
+ </Target>
+</Project>
diff --git a/cpp/src/slice2matlab/msbuild/slice2matlab.vcxproj.filters b/cpp/src/slice2matlab/msbuild/slice2matlab.vcxproj.filters
new file mode 100644
index 00000000000..32065e79211
--- /dev/null
+++ b/cpp/src/slice2matlab/msbuild/slice2matlab.vcxproj.filters
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="Source Files">
+ <UniqueIdentifier>{47F3A182-A9BF-4F97-9FCA-5E589023804E}</UniqueIdentifier>
+ <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+ </Filter>
+ <Filter Include="Header Files">
+ <UniqueIdentifier>{696A80CE-5F76-4E59-AE7F-FFBFB029D4B9}</UniqueIdentifier>
+ <Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
+ </Filter>
+ <Filter Include="Resource Files">
+ <UniqueIdentifier>{CD1D3DC3-DAD5-45AC-A584-9C90DB426C23}</UniqueIdentifier>
+ <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="..\Main.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ResourceCompile Include="..\Slice2Matlab.rc">
+ <Filter>Resource Files</Filter>
+ </ResourceCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="packages.config" />
+ </ItemGroup>
+</Project>
diff --git a/matlab/.gitignore b/matlab/.gitignore
new file mode 100644
index 00000000000..54737717b5a
--- /dev/null
+++ b/matlab/.gitignore
@@ -0,0 +1 @@
+*.mexw64
diff --git a/matlab/README.md b/matlab/README.md
new file mode 100644
index 00000000000..5dc1a984fdc
--- /dev/null
+++ b/matlab/README.md
@@ -0,0 +1,92 @@
+# Ice for MATLAB
+
+> *This project is in the prototype stage and is changing rapidly. Do not use
+in a production application.*
+
+## Prerequisites
+
+The build system currently requires Microsoft Visual Studio 2015.
+
+Ice for MATLAB is intended to support MATLAB 2016a or later but has only been
+tested with 2017a.
+
+## Build Instructions
+
+Open a Visual Studio command prompt. For example, with Visual Studio 2015, you
+can open one of:
+
+- VS2015 x86 Native Tools Command Prompt
+- VS2015 x64 Native Tools Command Prompt
+
+Using the first Command Prompt produces `Win32` binaries by default, while
+the second Command Prompt produces `x64` binaries by default. Select the
+platform that matches your MATLAB installation.
+
+In the Command Prompt, change to the `matlab` subdirectory:
+
+ cd matlab
+
+Add the MATLAB `bin` directory to your PATH:
+
+ PATH=<MATLAB installation directory>\bin;%PATH%
+
+Now you're ready to build Ice for MATLAB:
+
+ msbuild msbuild\ice.proj
+
+Upon completion, an x64 build generates the following components:
+
+ - Ice for C++11 library, located in `cpp\bin\x64\Release`
+ - slice2matlab executable, located in `cpp\bin\x64\Release`
+ - icematlab.mexw64 MEX file, located in `matlab\src\IceMatlab`
+ - MATLAB code for core Slice files, located in `matlab\lib\generated`
+
+## Using Ice for MATLAB
+
+### Search Path
+
+Add the following directories to your MATLAB search path:
+
+ - `matlab\lib`
+ - `matlab\lib\generated`
+ - `matlab\src\IceMatlab`
+
+### Slice Files
+
+Use `slice2matlab` to compile your Slice files. Run `slice2matlab -h` for a
+description of its command-line options. You can place the generated `*.m`
+files anywhere you like, but the enclosing directory must be in your MATLAB
+search path.
+
+### Loading the Library
+
+The Ice for MATLAB library can be loaded with this command:
+
+ loadlibrary icematlab
+
+The MEX file depends on `bzip2.dll` and `ice37++11.dll`. The build copied
+these DLLs to `matlab\src\IceMatlab`.
+
+### Running the Test
+
+One test has been ported to MATLAB so far, and the code is located in
+`matlab\test\Ice\operations`. Since Ice for MATLAB only supports client
+functionality, you will have to build and start a test server from a
+different language mapping.
+
+In a Command Prompt, start the test server.
+
+In MATLAB, change to the test directory:
+
+ cd matlab\test\Ice\operations
+
+Now you can start the MATLAB test client. Assuming the server is running on
+the same host, use this command:
+
+ Client.start({})
+
+If you started the server on a different host, use this command instead:
+
+ Client.start({'--Ice.Default.Host=<addr>'})
+
+Replace `<addr>` with the host name or IP address of the server host.
diff --git a/matlab/lib/+Ice/Communicator.m b/matlab/lib/+Ice/Communicator.m
new file mode 100644
index 00000000000..2cce5e4ca49
--- /dev/null
+++ b/matlab/lib/+Ice/Communicator.m
@@ -0,0 +1,31 @@
+%{
+**********************************************************************
+
+Copyright (c) 2003-2017 ZeroC, Inc. All rights reserved.
+
+This copy of Ice is licensed to you under the terms described in the
+ICE_LICENSE file included in this distribution.
+
+**********************************************************************
+%}
+
+classdef Communicator < Ice.WrapperObject
+ methods
+ function self = Communicator(impl)
+ self = self@Ice.WrapperObject(impl);
+ end
+ function r = stringToProxy(self, str)
+ impl = libpointer('voidPtr');
+ Ice.Util.callMethod(self, 'stringToProxy', str, impl);
+ r = Ice.ObjectPrx(impl);
+ end
+ function r = getProperties(self)
+ impl = libpointer('voidPtr');
+ Ice.Util.callMethod(self, 'getProperties', impl);
+ r = Ice.Properties(impl);
+ end
+ function destroy(self)
+ Ice.Util.callMethod(self, 'destroy');
+ end
+ end
+end
diff --git a/matlab/lib/+Ice/Connection.m b/matlab/lib/+Ice/Connection.m
new file mode 100755
index 00000000000..164cc7af7a8
--- /dev/null
+++ b/matlab/lib/+Ice/Connection.m
@@ -0,0 +1,76 @@
+%{
+**********************************************************************
+
+Copyright (c) 2003-2017 ZeroC, Inc. All rights reserved.
+
+This copy of Ice is licensed to you under the terms described in the
+ICE_LICENSE file included in this distribution.
+
+**********************************************************************
+%}
+%
+% Ice version 3.7.0
+%
+
+classdef Connection < Ice.WrapperObject
+ methods
+ function self = Connection(impl)
+ self = self@Ice.WrapperObject(impl);
+ end
+ function close(obj, mode)
+ Ice.Util.callMethod(obj, 'close', mode);
+ end
+ function r = createProxy(obj, id)
+ proxy = libpointer('voidPtr');
+ Ice.Util.callMethod(obj, 'createProxy', id, proxy);
+ r = Ice.ObjectPrx(proxy);
+ end
+ function r = getEndpoint(obj)
+ throw(Ice.FeatureNotSupportedException('', '', 'getEndpoint'));
+ end
+ function flushBatchRequests(obj, compress)
+ Ice.Util.callMethod(obj, 'flushBatchRequests', compress);
+ end
+ function r = flushBatchRequestsAsync(obj)
+ future = libpointer('voidPtr');
+ Ice.Util.callMethod(obj, 'flushBatchRequestsAsync', future);
+ assert(~isNull(future));
+ r = Ice.Future(future, 'flushBatchRequests', 0, 'Ice_SentFuture', []);
+ end
+ function heartbeat(obj)
+ Ice.Util.callMethod(obj, 'heartbeat');
+ end
+ function r = heartbeatAsync(obj)
+ future = libpointer('voidPtr');
+ Ice.Util.callMethod(obj, 'heartbeatAsync', future);
+ assert(~isNull(future));
+ r = Ice.Future(future, 'heartbeat', 0, 'Ice_SentFuture', []);
+ end
+ function setACM(obj, timeout, close, heartbeat)
+ Ice.Util.callMethod(obj, 'setACM', timeout, close, heartbeat);
+ end
+ function r = getACM(obj)
+ r = Ice.Util.callMethodWithResult(obj, 'getACM');
+ end
+ function r = type(obj)
+ r = Ice.Util.callMethodWithResult(obj, 'type');
+ end
+ function r = timeout(obj)
+ t = libpointer('int32Ptr', 0);
+ r = Ice.Util.callMethod(obj, 'timeout', t);
+ r = t.Value;
+ end
+ function r = toString(obj)
+ r = Ice.Util.callMethodWithResult(obj, 'toString');
+ end
+ function r = getInfo(obj)
+ throw(Ice.FeatureNotSupportedException('', '', 'getInfo'));
+ end
+ function setBufferSize(obj, rcvSize, sndSize)
+ Ice.Util.callMethod(obj, 'setBufferSize', rcvSize, sndSize);
+ end
+ function throwException(obj)
+ Ice.Util.callMethod(obj, 'throwException');
+ end
+ end
+end
diff --git a/matlab/lib/+Ice/Exception.m b/matlab/lib/+Ice/Exception.m
new file mode 100644
index 00000000000..47ae4ba719b
--- /dev/null
+++ b/matlab/lib/+Ice/Exception.m
@@ -0,0 +1,21 @@
+%{
+**********************************************************************
+
+Copyright (c) 2003-2017 ZeroC, Inc. All rights reserved.
+
+This copy of Ice is licensed to you under the terms described in the
+ICE_LICENSE file included in this distribution.
+
+**********************************************************************
+%}
+
+classdef (Abstract) Exception < MException
+ methods(Abstract)
+ ice_id(obj)
+ end
+ methods
+ function self = Exception(id, msg)
+ self = self@MException(id, msg)
+ end
+ end
+end
diff --git a/matlab/lib/+Ice/Future.m b/matlab/lib/+Ice/Future.m
new file mode 100644
index 00000000000..1678a804885
--- /dev/null
+++ b/matlab/lib/+Ice/Future.m
@@ -0,0 +1,67 @@
+%{
+**********************************************************************
+
+Copyright (c) 2003-2017 ZeroC, Inc. All rights reserved.
+
+This copy of Ice is licensed to you under the terms described in the
+ICE_LICENSE file included in this distribution.
+
+**********************************************************************
+%}
+
+classdef Future < handle
+ properties(SetAccess=private)
+ ID = 0
+ NumOutputArguments
+ Operation
+ Read = false
+ State = 'running'
+ end
+ methods
+ function obj = Future(impl, op, numOutArgs, type, fetchFunc)
+ obj.impl = impl;
+ obj.Operation = op;
+ obj.NumOutputArguments = numOutArgs;
+ obj.type_ = type;
+ obj.fetchFunc_ = fetchFunc;
+ idPtr = libpointer('uint64Ptr', 0);
+ Ice.Util.callMethodOnType(obj, obj.type_, 'id', idPtr);
+ obj.ID = idPtr.Value;
+ end
+ function delete(obj)
+ if ~isempty(obj.impl)
+ Ice.Util.callMethodOnType(obj, obj.type_, '_release');
+ end
+ end
+ function ok = wait(obj)
+ okPtr = libpointer('uint8Ptr', 0); % Output param
+ Ice.Util.callMethodOnType(obj, obj.type_, 'wait', okPtr);
+ ok = okPtr.Value == 1;
+ end
+ function varargout = fetchOutputs(obj)
+ if obj.Read
+ throw(MException('Ice:InvalidStateException', 'outputs already read'));
+ end
+ if obj.NumOutputArguments == 0
+ Ice.Util.callMethodOnType(obj, obj.type_, 'check');
+ else
+ [varargout{1:nargout}] = obj.fetchFunc_(obj);
+ end
+ obj.Read = true;
+ end
+ function cancel(obj)
+ Ice.Util.callMethodOnType(obj, obj.type_, 'cancel');
+ end
+ function r = get.State(obj)
+ obj.State = Ice.Util.callMethodOnTypeWithResult(obj, obj.type_, 'state');
+ r = obj.State;
+ end
+ end
+ properties(Access=private)
+ type_
+ fetchFunc_
+ end
+ properties(Hidden,SetAccess=protected)
+ impl
+ end
+end
diff --git a/matlab/lib/+Ice/InitializationData.m b/matlab/lib/+Ice/InitializationData.m
new file mode 100644
index 00000000000..56c1570d37e
--- /dev/null
+++ b/matlab/lib/+Ice/InitializationData.m
@@ -0,0 +1,28 @@
+%{
+**********************************************************************
+
+Copyright (c) 2003-2017 ZeroC, Inc. All rights reserved.
+
+This copy of Ice is licensed to you under the terms described in the
+ICE_LICENSE file included in this distribution.
+
+**********************************************************************
+%}
+
+classdef (Sealed) InitializationData
+ methods
+ function r = clone(obj)
+ r = Ice.InitializationData();
+ r.properties_ = obj.properties_;
+ r.logger = obj.logger;
+ r.compactIdResolver = obj.compactIdResolver;
+ r.valueFactoryManager = obj.valueFactoryManager;
+ end
+ end
+ properties
+ properties_
+ logger
+ compactIdResolver
+ valueFactoryManager
+ end
+end
diff --git a/matlab/lib/+Ice/InputStream.m b/matlab/lib/+Ice/InputStream.m
new file mode 100644
index 00000000000..a3dd84bbf4a
--- /dev/null
+++ b/matlab/lib/+Ice/InputStream.m
@@ -0,0 +1,197 @@
+%{
+**********************************************************************
+
+Copyright (c) 2003-2017 ZeroC, Inc. All rights reserved.
+
+This copy of Ice is licensed to you under the terms described in the
+ICE_LICENSE file included in this distribution.
+
+**********************************************************************
+%}
+
+classdef InputStream < Ice.WrapperObject
+ methods
+ function self = InputStream(impl)
+ self = self@Ice.WrapperObject(impl);
+ end
+ function r = readBool(self)
+ v = libpointer('uint8Ptr', 0);
+ Ice.Util.callMethod(self, 'readBool', v);
+ r = v.Value == 1;
+ end
+ function r = readBoolSeq(self)
+ r = Ice.Util.callMethodWithResult(self, 'readBoolSeq');
+ end
+ function r = readBoolOpt(self, tag)
+ r = Ice.Util.callMethodWithResult(self, 'readBoolOpt', tag);
+ end
+ function r = readBoolSeqOpt(self, tag)
+ r = Ice.Util.callMethodWithResult(self, 'readBoolSeqOpt', tag);
+ end
+ function r = readByte(self)
+ v = libpointer('uint8Ptr', 0);
+ Ice.Util.callMethod(self, 'readByte', v);
+ r = v.Value;
+ end
+ function r = readByteSeq(self)
+ r = Ice.Util.callMethodWithResult(self, 'readByteSeq');
+ end
+ function r = readByteOpt(self, tag)
+ r = Ice.Util.callMethodWithResult(self, 'readByteOpt', tag);
+ end
+ function r = readByteSeqOpt(self, tag)
+ r = Ice.Util.callMethodWithResult(self, 'readByteSeqOpt', tag);
+ end
+ function r = readShort(self)
+ v = libpointer('int16Ptr', 0);
+ Ice.Util.callMethod(self, 'readShort', v);
+ r = v.Value;
+ end
+ function r = readShortSeq(self)
+ r = Ice.Util.callMethodWithResult(self, 'readShortSeq');
+ end
+ function r = readShortOpt(self, tag)
+ r = Ice.Util.callMethodWithResult(self, 'readShortOpt', tag);
+ end
+ function r = readShortSeqOpt(self, tag)
+ r = Ice.Util.callMethodWithResult(self, 'readShortSeqOpt', tag);
+ end
+ function r = readInt(self)
+ v = libpointer('int32Ptr', 0);
+ Ice.Util.callMethod(self, 'readInt', v);
+ r = v.Value;
+ end
+ function r = readIntSeq(self)
+ r = Ice.Util.callMethodWithResult(self, 'readIntSeq');
+ end
+ function r = readIntOpt(self, tag)
+ r = Ice.Util.callMethodWithResult(self, 'readIntOpt', tag);
+ end
+ function r = readIntSeqOpt(self, tag)
+ r = Ice.Util.callMethodWithResult(self, 'readIntSeqOpt', tag);
+ end
+ function r = readLong(self)
+ v = libpointer('int64Ptr', 0);
+ Ice.Util.callMethod(self, 'readLong', v);
+ r = v.Value;
+ end
+ function r = readLongSeq(self)
+ r = Ice.Util.callMethodWithResult(self, 'readLongSeq');
+ end
+ function r = readLongOpt(self, tag)
+ r = Ice.Util.callMethodWithResult(self, 'readLongOpt', tag);
+ end
+ function r = readLongSeqOpt(self, tag)
+ r = Ice.Util.callMethodWithResult(self, 'readLongSeqOpt', tag);
+ end
+ function r = readFloat(self)
+ v = libpointer('singlePtr', 0);
+ Ice.Util.callMethod(self, 'readFloat', v);
+ r = v.Value;
+ end
+ function r = readFloatSeq(self)
+ r = Ice.Util.callMethodWithResult(self, 'readFloatSeq');
+ end
+ function r = readFloatOpt(self, tag)
+ r = Ice.Util.callMethodWithResult(self, 'readFloatOpt', tag);
+ end
+ function r = readFloatSeqOpt(self, tag)
+ r = Ice.Util.callMethodWithResult(self, 'readFloatSeqOpt', tag);
+ end
+ function r = readDouble(self)
+ v = libpointer('doublePtr', 0);
+ Ice.Util.callMethod(self, 'readDouble', v);
+ r = v.Value;
+ end
+ function r = readDoubleSeq(self)
+ r = Ice.Util.callMethodWithResult(self, 'readDoubleSeq');
+ end
+ function r = readDoubleOpt(self, tag)
+ r = Ice.Util.callMethodWithResult(self, 'readDoubleOpt', tag);
+ end
+ function r = readDoubleSeqOpt(self, tag)
+ r = Ice.Util.callMethodWithResult(self, 'readDoubleSeqOpt', tag);
+ end
+ function r = readString(self)
+ r = Ice.Util.callMethodWithResult(self, 'readString');
+ end
+ function r = readStringSeq(self)
+ r = Ice.Util.callMethodWithResult(self, 'readStringSeq');
+ end
+ function r = readStringOpt(self, tag)
+ r = Ice.Util.callMethodWithResult(self, 'readStringOpt', tag);
+ end
+ function r = readStringSeqOpt(self, tag)
+ r = Ice.Util.callMethodWithResult(self, 'readStringSeqOpt', tag);
+ end
+ function skip(self, n)
+ Ice.Util.callMethod(self, 'skip', n);
+ end
+ function startException(self)
+ Ice.Util.callMethod(self, 'startException');
+ end
+ function endException(self)
+ Ice.Util.callMethod(self, 'endException');
+ end
+ function startEncapsulation(self)
+ Ice.Util.callMethod(self, 'startEncapsulation');
+ end
+ function endEncapsulation(self)
+ Ice.Util.callMethod(self, 'endEncapsulation');
+ end
+ function skipEmptyEncapsulation(self)
+ Ice.Util.callMethod(self, 'skipEmptyEncapsulation');
+ end
+ function skipEncapsulation(self)
+ Ice.Util.callMethod(self, 'skipEncapsulation');
+ end
+ function r = getEncoding(self)
+ r = Ice.Util.callMethodWithResult(self, 'getEncoding');
+ end
+ function startSlice(self)
+ Ice.Util.callMethod(self, 'startSlice');
+ end
+ function endSlice(self)
+ Ice.Util.callMethod(self, 'endSlice');
+ end
+ function skipSlice(self)
+ Ice.Util.callMethod(self, 'skipSlice');
+ end
+ function r = readSize(self)
+ v = libpointer('int32Ptr', 0);
+ Ice.Util.callMethod(self, 'readSize', v);
+ r = v.Value;
+ end
+ function r = readOptional(self, tag, fmt)
+ v = libpointer('uint8Ptr', 0);
+ Ice.Util.callMethod(self, 'readOptional', tag, fmt);
+ r = v.Value == 1;
+ end
+ function r = readProxy(self)
+ v = libpointer('voidPtr');
+ Ice.Util.callMethod(self, 'readProxy', v);
+ if ~isNull(v)
+ r = Ice.ObjectPrx(v);
+ else
+ r = [];
+ end
+ end
+ function r = readProxyOpt(self, tag)
+ v = libpointer('voidPtr');
+ Ice.Util.callMethod(self, 'readProxyOpt', tag, v);
+ if ~isNull(v)
+ r = Ice.ObjectPrx(v);
+ else
+ r = [];
+ end
+ end
+ function r = readEnum(self, maxValue)
+ v = libpointer('int32Ptr', 0);
+ Ice.Util.callMethod(self, 'readEnum', maxValue, v);
+ r = v.Value;
+ end
+ function throwException(self)
+ Ice.Util.callMethod(self, 'throwException', self);
+ end
+ end
+end
diff --git a/matlab/lib/+Ice/LocalException.m b/matlab/lib/+Ice/LocalException.m
new file mode 100644
index 00000000000..4406fdb6601
--- /dev/null
+++ b/matlab/lib/+Ice/LocalException.m
@@ -0,0 +1,18 @@
+%{
+**********************************************************************
+
+Copyright (c) 2003-2017 ZeroC, Inc. All rights reserved.
+
+This copy of Ice is licensed to you under the terms described in the
+ICE_LICENSE file included in this distribution.
+
+**********************************************************************
+%}
+
+classdef (Abstract) LocalException < Ice.Exception
+ methods
+ function obj = LocalException(id, msg)
+ obj = obj@Ice.Exception(id, msg)
+ end
+ end
+end
diff --git a/matlab/lib/+Ice/ObjectPrx.m b/matlab/lib/+Ice/ObjectPrx.m
new file mode 100644
index 00000000000..fd45058b589
--- /dev/null
+++ b/matlab/lib/+Ice/ObjectPrx.m
@@ -0,0 +1,763 @@
+%{
+**********************************************************************
+
+Copyright (c) 2003-2017 ZeroC, Inc. All rights reserved.
+
+This copy of Ice is licensed to you under the terms described in the
+ICE_LICENSE file included in this distribution.
+
+**********************************************************************
+%}
+
+classdef ObjectPrx < Ice.WrapperObject
+ methods
+ function self = ObjectPrx(impl)
+ self = self@Ice.WrapperObject(impl);
+ end
+
+ function delete(self)
+ self.callMethod('_release');
+ self.impl = [];
+ end
+
+ %
+ % Override == operator.
+ %
+ function r = eq(self, other)
+ if isempty(other) || ~isa(other, 'Ice.ObjectPrx')
+ r = false;
+ else
+ v = libpointer('uint8Ptr', 0);
+ self.callMethod('equals', other.impl, v);
+ r = v.Value == 1;
+ end
+ end
+
+ function r = ice_createOutputStream(self)
+ stream = libpointer('voidPtr');
+ self.callMethod('ice_createOutputStream', stream);
+ r = Ice.OutputStream(stream);
+ end
+
+ function r = ice_toString(self)
+ r = self.callMethodWithResult('ice_toString');
+ end
+
+ function r = ice_getCommunicator(self)
+ v = libpointer('voidPtr');
+ self.callMethod('ice_getCommunicator', v);
+ assert(~isNull(v));
+ r = Ice.Communicator(v);
+ end
+
+ function ice_ping(self, varargin)
+ [ok, inStream] = self.invoke_('ice_ping', 'Nonmutating', false, [], varargin{:});
+ self.checkNoResponse_(ok, inStream);
+ end
+
+ function r = ice_pingAsync(self, varargin)
+ r = self.invokeAsync_('ice_ping', 'Nonmutating', false, [], 0, [], varargin{:});
+ end
+
+ function r = ice_isA(self, id, varargin)
+ os = self.startWriteParams_();
+ os.writeString(id);
+ self.endWriteParams_(os);
+ [ok, inStream] = self.invoke_('ice_isA', 'Nonmutating', true, os, varargin{:});
+ if ok
+ inStream.startEncapsulation();
+ r = inStream.readBool();
+ inStream.endEncapsulation();
+ else
+ self.throwUserException_(inStream);
+ end
+ end
+
+ function r = ice_isAAsync(self, id, varargin)
+ os = self.startWriteParams_();
+ os.writeString(id);
+ self.endWriteParams_(os);
+ function varargout = unmarshal(ok, is)
+ if ok
+ is.startEncapsulation();
+ varargout{1} = is.readBool();
+ is.endEncapsulation();
+ else
+ self.throwUserException_(is);
+ end
+ end
+ r = self.invokeAsync_('ice_isA', 'Nonmutating', true, os, 1, @unmarshal, varargin{:});
+ end
+
+ function r = ice_id(self, varargin)
+ [ok, inStream] = self.invoke_('ice_id', 'Nonmutating', true, [], varargin{:});
+ if ok
+ inStream.startEncapsulation();
+ r = inStream.readString();
+ inStream.endEncapsulation();
+ else
+ self.throwUserException_(inStream);
+ end
+ end
+
+ function r = ice_idAsync(self, varargin)
+ function varargout = unmarshal(ok, is)
+ if ok
+ is.startEncapsulation();
+ varargout{1} = is.readString();
+ is.endEncapsulation();
+ else
+ self.throwUserException_(is);
+ end
+ end
+ r = self.invokeAsync_('ice_id', 'Nonmutating', true, [], 1, @unmarshal, varargin{:});
+ end
+
+ function r = ice_ids(self, varargin)
+ [ok, inStream] = self.invoke_('ice_ids', 'Nonmutating', true, [], varargin{:});
+ if ok
+ inStream.startEncapsulation();
+ r = inStream.readStringSeq();
+ inStream.endEncapsulation();
+ else
+ self.throwUserException_(inStream);
+ end
+ end
+
+ function r = ice_idsAsync(self, varargin)
+ function varargout = unmarshal(ok, is)
+ if ok
+ is.startEncapsulation();
+ varargout{1} = is.readStringSeq();
+ is.endEncapsulation();
+ else
+ self.throwUserException_(is);
+ end
+ end
+ r = self.invokeAsync_('ice_ids', 'Nonmutating', true, [], 1, @unmarshal, varargin{:});
+ end
+
+ function r = ice_getIdentity(self)
+ r = self.callMethodWithResult('ice_getIdentity');
+ end
+
+ function r = ice_identity(self, id)
+ v = libpointer('voidPtr');
+ self.callMethod('ice_identity', id, v);
+ if isNull(v)
+ r = self;
+ else
+ r = Ice.ObjectPrx(v); % Don't use newInstance_ here
+ end
+ end
+
+ function r = ice_getContext(self)
+ r = self.callMethodWithResult('ice_getContext');
+ end
+
+ function r = ice_context(self, ctx)
+ v = libpointer('voidPtr');
+ self.callMethod('ice_context', ctx, v);
+ if isNull(v)
+ r = self;
+ else
+ r = self.newInstance_(v);
+ end
+ end
+
+ function r = ice_getFacet(self)
+ r = self.callMethodWithResult('ice_getFacet');
+ end
+
+ function r = ice_facet(self, f)
+ v = libpointer('voidPtr');
+ self.callMethod('ice_facet', f, v);
+ if isNull(v)
+ r = self;
+ else
+ r = Ice.ObjectPrx(v); % Don't use newInstance_ here
+ end
+ end
+
+ function r = ice_getAdapterId(self)
+ r = self.callMethodWithResult('ice_getAdapterId');
+ end
+
+ function r = ice_adapterId(self, id)
+ v = libpointer('voidPtr');
+ self.callMethod('ice_adapterId', id, v);
+ if isNull(v)
+ r = self;
+ else
+ r = self.newInstance_(v);
+ end
+ end
+
+ function r = ice_getEndpoints(self)
+ r = self.callMethodWithResult('ice_getEndpoints');
+ end
+
+ function r = ice_endpoints(self, endpts)
+ v = libpointer('voidPtr');
+ self.callMethod('ice_endpoints', endpts, v);
+ if isNull(v)
+ r = self;
+ else
+ r = self.newInstance_(v);
+ end
+ end
+
+ function r = ice_getLocatorCacheTimeout(self)
+ v = libpointer('int32Ptr', 0);
+ self.callMethod('ice_getLocatorCacheTimeout', v);
+ r = v.Value;
+ end
+
+ function r = ice_locatorcacheTimeout(self, t)
+ v = libpointer('voidPtr');
+ self.callMethod('ice_locatorCacheTimeout', t, v);
+ if isNull(v)
+ r = self;
+ else
+ r = self.newInstance_(v);
+ end
+ end
+
+ function r = ice_getInvocationTimeout(self)
+ v = libpointer('int32Ptr', 0);
+ self.callMethod('ice_getInvocationTimeout', v);
+ r = v.Value;
+ end
+
+ function r = ice_invocationTimeout(self, t)
+ v = libpointer('voidPtr');
+ self.callMethod('ice_invocationTimeout', t, v);
+ if isNull(v)
+ r = self;
+ else
+ r = self.newInstance_(v);
+ end
+ end
+
+ function r = ice_getConnectionId(self)
+ r = self.callMethodWithResult('ice_getConnectionId');
+ end
+
+ function r = ice_connectionId(self, id)
+ v = libpointer('voidPtr');
+ self.callMethod('ice_connectionId', id, v);
+ if isNull(v)
+ r = self;
+ else
+ r = self.newInstance_(v);
+ end
+ end
+
+ function r = ice_isConnectionCached(self)
+ v = libpointer('uint8Ptr', 0);
+ self.callMethod('ice_isConnectionCached', v);
+ r = v.Value == 1;
+ end
+
+ function r = ice_connectionCached(self, b)
+ v = libpointer('voidPtr');
+ if b
+ val = 1;
+ else
+ val = 0;
+ end
+ self.callMethod('ice_connectionCached', val, v);
+ if isNull(v)
+ r = self;
+ else
+ r = self.newInstance_(v);
+ end
+ end
+
+ function r = ice_getEndpointSelection(self)
+ v = libpointer('Ice_EndpointSelectionType', 'Random');
+ self.callMethod('ice_getEndpointSelection', v);
+ r = v.Value;
+ end
+
+ function r = ice_endpointSelection(self, t)
+ v = libpointer('voidPtr');
+ self.callMethod('ice_endpointSelection', t, v);
+ if isNull(v)
+ r = self;
+ else
+ r = self.newInstance_(v);
+ end
+ end
+
+ function r = ice_getEncodingVersion(self)
+ r = self.callMethodWithResult('ice_getEncodingVersion');
+ end
+
+ function r = ice_encodingVersion(self, ver)
+ v = libpointer('voidPtr');
+ self.callMethod('ice_encodingVersion', ver, v);
+ if isNull(v)
+ r = self;
+ else
+ r = self.newInstance_(v);
+ end
+ end
+
+ function r = ice_getRouter(self)
+ v = libpointer('voidPtr');
+ self.callMethod('ice_getRouter', v);
+ if isNull(v)
+ r = [];
+ else
+ r = Ice.RouterPrx(v);
+ end
+ end
+
+ function r = ice_router(self, rtr)
+ v = libpointer('voidPtr');
+ if isempty(rtr)
+ impl = libpointer('voidPtr');
+ else
+ impl = rtr.impl;
+ end
+ self.callMethod('ice_router', impl, v);
+ if isNull(v)
+ r = self;
+ else
+ r = self.newInstance_(v);
+ end
+ end
+
+ function r = ice_getLocator(self)
+ v = libpointer('voidPtr');
+ self.callMethod('ice_getLocator', v);
+ if isNull(v)
+ r = [];
+ else
+ r = Ice.LocatorPrx(v);
+ end
+ end
+
+ function r = ice_locator(self, loc)
+ v = libpointer('voidPtr');
+ if isempty(loc)
+ impl = libpointer('voidPtr');
+ else
+ impl = loc.impl;
+ end
+ self.callMethod('ice_locator', impl, v);
+ if isNull(v)
+ r = self;
+ else
+ r = self.newInstance_(v);
+ end
+ end
+
+ function r = ice_isSecure(self)
+ v = libpointer('uint8Ptr', 0);
+ self.callMethod('ice_isSecure', v);
+ r = v.Value == 1;
+ end
+
+ function r = ice_secure(self, b)
+ v = libpointer('voidPtr');
+ if b
+ val = 1;
+ else
+ val = 0;
+ end
+ self.callMethod('ice_secure', val, v);
+ if isNull(v)
+ r = self;
+ else
+ r = self.newInstance_(v);
+ end
+ end
+
+ function r = ice_isPreferSecure(self)
+ v = libpointer('uint8Ptr', 0);
+ self.callMethod('ice_isPreferSecure', v);
+ r = v.Value == 1;
+ end
+
+ function r = ice_preferSecure(self, b)
+ v = libpointer('voidPtr');
+ if b
+ val = 1;
+ else
+ val = 0;
+ end
+ self.callMethod('ice_preferSecure', val, v);
+ if isNull(v)
+ r = self;
+ else
+ r = self.newInstance_(v);
+ end
+ end
+
+ function r = ice_isTwoway(self)
+ v = libpointer('uint8Ptr', 0);
+ self.callMethod('ice_isTwoway', v);
+ r = v.Value == 1;
+ end
+
+ function r = ice_twoway(self)
+ v = libpointer('voidPtr');
+ self.callMethod('ice_twoway', v);
+ if isNull(v)
+ r = self;
+ else
+ r = self.newInstance_(v);
+ end
+ end
+
+ function r = ice_isOneway(self)
+ v = libpointer('uint8Ptr', 0);
+ self.callMethod('ice_isOneway', v);
+ r = v.Value == 1;
+ end
+
+ function r = ice_oneway(self)
+ v = libpointer('voidPtr');
+ self.callMethod('ice_oneway', v);
+ if isNull(v)
+ r = self;
+ else
+ r = self.newInstance_(v);
+ end
+ end
+
+ function r = ice_isBatchOneway(self)
+ v = libpointer('uint8Ptr', 0);
+ self.callMethod('ice_isBatchOneway', v);
+ r = v.Value == 1;
+ end
+
+ function r = ice_batchOneway(self)
+ v = libpointer('voidPtr');
+ self.callMethod('ice_batchOneway', v);
+ if isNull(v)
+ r = self;
+ else
+ r = self.newInstance_(v);
+ end
+ end
+
+ function r = ice_isDatagram(self)
+ v = libpointer('uint8Ptr', 0);
+ self.callMethod('ice_isDatagram', v);
+ r = v.Value == 1;
+ end
+
+ function r = ice_datagram(self)
+ v = libpointer('voidPtr');
+ self.callMethod('ice_datagram', v);
+ if isNull(v)
+ r = self;
+ else
+ r = self.newInstance_(v);
+ end
+ end
+
+ function r = ice_isBatchDatagram(self)
+ v = libpointer('uint8Ptr', 0);
+ self.callMethod('ice_isBatchDatagram', v);
+ r = v.Value == 1;
+ end
+
+ function r = ice_batchDatagram(self)
+ v = libpointer('voidPtr');
+ self.callMethod('ice_batchDatagram', v);
+ if isNull(v)
+ r = self;
+ else
+ r = self.newInstance_(v);
+ end
+ end
+
+ function r = ice_compress(self, b)
+ v = libpointer('voidPtr');
+ if b
+ val = 1;
+ else
+ val = 0;
+ end
+ self.callMethod('ice_compress', val, v);
+ if isNull(v)
+ r = self;
+ else
+ r = self.newInstance_(v);
+ end
+ end
+
+ function r = ice_timeout(self, t)
+ v = libpointer('voidPtr');
+ self.callMethod('ice_timeout', t, v);
+ if isNull(v)
+ r = self;
+ else
+ r = self.newInstance_(v);
+ end
+ end
+
+ function r = ice_getConnection(self)
+ v = libpointer('voidPtr');
+ self.callMethod('ice_getConnection', v);
+ if isNull(v)
+ r = [];
+ else
+ r = Ice.Connection(v);
+ end
+ end
+
+ function r = ice_getConnectionAsync(self)
+ future = libpointer('voidPtr');
+ self.callMethod('ice_getConnectionAsync', future);
+ assert(~isNull(future));
+ function varargout = fetch(f)
+ con = libpointer('voidPtr', 0); % Output param
+ Ice.Util.callMethodOnType(f, 'Ice_GetConnectionFuture', 'fetch', con);
+ assert(~isNull(con));
+ varargout{1} = Ice.Connection(con);
+ end
+ r = Ice.Future(future, 'ice_getConnection', 1, 'Ice_GetConnectionFuture', @fetch);
+ end
+
+ function r = ice_getCachedConnection(self)
+ v = libpointer('voidPtr');
+ self.callMethod('ice_getCachedConnection', v);
+ if isNull(v)
+ r = [];
+ else
+ r = Ice.Connection(v);
+ end
+ end
+
+ function ice_flushBatchRequests(self)
+ self.callMethod('ice_flushBatchRequests');
+ end
+
+ function r = ice_flushBatchRequestsAsync(self)
+ future = libpointer('voidPtr');
+ self.callMethod('ice_flushBatchRequestsAsync', future);
+ assert(~isNull(future));
+ r = Ice.Future(future, 'ice_flushBatchRequests', 0, 'Ice_SentFuture', []);
+ end
+ end
+
+ methods(Access=protected)
+ function checkNoResponse_(self, ok, inStream)
+ if self.ice_isTwoway()
+ if ok == 0
+ try
+ self.throwUserException_(inStream);
+ catch ex
+ ex.throwAsCaller();
+ end
+ else
+ inStream.skipEmptyEncapsulation();
+ end
+ end
+ end
+
+ function os = startWriteParams_(self)
+ os = self.ice_createOutputStream();
+ os.startEncapsulation();
+ end
+
+ function os = startWriteParamsWithFormat_(self, format)
+ os = self.ice_createOutputStream();
+ os.startEncapsulationWithFormat(format);
+ end
+
+ function endWriteParams_(self, os)
+ os.endEncapsulation();
+ end
+
+ function [ok, inStream] = invoke_(self, op, mode, twowayOnly, os, varargin)
+ try
+ % Vararg accepted for optional context argument.
+ if length(varargin) > 1
+ throw(MException('Ice:ArgumentException', 'one optional argument is allowed for request context'))
+ end
+ if twowayOnly && ~self.ice_isTwoway()
+ throw(Ice.TwowayOnlyException('', 'invocation requires twoway proxy', op));
+ end
+ if ~isempty(os)
+ outStream = os.impl;
+ else
+ outStream = libpointer('voidPtr'); % Null pointer for output stream
+ end
+ okPtr = libpointer('uint8Ptr', 0); % Output param
+ inStreamPtr = libpointer('voidPtr'); % Output param
+ if length(varargin) == 1
+ self.callMethod('ice_invoke', op, mode, outStream, varargin{1}, okPtr, inStreamPtr);
+ else
+ self.callMethod('ice_invokeNC', op, mode, outStream, okPtr, inStreamPtr);
+ end
+ ok = okPtr.Value == 1;
+ inStream = [];
+ if ~isNull(inStreamPtr)
+ inStream = Ice.InputStream(inStreamPtr);
+ end
+ catch ex
+ ex.throwAsCaller();
+ end
+ end
+
+ function fut = invokeAsync_(self, op, mode, twowayOnly, os, numOutArgs, unmarshalFunc, varargin)
+ function varargout = fetch(f)
+ okPtr = libpointer('uint8Ptr', 0); % Output param
+ inStreamPtr = libpointer('voidPtr', 0); % Output param
+ Ice.Util.callMethodOnType(f, 'Ice_InvocationFuture', 'stream', okPtr, inStreamPtr);
+ ok = okPtr.Value == 1;
+ assert(~isNull(inStreamPtr));
+ inStream = Ice.InputStream(inStreamPtr);
+ [varargout{1:numOutArgs}] = unmarshalFunc(ok, inStream);
+ end
+ try
+ % Vararg accepted for optional context argument.
+ if length(varargin) > 1
+ throw(MException('Ice:ArgumentException', 'one optional argument is allowed for request context'))
+ end
+ if twowayOnly && ~self.ice_isTwoway()
+ throw(Ice.TwowayOnlyException('', 'invocation requires twoway proxy', op));
+ end
+ if ~isempty(os)
+ outStream = os.impl;
+ else
+ outStream = libpointer('voidPtr'); % Null pointer for output stream
+ end
+ futPtr = libpointer('voidPtr'); % Output param
+ if length(varargin) == 1
+ self.callMethod('ice_invokeAsync', op, mode, outStream, varargin{1}, futPtr);
+ else
+ self.callMethod('ice_invokeAsyncNC', op, mode, outStream, futPtr);
+ end
+ assert(~isNull(futPtr));
+ fut = Ice.Future(futPtr, op, numOutArgs, 'Ice_InvocationFuture', @fetch);
+ catch ex
+ ex.throwAsCaller();
+ end
+ end
+
+ function throwUserException_(self, inStream, varargin) % Varargs are user exception type names
+ try
+ inStream.throwUserException();
+ catch ex
+ if isa(ex, Ice.UserException)
+ for i = 1:length(varargin)
+ if isa(ex, varargin{i})
+ ex.throwAsCaller();
+ end
+ end
+ uue = Ice.UnknownUserException('', '', ex.ice_id());
+ uue.throwAsCaller();
+ else
+ ex.throwAsCaller();
+ end
+ end
+ end
+
+ function r = newInstance_(self, impl)
+ constructor = str2func(class(self)); % Obtain the constructor for this class
+ r = constructor(impl); % Call the constructor
+ end
+
+ function r = clone_(self)
+ implPtr = libpointer('voidPtr'); % Output param
+ self.callMethod('clone', implPtr);
+ r = implPtr;
+ end
+ end
+
+ methods(Access=private)
+ % We don't use the functions in Ice.Util because they use the most-derived class name, whereas we always
+ % want to use Ice_ObjectPrx_xxx.
+ function callMethod(self, fn, varargin)
+ name = strcat('Ice_ObjectPrx_', fn);
+ ex = calllib('icematlab', name, self.impl, varargin{:});
+ if ~isempty(ex)
+ ex.throwAsCaller();
+ end
+ end
+
+ function r = callMethodWithResult(self, fn, varargin)
+ name = strcat('Ice_ObjectPrx_', fn);
+ result = calllib('icematlab', name, self.impl, varargin{:});
+ if ~isempty(result.exception)
+ result.exception.throwAsCaller();
+ end
+ r = result.result;
+ end
+ end
+
+ methods(Static,Access=protected)
+ function r = read_(inStream, cls)
+ p = inStream.readProxy();
+ if ~isempty(p)
+ constructor = str2func(cls);
+ r = constructor(p.clone_());
+ else
+ r = [];
+ end
+ end
+
+ function r = checkedCast_(p, id, cls, varargin)
+ %try
+ hasFacet = false;
+ facet = [];
+ context = {};
+ if length(varargin) == 1
+ facet = varargin{1};
+ hasFacet = true;
+ elseif length(varargin) == 2
+ facet = varargin{1};
+ context = {varargin{2}};
+ elseif length(varargin) > 2
+ throw(MException('Ice:ArgumentException', 'too many arguments to checkedCast'));
+ end
+ if ~isempty(p)
+ if hasFacet
+ p = p.ice_facet(facet);
+ end
+ if isa(p, cls)
+ r = p;
+ elseif p.ice_isA(id, context{:})
+ constructor = str2func(cls);
+ r = constructor(p.clone_());
+ else
+ r = [];
+ end
+ else
+ r = p;
+ end
+ %catch ex
+ % ex.throwAsCaller();
+ %end
+ end
+
+ function r = uncheckedCast_(p, cls, varargin)
+ facet = [];
+ if length(varargin) == 1
+ facet = varargin{1};
+ elseif length(varargin) > 1
+ throw(MException('Ice:ArgumentException', 'too many arguments to uncheckedCast'));
+ end
+ if ~isempty(p)
+ if ~isempty(facet)
+ p = p.ice_facet(facet);
+ end
+ if isa(p, cls)
+ r = p;
+ else
+ constructor = str2func(cls);
+ r = constructor(p.clone_());
+ end
+ else
+ r = p;
+ end
+ end
+ end
+end
diff --git a/matlab/lib/+Ice/Optional.m b/matlab/lib/+Ice/Optional.m
new file mode 100644
index 00000000000..ec30540fd11
--- /dev/null
+++ b/matlab/lib/+Ice/Optional.m
@@ -0,0 +1,48 @@
+%{
+**********************************************************************
+
+Copyright (c) 2003-2017 ZeroC, Inc. All rights reserved.
+
+This copy of Ice is licensed to you under the terms described in the
+ICE_LICENSE file included in this distribution.
+
+**********************************************************************
+%}
+
+classdef Optional
+ methods
+ function obj = Optional(v)
+ if nargin == 0
+ obj.isSet = false
+ else
+ obj.value = v
+ end
+ end
+ function obj = set.value(obj, v)
+ if isempty(v)
+ obj.value = v
+ obj.isSet = false
+ else
+ obj.value = v
+ obj.isSet = true
+ end
+ end
+ function v = get.value(obj)
+ if obj.isSet
+ v = obj.value
+ else
+ throw(MException('ICE:IllegalStateException', 'Optional does not have a value'))
+ end
+ end
+ function obj = clear(obj) % Use with v = v.clear()
+ obj.value = []
+ obj.isSet = false
+ end
+ end
+ properties
+ value
+ end
+ properties(SetAccess = private)
+ isSet
+ end
+end
diff --git a/matlab/lib/+Ice/OutputStream.m b/matlab/lib/+Ice/OutputStream.m
new file mode 100644
index 00000000000..32e5b8220f0
--- /dev/null
+++ b/matlab/lib/+Ice/OutputStream.m
@@ -0,0 +1,161 @@
+%{
+**********************************************************************
+
+Copyright (c) 2003-2017 ZeroC, Inc. All rights reserved.
+
+This copy of Ice is licensed to you under the terms described in the
+ICE_LICENSE file included in this distribution.
+
+**********************************************************************
+%}
+
+classdef OutputStream < Ice.WrapperObject
+ methods
+ function self = OutputStream(impl)
+ self = self@Ice.WrapperObject(impl);
+ end
+ function writeBool(self, v)
+ Ice.Util.callMethod(self, 'writeBool', v);
+ end
+ function writeBoolOpt(self, tag, v)
+ Ice.Util.callMethod(self, 'writeBoolOpt', tag, v);
+ end
+ function writeBoolSeq(self, v)
+ Ice.Util.callMethod(self, 'writeBoolSeq', v, length(v));
+ end
+ function writeBoolSeqOpt(self, tag, v)
+ Ice.Util.callMethod(self, 'writeBoolSeqOpt', tag, v, length(v));
+ end
+ function writeByte(self, v)
+ Ice.Util.callMethod(self, 'writeByte', v);
+ end
+ function writeByteOpt(self, tag, v)
+ Ice.Util.callMethod(self, 'writeByteOpt', tag, v);
+ end
+ function writeByteSeq(self, v)
+ Ice.Util.callMethod(self, 'writeByteSeq', v, length(v));
+ end
+ function writeByteSeqOpt(self, tag, v)
+ Ice.Util.callMethod(self, 'writeByteSeqOpt', tag, v, length(v));
+ end
+ function writeShort(self, v)
+ Ice.Util.callMethod(self, 'writeShort', v);
+ end
+ function writeShortOpt(self, tag, v)
+ Ice.Util.callMethod(self, 'writeShortOpt', tag, v);
+ end
+ function writeShortSeq(self, v)
+ Ice.Util.callMethod(self, 'writeShortSeq', v, length(v));
+ end
+ function writeShortSeqOpt(self, tag, v)
+ Ice.Util.callMethod(self, 'writeShortSeqOpt', tag, v, length(v));
+ end
+ function writeInt(self, v)
+ Ice.Util.callMethod(self, 'writeInt', v);
+ end
+ function writeIntOpt(self, tag, v)
+ Ice.Util.callMethod(self, 'writeIntOpt', tag, v);
+ end
+ function writeIntSeq(self, v)
+ Ice.Util.callMethod(self, 'writeIntSeq', v, length(v));
+ end
+ function writeIntSeqOpt(self, tag, v)
+ Ice.Util.callMethod(self, 'writeIntSeqOpt', tag, v, length(v));
+ end
+ function writeLong(self, v)
+ Ice.Util.callMethod(self, 'writeLong', v);
+ end
+ function writeLongOpt(self, tag, v)
+ Ice.Util.callMethod(self, 'writeLongOpt', tag, v);
+ end
+ function writeLongSeq(self, v)
+ Ice.Util.callMethod(self, 'writeLongSeq', v, length(v));
+ end
+ function writeLongSeqOpt(self, tag, v)
+ Ice.Util.callMethod(self, 'writeLongSeqOpt', tag, v, length(v));
+ end
+ function writeFloat(self, v)
+ Ice.Util.callMethod(self, 'writeFloat', v);
+ end
+ function writeFloatOpt(self, tag, v)
+ Ice.Util.callMethod(self, 'writeFloatOpt', tag, v);
+ end
+ function writeFloatSeq(self, v)
+ Ice.Util.callMethod(self, 'writeFloatSeq', v, length(v));
+ end
+ function writeFloatSeqOpt(self, tag, v)
+ Ice.Util.callMethod(self, 'writeFloatSeqOpt', tag, v, length(v));
+ end
+ function writeDouble(self, v)
+ Ice.Util.callMethod(self, 'writeDouble', v);
+ end
+ function writeDoubleOpt(self, tag, v)
+ Ice.Util.callMethod(self, 'writeDoubleOpt', tag, v);
+ end
+ function writeDoubleSeq(self, v)
+ Ice.Util.callMethod(self, 'writeDoubleSeq', v, length(v));
+ end
+ function writeDoubleSeqOpt(self, tag, v)
+ Ice.Util.callMethod(self, 'writeDoubleSeqOpt', tag, v, length(v));
+ end
+ function writeString(self, str)
+ Ice.Util.callMethod(self, 'writeString', str);
+ end
+ function writeStringOpt(self, tag, str)
+ Ice.Util.callMethod(self, 'writeStringOpt', tag, str);
+ end
+ function writeStringSeq(self, v)
+ Ice.Util.callMethod(self, 'writeStringSeq', v);
+ end
+ function writeStringSeqOpt(self, tag, v)
+ Ice.Util.callMethod(self, 'writeStringSeqOpt', tag, v);
+ end
+ function writeSize(self, size)
+ Ice.Util.callMethod(self, 'writeSize', size);
+ end
+ function writeProxy(self, v)
+ if isempty(v)
+ impl = libpointer;
+ else
+ impl = v.impl;
+ end
+ Ice.Util.callMethod(self, 'writeProxy', impl);
+ end
+ function writeProxyOpt(self, tag, v)
+ if ~isempty(v)
+ Ice.Util.callMethod(self, 'writeProxyOpt', tag, v.impl);
+ end
+ end
+ function writeEnum(self, v, maxValue)
+ Ice.Util.callMethod(self, 'writeEnum', v, maxValue);
+ end
+ function startEncapsulation(self)
+ Ice.Util.callMethod(self, 'startEncapsulation');
+ end
+ function startEncapsulationWithFormat(self, fmt)
+ Ice.Util.callMethod(self, 'startEncapsulationWithFormat', fmt);
+ end
+ function endEncapsulation(self)
+ Ice.Util.callMethod(self, 'endEncapsulation');
+ end
+ function startSlice(self, typeId, compactId, last)
+ Ice.Util.callMethod(self, 'startSlice', typeId, compactId, last);
+ end
+ function endSlice(self)
+ Ice.Util.callMethod(self, 'endSlice');
+ end
+ function r = writeOptional(self, tag, f)
+ supportsOptionals = libpointer('uint8Ptr', 0);
+ Ice.Util.callMethod(self, 'writeOptional', tag, f, supportsOptionals);
+ r = supportsOptionals.Value;
+ end
+ function r = startSize(self)
+ pos = libpointer('uint32Ptr', 0);
+ Ice.Util.callMethod(self, 'startSize', pos);
+ r = pos.Value;
+ end
+ function endSize(self, pos)
+ Ice.Util.callMethod(self, 'endSize', pos);
+ end
+ end
+end
diff --git a/matlab/lib/+Ice/Properties.m b/matlab/lib/+Ice/Properties.m
new file mode 100644
index 00000000000..7a8ad2848d1
--- /dev/null
+++ b/matlab/lib/+Ice/Properties.m
@@ -0,0 +1,63 @@
+%{
+**********************************************************************
+
+Copyright (c) 2003-2017 ZeroC, Inc. All rights reserved.
+
+This copy of Ice is licensed to you under the terms described in the
+ICE_LICENSE file included in this distribution.
+
+**********************************************************************
+%}
+
+classdef Properties < Ice.WrapperObject
+ methods
+ function self = Properties(impl)
+ self = self@Ice.WrapperObject(impl);
+ end
+ function r = getProperty(self, key)
+ r = Ice.Util.callMethodWithResult(self, 'getProperty', key);
+ end
+ function r = getPropertyWithDefault(self, key, def)
+ r = Ice.Util.callMethodWithResult(self, 'getPropertyWithDefault', key, def);
+ end
+ function r = getPropertyAsInt(self, key)
+ v = libpointer('int32Ptr', 0);
+ Ice.Util.callMethod(self, 'getPropertyAsInt', key, v);
+ r = v.Value;
+ end
+ function r = getPropertyAsIntWithDefault(self, key, def)
+ v = libpointer('int32Ptr', 0);
+ Ice.Util.callMethod(self, 'getPropertyAsIntWithDefault', key, def, v);
+ r = v.Value;
+ end
+ function r = getPropertyAsList(self, key)
+ r = Ice.Util.callMethodWithResult(self, 'getPropertyAsList', key);
+ end
+ function r = getPropertyAsListWithDefault(self, key, def)
+ r = Ice.Util.callMethodWithResult(self, 'getPropertyAsListWithDefault', key, def);
+ end
+ function r = getPropertiesForPrefix(self, prefix)
+ r = Ice.Util.callMethodWithResult(self, 'getPropertiesForPrefix', prefix);
+ end
+ function setProperty(self, key, value)
+ Ice.Util.callMethod(self, 'setProperty', key, value);
+ end
+ function r = getCommandLineOptions(self)
+ r = Ice.Util.callMethodWithResult(self, 'getCommandLineOptions');
+ end
+ function r = parseCommandLineOptions(self, prefix, options)
+ r = Ice.Util.callMethodWithResult(self, 'parseCommandLineOptions', prefix, options);
+ end
+ function r = parseIceCommandLineOptions(self, options)
+ r = Ice.Util.callMethodWithResult(self, 'parseIceCommandLineOptions', options);
+ end
+ function load(self, file)
+ Ice.Util.callMethod(self, 'load', file);
+ end
+ function r = clone(self)
+ impl = libpointer('voidPtr');
+ Ice.Util.callMethod(self, 'clone', impl);
+ r = Ice.Properties(impl);
+ end
+ end
+end
diff --git a/matlab/lib/+Ice/UserException.m b/matlab/lib/+Ice/UserException.m
new file mode 100644
index 00000000000..8c74080ecbb
--- /dev/null
+++ b/matlab/lib/+Ice/UserException.m
@@ -0,0 +1,29 @@
+%{
+**********************************************************************
+
+Copyright (c) 2003-2017 ZeroC, Inc. All rights reserved.
+
+This copy of Ice is licensed to you under the terms described in the
+ICE_LICENSE file included in this distribution.
+
+**********************************************************************
+%}
+
+classdef (Abstract) UserException < Ice.Exception
+ methods
+ function obj = UserException(id, msg)
+ obj = obj@Ice.Exception(id, msg)
+ end
+ function self = read_(self, is)
+ is.startException();
+ self = self._readImpl(is);
+ is.endException();
+ end
+ function r = usesClasses_(self)
+ r = false
+ end
+ end
+ methods(Abstract)
+ self = readImpl_(self, is)
+ end
+end
diff --git a/matlab/lib/+Ice/Util.m b/matlab/lib/+Ice/Util.m
new file mode 100644
index 00000000000..297eaff7522
--- /dev/null
+++ b/matlab/lib/+Ice/Util.m
@@ -0,0 +1,116 @@
+%{
+**********************************************************************
+
+Copyright (c) 2003-2017 ZeroC, Inc. All rights reserved.
+
+This copy of Ice is licensed to you under the terms described in the
+ICE_LICENSE file included in this distribution.
+
+**********************************************************************
+%}
+
+classdef Util
+ methods(Static)
+ %
+ % Internal method - invoke a C function with the given name.
+ % The value for fn MUST be given in single quotes!
+ %
+ function call(fn, varargin)
+ ex = calllib('icematlab', fn, varargin{:});
+ if ~isempty(ex)
+ ex.throwAsCaller();
+ end
+ end
+
+ %
+ % Internal method - invoke a C function representing a global function.
+ % The value for fn MUST be given in single quotes!
+ %
+ function r = callWithResult(fn, varargin)
+ result = calllib('icematlab', fn, varargin{:});
+ if isempty(result)
+ r = result;
+ elseif ~isempty(result.exception)
+ result.exception.throwAsCaller();
+ else
+ r = result.result;
+ end
+ end
+
+ %
+ % Internal method - invoke a C function representing an object method.
+ % The value for fn MUST be given in single quotes!
+ %
+ function callMethod(self, fn, varargin)
+ name = replace(strcat(class(self), '.', fn), '.', '_');
+ ex = calllib('icematlab', name, self.impl, varargin{:});
+ if ~isempty(ex)
+ ex.throwAsCaller();
+ end
+ end
+
+ %
+ % Internal method - invoke a C function representing an object method.
+ % The value for fn MUST be given in single quotes!
+ %
+ function r = callMethodWithResult(self, fn, varargin)
+ name = replace(strcat(class(self), '.', fn), '.', '_');
+ result = calllib('icematlab', name, self.impl, varargin{:});
+ if isempty(result)
+ r = result;
+ elseif ~isempty(result.exception)
+ result.exception.throwAsCaller();
+ else
+ r = result.result;
+ end
+ end
+
+ %
+ % Internal method - invoke a C function representing an object method.
+ % The value for fn MUST be given in single quotes!
+ %
+ function callMethodOnType(self, type, fn, varargin)
+ name = strcat(type, '_', fn);
+ ex = calllib('icematlab', name, self.impl, varargin{:});
+ if ~isempty(ex)
+ ex.throwAsCaller();
+ end
+ end
+
+ %
+ % Internal method - invoke a C function representing an object method.
+ % The value for fn MUST be given in single quotes!
+ %
+ function r = callMethodOnTypeWithResult(self, type, fn, varargin)
+ name = strcat(type, '_', fn);
+ result = calllib('icematlab', name, self.impl, varargin{:});
+ if isempty(result)
+ r = result;
+ elseif ~isempty(result.exception)
+ result.exception.throwAsCaller();
+ else
+ r = result.result;
+ end
+ end
+
+ function r = strcmp(s1, s2)
+ n = min(length(s1), length(s2));
+ for i = 1:n
+ if s1(i) < s2(i)
+ r = -1;
+ return;
+ elseif s1(i) > s2(i)
+ r = 1;
+ return;
+ end
+ end
+ if length(s1) > n
+ r = 1;
+ elseif length(s2) > n
+ r = -1;
+ else
+ r = 0;
+ end
+ end
+ end
+end
diff --git a/matlab/lib/+Ice/Value.m b/matlab/lib/+Ice/Value.m
new file mode 100644
index 00000000000..0e24b1ee5e7
--- /dev/null
+++ b/matlab/lib/+Ice/Value.m
@@ -0,0 +1,41 @@
+%{
+**********************************************************************
+
+Copyright (c) 2003-2017 ZeroC, Inc. All rights reserved.
+
+This copy of Ice is licensed to you under the terms described in the
+ICE_LICENSE file included in this distribution.
+
+**********************************************************************
+%}
+
+classdef (Abstract) Value < matlab.mixin.Copyable
+ methods
+ function ice_preMarshal(obj)
+ end
+ function ice_postUnmarshal(obj)
+ end
+ function id = ice_id(obj)
+ id = ice_staticId()
+ end
+ function iceWrite_(self, os)
+ os.startValue([]);
+ self.iceWriteImpl_(os);
+ os.endValue();
+ end
+ function self = iceRead_(self, is)
+ is.startValue();
+ self = self.iceReadImpl_(is);
+ is.endValue(false);
+ end
+ end
+ methods(Abstract)
+ iceWriteImpl_(self, os)
+ self = iceReadImpl_(self, is)
+ end
+ methods(Static)
+ function id = ice_staticId()
+ id = '::Ice::Object'
+ end
+ end
+end
diff --git a/matlab/lib/+Ice/WrapperObject.m b/matlab/lib/+Ice/WrapperObject.m
new file mode 100644
index 00000000000..b5c1e019558
--- /dev/null
+++ b/matlab/lib/+Ice/WrapperObject.m
@@ -0,0 +1,26 @@
+%{
+**********************************************************************
+
+Copyright (c) 2003-2017 ZeroC, Inc. All rights reserved.
+
+This copy of Ice is licensed to you under the terms described in the
+ICE_LICENSE file included in this distribution.
+
+**********************************************************************
+%}
+
+classdef (Abstract) WrapperObject < handle
+ methods
+ function self = WrapperObject(impl)
+ self.impl = impl;
+ end
+ function delete(self)
+ if ~isempty(self.impl)
+ Ice.Util.callMethod(self, '_release');
+ end
+ end
+ end
+ properties(Hidden,SetAccess=protected)
+ impl
+ end
+end
diff --git a/matlab/lib/+Ice/createProperties.m b/matlab/lib/+Ice/createProperties.m
new file mode 100644
index 00000000000..d619a4de343
--- /dev/null
+++ b/matlab/lib/+Ice/createProperties.m
@@ -0,0 +1,29 @@
+%{
+**********************************************************************
+
+Copyright (c) 2003-2017 ZeroC, Inc. All rights reserved.
+
+This copy of Ice is licensed to you under the terms described in the
+ICE_LICENSE file included in this distribution.
+
+**********************************************************************
+%}
+
+function [properties, remArgs] = createProperties(varargin)
+ if length(varargin) >= 1 && ~isempty(varargin{1})
+ args = varargin{1};
+ else
+ args = {};
+ end
+ if length(varargin) >= 2 && ~isempty(varargin{2})
+ if ~isa(varargin{2}, 'Ice.Properties')
+ throw(MException('Ice:ArgumentException', 'expecting Ice.Properties object'));
+ end
+ defaults = varargin{2}.impl;
+ else
+ defaults = libpointer('voidPtr');
+ end
+ impl = libpointer('voidPtr');
+ remArgs = Ice.Util.callWithResult('Ice_createProperties', args, defaults, impl);
+ properties = Ice.Properties(impl);
+end
diff --git a/matlab/lib/+Ice/identityToString.m b/matlab/lib/+Ice/identityToString.m
new file mode 100644
index 00000000000..d3580ef1819
--- /dev/null
+++ b/matlab/lib/+Ice/identityToString.m
@@ -0,0 +1,14 @@
+%{
+**********************************************************************
+
+Copyright (c) 2003-2017 ZeroC, Inc. All rights reserved.
+
+This copy of Ice is licensed to you under the terms described in the
+ICE_LICENSE file included in this distribution.
+
+**********************************************************************
+%}
+
+function r = identityToString(id)
+ r = Ice.Util.callWithResult('Ice_identityToString', id);
+end
diff --git a/matlab/lib/+Ice/initialize.m b/matlab/lib/+Ice/initialize.m
new file mode 100644
index 00000000000..b164fe6c40a
--- /dev/null
+++ b/matlab/lib/+Ice/initialize.m
@@ -0,0 +1,47 @@
+%{
+**********************************************************************
+
+Copyright (c) 2003-2017 ZeroC, Inc. All rights reserved.
+
+This copy of Ice is licensed to you under the terms described in the
+ICE_LICENSE file included in this distribution.
+
+**********************************************************************
+%}
+
+function [communicator, args] = initialize(varargin)
+ if length(varargin) >= 1 && ~isempty(varargin{1})
+ args = varargin{1};
+ else
+ args = {};
+ end
+
+ if length(varargin) >= 2 && ~isempty(varargin{2})
+ if ~isa(varargin{2}, 'Ice.InitializationData')
+ throw(MException('Ice:ArgumentException', 'initData argument must be an Ice.InitializationData object'));
+ end
+ initData = varargin{2};
+ else
+ initData = [];
+ end
+
+ %
+ % Implementation note: We need to extract and pass the libpointer object for properties to the C function.
+ % Passing the wrapper (Ice.Properties) object won't work because the C code has no way to obtain the
+ % inner pointer.
+ %
+ props = libpointer('voidPtr');
+ if ~isempty(initData)
+ if ~isempty(initData.properties_)
+ if ~isa(initData.properties_, 'Ice.Properties')
+ throw(MException('Ice:ArgumentException', 'invalid value for properties_ member'));
+ else
+ props = initData.properties_.impl;
+ end
+ end
+ end
+
+ impl = libpointer('voidPtr');
+ args = Ice.Util.callWithResult('Ice_initialize', args, props, impl);
+ communicator = Ice.Communicator(impl);
+end
diff --git a/matlab/lib/+Ice/proxyIdentityAndFacetCompare.m b/matlab/lib/+Ice/proxyIdentityAndFacetCompare.m
new file mode 100644
index 00000000000..ff9549f0188
--- /dev/null
+++ b/matlab/lib/+Ice/proxyIdentityAndFacetCompare.m
@@ -0,0 +1,45 @@
+%{
+**********************************************************************
+
+Copyright (c) 2003-2017 ZeroC, Inc. All rights reserved.
+
+This copy of Ice is licensed to you under the terms described in the
+ICE_LICENSE file included in this distribution.
+
+**********************************************************************
+%}
+
+function r = proxyIdentityAndFacetCompare(lhs, rhs)
+ if isempty(lhs) && isempty(rhs)
+ r = 0;
+ elseif isempty(lhs) && ~isempty(rhs)
+ r = -1;
+ elseif ~isempty(lhs) && isempty(rhs)
+ r = 1;
+ else
+ lhsIdentity = lhs.ice_getIdentity();
+ rhsIdentity = rhs.ice_getIdentity();
+ n = Ice.Util.strcmp(lhsIdentity.name, rhsIdentity.name);
+ if n ~= 0
+ r = n;
+ return;
+ end
+ n = Ice.Util.strcmp(lhsIdentity.category, rhsIdentity.category);
+ if n ~= 0
+ r = n;
+ return;
+ end
+
+ lhsFacet = lhs.ice_getFacet();
+ rhsFacet = rhs.ice_getFacet();
+ if isempty(lhsFacet) && isempty(rhsFacet)
+ r = 0;
+ elseif isempty(lhsFacet)
+ r = -1;
+ elseif isempty(rhsFacet)
+ r = 1;
+ else
+ r = Ice.Util.strcmp(lhsFacet, rhsFacet);
+ end
+ end
+end
diff --git a/matlab/lib/+Ice/proxyIdentityCompare.m b/matlab/lib/+Ice/proxyIdentityCompare.m
new file mode 100644
index 00000000000..0b660c86346
--- /dev/null
+++ b/matlab/lib/+Ice/proxyIdentityCompare.m
@@ -0,0 +1,29 @@
+%{
+**********************************************************************
+
+Copyright (c) 2003-2017 ZeroC, Inc. All rights reserved.
+
+This copy of Ice is licensed to you under the terms described in the
+ICE_LICENSE file included in this distribution.
+
+**********************************************************************
+%}
+
+function r = proxyIdentityCompare(lhs, rhs)
+ if isempty(lhs) && isempty(rhs)
+ r = 0;
+ elseif isempty(lhs) && ~isempty(rhs)
+ r = -1;
+ elseif ~isempty(lhs) && isempty(rhs)
+ r = 1;
+ else
+ lhsIdentity = lhs.ice_getIdentity();
+ rhsIdentity = rhs.ice_getIdentity();
+ n = Ice.Util.strcmp(lhsIdentity.name, rhsIdentity.name);
+ if n ~= 0
+ r = n;
+ return;
+ end
+ r = Ice.Util.strcmp(lhsIdentity.category, rhsIdentity.category);
+ end
+end
diff --git a/matlab/lib/+Ice/stringToIdentity.m b/matlab/lib/+Ice/stringToIdentity.m
new file mode 100644
index 00000000000..e846ad1a61e
--- /dev/null
+++ b/matlab/lib/+Ice/stringToIdentity.m
@@ -0,0 +1,14 @@
+%{
+**********************************************************************
+
+Copyright (c) 2003-2017 ZeroC, Inc. All rights reserved.
+
+This copy of Ice is licensed to you under the terms described in the
+ICE_LICENSE file included in this distribution.
+
+**********************************************************************
+%}
+
+function r = stringToIdentity(s)
+ r = Ice.Util.callWithResult('Ice_stringToIdentity', s);
+end
diff --git a/matlab/lib/generated/.gitignore b/matlab/lib/generated/.gitignore
new file mode 100644
index 00000000000..39af5887579
--- /dev/null
+++ b/matlab/lib/generated/.gitignore
@@ -0,0 +1 @@
+# Dummy file, so that git retains this otherwise empty directory.
diff --git a/matlab/msbuild/ice.proj b/matlab/msbuild/ice.proj
new file mode 100644
index 00000000000..0b777a901b9
--- /dev/null
+++ b/matlab/msbuild/ice.proj
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+
+ <PropertyGroup>
+ <Platform Condition="'$(Platform)' == ''">Win32</Platform>
+ <Configuration Condition="'$(Configuration)' == ''">Release</Configuration>
+ </PropertyGroup>
+
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <Import Project="$(MSBuildThisFileDirectory)\..\..\config\ice.common.targets"/>
+
+ <PropertyGroup>
+ <topSrcDir>$(MSBuildThisFileDirectory)..\..</topSrcDir>
+ <sliceDir>$(topSrcDir)\slice</sliceDir>
+ <srcDir>$(MSBuildThisFileDirectory)..\src\IceMatlab</srcDir>
+ <testDir>$(MSBuildThisFileDirectory)..\test</testDir>
+ <slice2matlabexe>$(topSrcDir)\cpp\bin\$(Platform)\$(Configuration)\slice2matlab</slice2matlabexe>
+ <slice2matlab Condition="'$(DefaultPlatformToolset)' == 'v140'">c++98\slice2matlab</slice2matlab>
+ <cpp11core Condition="'$(DefaultPlatformToolset)' == 'v140'">c++11\ice++11</cpp11core>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <Slice Include="$(sliceDir)\Ice\Connection.ice" />
+ <Slice Include="$(sliceDir)\Ice\Current.ice" />
+ <Slice Include="$(sliceDir)\Ice\Identity.ice" />
+ <Slice Include="$(sliceDir)\Ice\LocalException.ice" />
+ <Slice Include="$(sliceDir)\Ice\Version.ice" />
+ </ItemGroup>
+
+ <Target Name="CppPrereqs">
+ <MSBuild Projects="$(topSrcDir)\cpp\msbuild\ice.proj"
+ Targets="NuGetRestore"
+ BuildInParallel="false"/>
+
+ <MSBuild Projects="$(topSrcDir)\cpp\msbuild\ice.$(DefaultPlatformToolset).sln"
+ Targets="$(slice2matlab);$(cpp11core)"
+ BuildInParallel="false"
+ Properties="Platform=$(Platform);Configuration=$(Configuration)"/>
+ </Target>
+
+ <Target Name="Build" DependsOnTargets="CppPrereqs">
+ <Exec Command="$(slice2matlabexe) -I$(sliceDir) --output-dir $(MSBuildThisFileDirectory)..\lib\generated %(Slice.FullPath)"/>
+ <Exec Command="$(slice2matlabexe) -I$(sliceDir) --output-dir $(testDir)\Ice\operations\generated $(testDir)\Ice\operations\Test.ice"/>
+ <Exec Command="mex -outdir $(srcDir) -output icematlab -I$(topSrcDir)\cpp\include -I$(topSrcDir)\cpp\include\generated\cpp11\$(Platform)\$(Configuration) -DICE_CPP11_MAPPING -DICE_BUILDING_SRC -L$(topSrcDir)\cpp\lib\$(Platform)\$(Configuration) -lmex -lmx $(srcDir)\*.cpp"/>
+ <Exec Command="copy /Y $(topSrcDir)\cpp\bin\$(Platform)\$(Configuration)\bzip2.dll $(srcDir)"/>
+ <Exec Command="copy /Y &quot;$(topSrcDir)\cpp\bin\$(Platform)\$(Configuration)\ice37++11.dll&quot; $(srcDir)"/>
+ </Target>
+
+</Project>
diff --git a/matlab/src/IceMatlab/Communicator.cpp b/matlab/src/IceMatlab/Communicator.cpp
new file mode 100644
index 00000000000..0d4208bf9f9
--- /dev/null
+++ b/matlab/src/IceMatlab/Communicator.cpp
@@ -0,0 +1,86 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2017 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#define EXPORT_FCNS
+
+#include <Ice/Communicator.h>
+#include <Ice/Proxy.h>
+#include <Ice/OutputStream.h>
+#include "icematlab.h"
+#include "Util.h"
+
+#define SELF (*(reinterpret_cast<shared_ptr<Ice::Communicator>*>(self)))
+
+using namespace std;
+using namespace IceMatlab;
+
+extern "C"
+{
+
+EXPORTED_FUNCTION mxArray*
+Ice_Communicator__release(void* self)
+{
+ delete &SELF;
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_Communicator_stringToProxy(void* self, const char* s, void** proxy)
+{
+ try
+ {
+ shared_ptr<Ice::ObjectPrx> p = SELF->stringToProxy(s);
+ *proxy = new shared_ptr<Ice::ObjectPrx>(p);
+ }
+ catch(const std::exception& ex)
+ {
+ return convertException(ex);
+ }
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_Communicator_getProperties(void* self, void** props)
+{
+ try
+ {
+ shared_ptr<Ice::Properties> p = SELF->getProperties();
+ *props = new shared_ptr<Ice::Properties>(p);
+ }
+ catch(const std::exception& ex)
+ {
+ return convertException(ex);
+ }
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_Communicator_createOutputStream(void* self, mxArray* encoding, void** stream)
+{
+ Ice::EncodingVersion v;
+ getEncodingVersion(encoding, v);
+ *stream = new Ice::OutputStream(SELF, v);
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_Communicator_destroy(void* self)
+{
+ try
+ {
+ SELF->destroy();
+ }
+ catch(const std::exception& ex)
+ {
+ return convertException(ex);
+ }
+ return 0;
+}
+
+}
diff --git a/matlab/src/IceMatlab/Connection.cpp b/matlab/src/IceMatlab/Connection.cpp
new file mode 100644
index 00000000000..fd965e75d13
--- /dev/null
+++ b/matlab/src/IceMatlab/Connection.cpp
@@ -0,0 +1,286 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2017 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#define EXPORT_FCNS
+
+#include <Ice/Ice.h>
+#include "icematlab.h"
+#include "Future.h"
+#include "Util.h"
+
+#define SELF (*(reinterpret_cast<shared_ptr<Ice::Connection>*>(self)))
+
+using namespace std;
+using namespace IceMatlab;
+
+extern "C"
+{
+
+EXPORTED_FUNCTION mxArray*
+Ice_Connection__release(void* self)
+{
+ delete &SELF;
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_Connection_close(void* self, mxArray* m)
+{
+ try
+ {
+ Ice::ConnectionClose mode = static_cast<Ice::ConnectionClose>(getEnumerator(m, "Ice.ConnectionClose"));
+ SELF->close(mode);
+ }
+ catch(const std::exception& ex)
+ {
+ return convertException(ex);
+ }
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_Connection_createProxy(void* self, mxArray* id, void** r)
+{
+ try
+ {
+ Ice::Identity ident;
+ getIdentity(id, ident);
+ shared_ptr<Ice::ObjectPrx> proxy = SELF->createProxy(ident);
+ *r = new shared_ptr<Ice::ObjectPrx>(proxy);
+ }
+ catch(const std::exception& ex)
+ {
+ return convertException(ex);
+ }
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_Connection_flushBatchRequests(void* self, mxArray* c)
+{
+ try
+ {
+ Ice::CompressBatch mode = static_cast<Ice::CompressBatch>(getEnumerator(c, "Ice.CompressBatch"));
+ SELF->flushBatchRequests(mode);
+ }
+ catch(const std::exception& ex)
+ {
+ return convertException(ex);
+ }
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_Connection_flushBatchRequestsAsync(void* self, mxArray* c, void** future)
+{
+ *future = 0;
+ auto f = make_shared<SentFuture>();
+
+ try
+ {
+ Ice::CompressBatch mode = static_cast<Ice::CompressBatch>(getEnumerator(c, "Ice.CompressBatch"));
+ function<void()> token = SELF->flushBatchRequestsAsync(
+ mode,
+ [f](exception_ptr e)
+ {
+ f->exception(e);
+ },
+ [f](bool /*sentSynchronously*/)
+ {
+ f->sent();
+ });
+ f->token(token);
+ *future = new shared_ptr<SentFuture>(f);
+ }
+ catch(const std::exception& ex)
+ {
+ return convertException(ex);
+ }
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_Connection_heartbeat(void* self)
+{
+ try
+ {
+ SELF->heartbeat();
+ }
+ catch(const std::exception& ex)
+ {
+ return convertException(ex);
+ }
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_Connection_heartbeatAsync(void* self, void** future)
+{
+ *future = 0;
+ auto f = make_shared<SentFuture>();
+
+ try
+ {
+ function<void()> token = SELF->heartbeatAsync(
+ [f](exception_ptr e)
+ {
+ f->exception(e);
+ },
+ [f](bool /*sentSynchronously*/)
+ {
+ f->sent();
+ });
+ f->token(token);
+ *future = new shared_ptr<SentFuture>(f);
+ }
+ catch(const std::exception& ex)
+ {
+ return convertException(ex);
+ }
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_Connection_setACM(void* self, mxArray* t, mxArray* c, mxArray* h)
+{
+ Ice::optional<int> timeout;
+ Ice::optional<Ice::ACMClose> close;
+ Ice::optional<Ice::ACMHeartbeat> heartbeat;
+
+ try
+ {
+ if(!mxIsEmpty(t))
+ {
+ if(!mxIsScalar(t))
+ {
+ throw invalid_argument("scalar value required for timeout");
+ }
+ if(!mxIsNumeric(t))
+ {
+ throw invalid_argument("numeric value required for timeout");
+ }
+ timeout = static_cast<int>(mxGetScalar(t));
+ }
+ if(!mxIsEmpty(c))
+ {
+ if(!mxIsClass(c, "Ice.ACMClose"))
+ {
+ throw invalid_argument("ACMClose enumerator required for close");
+ }
+ close = static_cast<Ice::ACMClose>(static_cast<int>(mxGetScalar(c)));
+ }
+ if(!mxIsEmpty(h))
+ {
+ if(!mxIsClass(c, "Ice.ACMHeartbeat"))
+ {
+ throw invalid_argument("ACMHeartbeat enumerator required for heartbeat");
+ }
+ heartbeat = static_cast<Ice::ACMHeartbeat>(static_cast<int>(mxGetScalar(h)));
+ }
+ SELF->setACM(timeout, close, heartbeat);
+ }
+ catch(const std::exception& ex)
+ {
+ return convertException(ex);
+ }
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_Connection_getACM(void* self)
+{
+ try
+ {
+ Ice::ACM acm = SELF->getACM();
+ mxArray* params[3];
+ params[0] = createInt(acm.timeout);
+ params[1] = createEnumerator("Ice.ACMClose", static_cast<int>(acm.close));
+ params[2] = createEnumerator("Ice.ACMHeartbeat", static_cast<int>(acm.heartbeat));
+ mxArray* r;
+ mexCallMATLAB(1, &r, 3, params, "Ice.ACM");
+ return createResultValue(r);
+ }
+ catch(const std::exception& ex)
+ {
+ return createResultException(convertException(ex));
+ }
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_Connection_type(void* self)
+{
+ try
+ {
+ return createResultValue(createStringFromUTF8(SELF->type()));
+ }
+ catch(const std::exception& ex)
+ {
+ return createResultException(convertException(ex));
+ }
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_Connection_timeout(void* self, int* timeout)
+{
+ try
+ {
+ *timeout = SELF->timeout();
+ }
+ catch(const std::exception& ex)
+ {
+ return convertException(ex);
+ }
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_Connection_toString(void* self)
+{
+ try
+ {
+ return createResultValue(createStringFromUTF8(SELF->toString()));
+ }
+ catch(const std::exception& ex)
+ {
+ return createResultException(convertException(ex));
+ }
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_Connection_setBufferSize(void* self, int rcvSize, int sndSize)
+{
+ try
+ {
+ SELF->setBufferSize(rcvSize, sndSize);
+ }
+ catch(const std::exception& ex)
+ {
+ return convertException(ex);
+ }
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_Connection_throwException(void* self)
+{
+ try
+ {
+ SELF->throwException();
+ }
+ catch(const std::exception& ex)
+ {
+ return convertException(ex);
+ }
+ return 0;
+}
+
+}
diff --git a/matlab/src/IceMatlab/Future.cpp b/matlab/src/IceMatlab/Future.cpp
new file mode 100644
index 00000000000..f3d326c2135
--- /dev/null
+++ b/matlab/src/IceMatlab/Future.cpp
@@ -0,0 +1,166 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2017 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#define EXPORT_FCNS
+
+#include "icematlab.h"
+#include "Future.h"
+#include "Util.h"
+
+using namespace std;
+using namespace IceMatlab;
+
+void
+IceMatlab::Future::token(function<void()> t)
+{
+ IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this);
+ if(!isFinished())
+ {
+ _token = std::move(t);
+ }
+}
+
+bool
+IceMatlab::Future::waitUntilFinished()
+{
+ IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this);
+ while(!isFinished())
+ {
+ wait();
+ }
+ return !_exception;
+}
+
+void
+IceMatlab::Future::exception(exception_ptr e)
+{
+ IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this);
+ _token = nullptr;
+ _exception = e;
+ notifyAll();
+}
+
+exception_ptr
+IceMatlab::Future::getException() const
+{
+ IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this);
+ return _exception;
+}
+
+void
+IceMatlab::Future::sent()
+{
+}
+
+void
+IceMatlab::Future::cancel()
+{
+ IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this);
+ if(_token)
+ {
+ _token();
+ _token = nullptr;
+ }
+}
+
+IceMatlab::SentFuture::SentFuture() :
+ _sent(false)
+{
+}
+
+void
+IceMatlab::SentFuture::sent()
+{
+ IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this);
+ _sent = true;
+ notifyAll();
+}
+
+string
+IceMatlab::SentFuture::state() const
+{
+ IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this);
+ if(_exception || _sent)
+ {
+ return "finished";
+ }
+ else
+ {
+ return "running";
+ }
+}
+
+bool
+IceMatlab::SentFuture::isFinished() const
+{
+ return _sent || _exception;
+}
+
+#define SFSELF (*(reinterpret_cast<shared_ptr<SentFuture>*>(self)))
+
+extern "C"
+{
+
+EXPORTED_FUNCTION mxArray*
+Ice_SentFuture__release(void* self)
+{
+ delete &SFSELF;
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_SentFuture_id(void* self, unsigned long long* id)
+{
+ *id = reinterpret_cast<unsigned long long>(self);
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_SentFuture_wait(void* self, unsigned char* ok)
+{
+ // TBD: Timeout?
+
+ bool b = SFSELF->waitUntilFinished();
+ *ok = b ? 1 : 0;
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_SentFuture_state(void* self)
+{
+ return createResultValue(createStringFromUTF8(SFSELF->state()));
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_SentFuture_cancel(void* self)
+{
+ SFSELF->cancel();
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_SentFuture_check(void* self)
+{
+ if(!SFSELF->waitUntilFinished())
+ {
+ assert(SFSELF->getException());
+ try
+ {
+ rethrow_exception(SFSELF->getException());
+ }
+ catch(const std::exception& ex)
+ {
+ return convertException(ex);
+ }
+ }
+
+ return 0;
+}
+
+}
diff --git a/matlab/src/IceMatlab/Future.h b/matlab/src/IceMatlab/Future.h
new file mode 100644
index 00000000000..28a5b112cc4
--- /dev/null
+++ b/matlab/src/IceMatlab/Future.h
@@ -0,0 +1,58 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2017 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#include <Ice/Ice.h>
+
+namespace IceMatlab
+{
+
+class Future : public IceUtil::Monitor<IceUtil::Mutex>
+{
+public:
+
+ void token(std::function<void()>);
+ bool waitUntilFinished();
+
+ virtual void exception(std::exception_ptr);
+ std::exception_ptr getException() const;
+
+ virtual void sent();
+ virtual std::string state() const = 0;
+ void cancel();
+
+protected:
+
+ virtual bool isFinished() const = 0;
+
+ std::function<void()> _token;
+ std::exception_ptr _exception; // If a local exception occurs.
+};
+
+//
+// For invocations that are considered completed when sent.
+//
+class SentFuture : public Future
+{
+public:
+
+ SentFuture();
+
+ virtual void sent();
+ virtual std::string state() const;
+
+protected:
+
+ virtual bool isFinished() const;
+
+private:
+
+ bool _sent;
+};
+
+}
diff --git a/matlab/src/IceMatlab/IceMatlab.rc b/matlab/src/IceMatlab/IceMatlab.rc
new file mode 100644
index 00000000000..10fa5af893a
--- /dev/null
+++ b/matlab/src/IceMatlab/IceMatlab.rc
@@ -0,0 +1,38 @@
+#include <IceUtil/ResourceConfig.h>
+
+#ifdef _DEBUG
+# define ICE_INTERNALNAME "icematlab_d\0"
+# define ICE_ORIGINALFILENAME "icematlab_d.dll\0"
+#else
+# define ICE_INTERNALNAME "icematlab\0"
+# define ICE_ORIGINALFILENAME "icematlab.dll\0"
+#endif
+
+VS_VERSION_INFO VERSIONINFO
+FILEVERSION ICE_VERSION
+PRODUCTVERSION ICE_VERSION
+FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
+FILEOS VOS_NT_WINDOWS32
+FILETYPE VFT_DLL
+FILESUBTYPE VFT2_UNKNOWN
+FILEFLAGS VER_DEBUG
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904e4"
+ BEGIN
+ VALUE "CompanyName", ICE_COMPANY_NAME
+ VALUE "FileDescription", "Ice for Matlab Extension\0"
+ VALUE "FileVersion", ICE_STRING_VERSION
+ VALUE "InternalName", ICE_INTERNALNAME
+ VALUE "LegalCopyright", ICE_COPYRIGHT
+ VALUE "OriginalFilename", ICE_ORIGINALFILENAME
+ VALUE "ProductName", ICE_PRODUCT_NAME
+ VALUE "ProductVersion", ICE_STRING_VERSION
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1252
+ END
+END
diff --git a/matlab/src/IceMatlab/Init.cpp b/matlab/src/IceMatlab/Init.cpp
new file mode 100644
index 00000000000..e9fe0b57256
--- /dev/null
+++ b/matlab/src/IceMatlab/Init.cpp
@@ -0,0 +1,94 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2017 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#define EXPORT_FCNS
+
+#include <Ice/Ice.h>
+#include <Ice/RegisterPlugins.h>
+#include "icematlab.h"
+#include "Util.h"
+
+using namespace std;
+using namespace IceMatlab;
+
+extern "C"
+{
+
+EXPORTED_FUNCTION mxArray*
+Ice_initialize(mxArray* args, void* propsImpl, void** r)
+{
+ try
+ {
+ Ice::StringSeq a;
+ getStringList(args, a);
+
+ //
+ // Collect InitializationData members.
+ //
+ Ice::InitializationData id;
+
+ //
+ // Properties
+ //
+ if(propsImpl)
+ {
+ id.properties = *(reinterpret_cast<shared_ptr<Ice::Properties>*>(propsImpl));
+ }
+
+ shared_ptr<Ice::Communicator> c = Ice::initialize(a, id);
+ *r = new shared_ptr<Ice::Communicator>(c);
+ return createResultValue(createStringList(a));
+ }
+ catch(const std::exception& ex)
+ {
+ return createResultException(convertException(ex));
+ }
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_stringToIdentity(mxArray* s)
+{
+ try
+ {
+ Ice::Identity id = Ice::stringToIdentity(getStringFromUTF16(s));
+ return createResultValue(createIdentity(id));
+ }
+ catch(const std::exception& ex)
+ {
+ return createResultException(convertException(ex));
+ }
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_identityToString(mxArray* id)
+{
+ try
+ {
+ Ice::Identity ident;
+ getIdentity(id, ident);
+ return createResultValue(createStringFromUTF8(Ice::identityToString(ident)));
+ }
+ catch(const std::exception& ex)
+ {
+ return createResultException(convertException(ex));
+ }
+ return 0;
+}
+
+//
+// This function exists so that mex may be used to compile the library. It is not otherwise needed.
+//
+void
+mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
+{
+}
+
+}
diff --git a/matlab/src/IceMatlab/InputStream.cpp b/matlab/src/IceMatlab/InputStream.cpp
new file mode 100644
index 00000000000..33633f0d3f9
--- /dev/null
+++ b/matlab/src/IceMatlab/InputStream.cpp
@@ -0,0 +1,830 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2017 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#define EXPORT_FCNS
+
+#include <Ice/Ice.h>
+#include <Ice/Optional.h>
+#include "icematlab.h"
+#include "InputStream.h"
+#include "Util.h"
+
+#define SELF (reinterpret_cast<IceMatlab::InputStreamData*>(self))
+
+using namespace std;
+using namespace IceMatlab;
+
+void*
+IceMatlab::createInputStream(const shared_ptr<Ice::Communicator>& communicator, const Ice::EncodingVersion& encoding,
+ vector<Ice::Byte>& data)
+{
+ InputStreamData* p = new InputStreamData;
+ p->data.swap(data);
+ p->in = new Ice::InputStream(communicator, encoding, p->data);
+ return p;
+}
+
+namespace
+{
+
+template<typename T>
+mxArray*
+readSeq(Ice::InputStream* in, mxClassID cls)
+{
+ try
+ {
+ pair<const T*, const T*> p;
+ in->read(p);
+ const size_t nelem = p.second - p.first;
+ if(nelem > 0)
+ {
+ mxArray* r = mxCreateUninitNumericMatrix(1, nelem, cls, mxREAL);
+ memcpy(reinterpret_cast<T*>(mxGetData(r)), p.first, nelem * sizeof(T));
+ return createResultValue(r);
+ }
+ }
+ catch(const std::exception& ex)
+ {
+ return createResultException(convertException(ex));
+ }
+ return 0;
+}
+
+template<typename T>
+mxArray*
+readOpt(Ice::InputStream* in, int tag, mxClassID cls)
+{
+ try
+ {
+ Ice::optional<T> opt;
+ in->read(tag, opt);
+ if(opt.has_value())
+ {
+ mxArray* r = mxCreateUninitNumericMatrix(1, 1, cls, mxREAL);
+ *(reinterpret_cast<T*>(mxGetData(r))) = opt.value();
+ return createResultValue(r);
+ }
+ }
+ catch(const std::exception& ex)
+ {
+ return createResultException(convertException(ex));
+ }
+ return 0;
+}
+
+template<typename T>
+mxArray*
+readSeqOpt(Ice::InputStream* in, int tag, mxClassID cls)
+{
+ try
+ {
+ Ice::optional<pair<const T*, const T*>> opt;
+ in->read(tag, opt);
+ const size_t sz = opt.value().second - opt.value().first;
+ if(opt.has_value() && sz > 0)
+ {
+ mxArray* r = mxCreateUninitNumericMatrix(1, sz / sizeof(T), cls, mxREAL);
+ memcpy(reinterpret_cast<T*>(mxGetData(r)), opt.value().first, sz);
+ return createResultValue(r);
+ }
+ }
+ catch(const std::exception& ex)
+ {
+ return createResultException(convertException(ex));
+ }
+ return 0;
+}
+
+}
+
+extern "C"
+{
+
+EXPORTED_FUNCTION mxArray*
+Ice_InputStream__release(void* self)
+{
+ delete SELF->in;
+ delete SELF;
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_InputStream_readBool(void* self, unsigned char* v)
+{
+ try
+ {
+ bool b;
+ SELF->in->read(b);
+ *v = b ? 1 : 0;
+ }
+ catch(const std::exception& ex)
+ {
+ return convertException(ex);
+ }
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_InputStream_readBoolSeq(void* self)
+{
+ try
+ {
+ pair<const bool*, const bool*> p;
+ SELF->in->read(p);
+ const size_t sz = p.second - p.first;
+ if(sz > 0)
+ {
+ mxArray* r = mxCreateLogicalMatrix(1, sz);
+ memcpy(mxGetLogicals(r), p.first, sz);
+ return createResultValue(r);
+ }
+ }
+ catch(const std::exception& ex)
+ {
+ return createResultException(convertException(ex));
+ }
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_InputStream_readBoolOpt(void* self, int tag)
+{
+ try
+ {
+ Ice::optional<bool> opt;
+ SELF->in->read(tag, opt);
+ if(opt.has_value())
+ {
+ return createResultValue(mxCreateLogicalScalar(opt.value()));
+ }
+ }
+ catch(const std::exception& ex)
+ {
+ return createResultException(convertException(ex));
+ }
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_InputStream_readBoolSeqOpt(void* self, int tag)
+{
+ try
+ {
+ Ice::optional<pair<const bool*, const bool*>> opt;
+ SELF->in->read(tag, opt);
+ const size_t sz = opt.value().second - opt.value().first;
+ if(opt.has_value() && sz > 0)
+ {
+ mxArray* r = mxCreateLogicalMatrix(1, sz);
+ memcpy(mxGetLogicals(r), opt.value().first, sz);
+ return createResultValue(r);
+ }
+ }
+ catch(const std::exception& ex)
+ {
+ return createResultException(convertException(ex));
+ }
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_InputStream_readByte(void* self, unsigned char* v)
+{
+ try
+ {
+ Ice::Byte b;
+ SELF->in->read(b);
+ *v = b;
+ }
+ catch(const std::exception& ex)
+ {
+ return convertException(ex);
+ }
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_InputStream_readByteSeq(void* self)
+{
+ return readSeq<Ice::Byte>(SELF->in, mxUINT8_CLASS);
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_InputStream_readByteOpt(void* self, int tag)
+{
+ return readOpt<Ice::Byte>(SELF->in, tag, mxUINT8_CLASS);
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_InputStream_readByteSeqOpt(void* self, int tag)
+{
+ return readSeqOpt<Ice::Byte>(SELF->in, tag, mxUINT8_CLASS);
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_InputStream_readShort(void* self, short* v)
+{
+ try
+ {
+ SELF->in->read(*v);
+ }
+ catch(const std::exception& ex)
+ {
+ return convertException(ex);
+ }
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_InputStream_readShortSeq(void* self)
+{
+ return readSeq<short>(SELF->in, mxINT16_CLASS);
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_InputStream_readShortOpt(void* self, int tag)
+{
+ return readOpt<short>(SELF->in, tag, mxINT16_CLASS);
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_InputStream_readShortSeqOpt(void* self, int tag)
+{
+ return readSeqOpt<short>(SELF->in, tag, mxINT16_CLASS);
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_InputStream_readInt(void* self, int* v)
+{
+ try
+ {
+ SELF->in->read(*v);
+ }
+ catch(const std::exception& ex)
+ {
+ return convertException(ex);
+ }
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_InputStream_readIntSeq(void* self)
+{
+ return readSeq<int>(SELF->in, mxINT32_CLASS);
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_InputStream_readIntOpt(void* self, int tag)
+{
+ return readOpt<int>(SELF->in, tag, mxINT32_CLASS);
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_InputStream_readIntSeqOpt(void* self, int tag)
+{
+ return readSeqOpt<int>(SELF->in, tag, mxINT32_CLASS);
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_InputStream_readLong(void* self, long long* v)
+{
+ try
+ {
+ SELF->in->read(*v);
+ }
+ catch(const std::exception& ex)
+ {
+ return convertException(ex);
+ }
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_InputStream_readLongSeq(void* self)
+{
+ return readSeq<long long>(SELF->in, mxINT64_CLASS);
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_InputStream_readLongOpt(void* self, int tag)
+{
+ return readOpt<long long>(SELF->in, tag, mxINT64_CLASS);
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_InputStream_readLongSeqOpt(void* self, int tag)
+{
+ return readSeqOpt<long long>(SELF->in, tag, mxINT64_CLASS);
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_InputStream_readFloat(void* self, float* v)
+{
+ try
+ {
+ SELF->in->read(*v);
+ }
+ catch(const std::exception& ex)
+ {
+ return convertException(ex);
+ }
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_InputStream_readFloatSeq(void* self)
+{
+ return readSeq<float>(SELF->in, mxSINGLE_CLASS);
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_InputStream_readFloatOpt(void* self, int tag)
+{
+ return readOpt<float>(SELF->in, tag, mxSINGLE_CLASS);
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_InputStream_readFloatSeqOpt(void* self, int tag)
+{
+ return readSeqOpt<float>(SELF->in, tag, mxSINGLE_CLASS);
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_InputStream_readDouble(void* self, double* v)
+{
+ try
+ {
+ SELF->in->read(*v);
+ }
+ catch(const std::exception& ex)
+ {
+ return convertException(ex);
+ }
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_InputStream_readDoubleSeq(void* self)
+{
+ return readSeq<double>(SELF->in, mxDOUBLE_CLASS);
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_InputStream_readDoubleOpt(void* self, int tag)
+{
+ return readOpt<double>(SELF->in, tag, mxDOUBLE_CLASS);
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_InputStream_readDoubleSeqOpt(void* self, int tag)
+{
+ return readSeqOpt<double>(SELF->in, tag, mxDOUBLE_CLASS);
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_InputStream_readString(void* self)
+{
+ string s;
+ try
+ {
+ SELF->in->read(s, false);
+ return createResultValue(createStringFromUTF8(s));
+ }
+ catch(const std::exception& ex)
+ {
+ return createResultException(convertException(ex));
+ }
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_InputStream_readStringSeq(void* self)
+{
+ try
+ {
+ vector<string> v;
+ SELF->in->read(v, false);
+ return createResultValue(createStringList(v));
+ }
+ catch(const std::exception& ex)
+ {
+ return createResultException(convertException(ex));
+ }
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_InputStream_readStringOpt(void* self, int tag)
+{
+ try
+ {
+ Ice::optional<string> opt;
+ SELF->in->read(tag, opt);
+ if(opt.has_value())
+ {
+ return createResultValue(createStringFromUTF8(opt.value()));
+ }
+ }
+ catch(const std::exception& ex)
+ {
+ return createResultException(convertException(ex));
+ }
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_InputStream_readStringSeqOpt(void* self, int tag)
+{
+ try
+ {
+ if(SELF->in->readOptional(tag, Ice::OptionalFormat::FSize))
+ {
+ SELF->in->skip(4);
+ return Ice_InputStream_readStringSeq(self);
+ }
+ }
+ catch(const std::exception& ex)
+ {
+ return createResultException(convertException(ex));
+ }
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_InputStream_skip(void* self, int n)
+{
+ try
+ {
+ SELF->in->skip(n);
+ }
+ catch(const std::exception& ex)
+ {
+ return convertException(ex);
+ }
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_InputStream_startException(void* self)
+{
+ try
+ {
+ SELF->in->startException();
+ }
+ catch(const std::exception& ex)
+ {
+ return convertException(ex);
+ }
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_InputStream_endException(void* self)
+{
+ try
+ {
+ SELF->in->endException(false);
+ }
+ catch(const std::exception& ex)
+ {
+ return convertException(ex);
+ }
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_InputStream_startEncapsulation(void* self)
+{
+ try
+ {
+ SELF->in->startEncapsulation();
+ }
+ catch(const std::exception& ex)
+ {
+ return convertException(ex);
+ }
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_InputStream_endEncapsulation(void* self)
+{
+ try
+ {
+ SELF->in->endEncapsulation();
+ }
+ catch(const std::exception& ex)
+ {
+ return convertException(ex);
+ }
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_InputStream_skipEmptyEncapsulation(void* self)
+{
+ try
+ {
+ SELF->in->skipEmptyEncapsulation();
+ }
+ catch(const std::exception& ex)
+ {
+ return convertException(ex);
+ }
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_InputStream_skipEncapsulation(void* self)
+{
+ try
+ {
+ return createResultValue(createEncodingVersion(SELF->in->skipEncapsulation()));
+ }
+ catch(const std::exception& ex)
+ {
+ return createResultException(convertException(ex));
+ }
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_InputStream_getEncoding(void* self)
+{
+ try
+ {
+ return createResultValue(createEncodingVersion(SELF->in->getEncoding()));
+ }
+ catch(const std::exception& ex)
+ {
+ return createResultException(convertException(ex));
+ }
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_InputStream_startSlice(void* self)
+{
+ try
+ {
+ SELF->in->startSlice();
+ }
+ catch(const std::exception& ex)
+ {
+ return convertException(ex);
+ }
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_InputStream_endSlice(void* self)
+{
+ try
+ {
+ SELF->in->endSlice();
+ }
+ catch(const std::exception& ex)
+ {
+ return convertException(ex);
+ }
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_InputStream_skipSlice(void* self)
+{
+ try
+ {
+ SELF->in->skipSlice();
+ }
+ catch(const std::exception& ex)
+ {
+ return createResultException(convertException(ex));
+ }
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_InputStream_readSize(void* self, int* size)
+{
+ try
+ {
+ *size = SELF->in->readSize();
+ }
+ catch(const std::exception& ex)
+ {
+ return convertException(ex);
+ }
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_InputStream_readOptional(void* self, int tag, Ice_OptionalFormat f, unsigned char* r)
+{
+ try
+ {
+ bool b = SELF->in->readOptional(tag, static_cast<Ice::OptionalFormat>(f));
+ *r = b ? 1 : 0;
+ }
+ catch(const std::exception& ex)
+ {
+ return convertException(ex);
+ }
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_InputStream_readProxy(void* self, void** r)
+{
+ try
+ {
+ shared_ptr<Ice::ObjectPrx> proxy;
+ SELF->in->read(proxy);
+ if(proxy)
+ {
+ *r = new shared_ptr<Ice::ObjectPrx>(proxy);
+ }
+ else
+ {
+ *r = 0;
+ }
+ }
+ catch(const std::exception& ex)
+ {
+ return convertException(ex);
+ }
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_InputStream_readProxyOpt(void* self, int tag, void** r)
+{
+ try
+ {
+ Ice::optional<shared_ptr<Ice::ObjectPrx>> opt;
+ SELF->in->readAll({tag}, opt);
+ if(opt.has_value())
+ {
+ *r = new shared_ptr<Ice::ObjectPrx>(opt.value());
+ }
+ else
+ {
+ *r = 0;
+ }
+ }
+ catch(const std::exception& ex)
+ {
+ return convertException(ex);
+ }
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_InputStream_readEnum(void* self, int maxValue, int* r)
+{
+ try
+ {
+ *r = SELF->in->readEnum(maxValue);
+ }
+ catch(const std::exception& ex)
+ {
+ return convertException(ex);
+ }
+ return 0;
+}
+
+namespace
+{
+
+class MatlabUserException : public Ice::UserException
+{
+public:
+
+ MatlabUserException(const string& id, mxArray* ex, mxArray* streamWrapper) :
+ _id(id), _ex(ex), _streamWrapper(streamWrapper)
+ {
+ }
+
+ mxArray* exception() const
+ {
+ return _ex;
+ }
+
+ virtual string ice_id() const override
+ {
+ return _id;
+ }
+
+ virtual void _read(Ice::InputStream*) override
+ {
+ //
+ // Call read_() on the exception instance.
+ //
+ mxArray* params[2];
+ params[0] = _ex;
+ params[1] = _streamWrapper;
+ mxArray* err = mexCallMATLABWithTrap(0, 0, 2, params, "read_");
+ if(err)
+ {
+ mxDestroyArray(err);
+ throw Ice::MarshalException(__FILE__, __LINE__, "failure in exception's read_ method");
+ }
+ }
+
+ virtual bool _usesClasses() const override
+ {
+ //
+ // Call usesClasses_() on the exception instance.
+ //
+ mxArray* ex = const_cast<mxArray*>(_ex);
+ mxArray* r;
+ mxArray* err = mexCallMATLABWithTrap(1, &r, 1, &ex, "usesClasses_");
+ if(err)
+ {
+ mxDestroyArray(err);
+ throw Ice::MarshalException(__FILE__, __LINE__, "failure in exception's usesClasses_ method");
+ }
+ else
+ {
+ bool b = mxIsLogicalScalarTrue(r) ? true : false;
+ mxDestroyArray(r);
+ return b;
+ }
+ }
+
+ virtual void ice_throw() const override
+ {
+ throw static_cast<const MatlabUserException&>(*this);
+ }
+
+protected:
+
+ virtual IceUtil::Exception* ice_cloneImpl() const override
+ {
+ return 0;
+ }
+
+ virtual void _writeImpl(Ice::OutputStream*) const override
+ {
+ assert(false);
+ }
+
+ virtual void _readImpl(Ice::InputStream* in) override
+ {
+ assert(false);
+ }
+
+private:
+
+ string _id;
+ mxArray* _ex;
+ mxArray* _streamWrapper;
+};
+
+void createException(mxArray* streamWrapper, const string& id)
+{
+ //
+ // Convert the Slice type ID to a Matlab class name.
+ //
+ string cls = idToClass(id);
+ //
+ // Attempt to call the class constructor to obtain an instance. This may raise an exception.
+ //
+ mxArray* ex;
+ mxArray* err = mexCallMATLABWithTrap(1, &ex, 0, 0, cls.c_str());
+ if(err)
+ {
+ mxDestroyArray(err);
+ }
+ else
+ {
+ throw MatlabUserException(id, ex, streamWrapper);
+ }
+}
+
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_InputStream_throwException(void* self, mxArray* wrapper)
+{
+ try
+ {
+ SELF->in->throwException([wrapper](const string& id){ createException(wrapper, id); });
+ }
+ catch(MatlabUserException& ex)
+ {
+ return ex.exception();
+ }
+ catch(const std::exception& ex)
+ {
+ return convertException(ex);
+ }
+ return 0;
+}
+
+}
diff --git a/matlab/src/IceMatlab/InputStream.h b/matlab/src/IceMatlab/InputStream.h
new file mode 100644
index 00000000000..a801d6a5cb4
--- /dev/null
+++ b/matlab/src/IceMatlab/InputStream.h
@@ -0,0 +1,27 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2017 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#include <Ice/InputStream.h>
+
+namespace IceMatlab
+{
+
+struct InputStreamData
+{
+ std::vector<Ice::Byte> data;
+ Ice::InputStream* in;
+};
+
+//
+// Consumes the vector.
+//
+void* createInputStream(const std::shared_ptr<Ice::Communicator>&, const Ice::EncodingVersion&,
+ std::vector<Ice::Byte>&);
+
+}
diff --git a/matlab/src/IceMatlab/ObjectPrx.cpp b/matlab/src/IceMatlab/ObjectPrx.cpp
new file mode 100644
index 00000000000..3da06a7fd71
--- /dev/null
+++ b/matlab/src/IceMatlab/ObjectPrx.cpp
@@ -0,0 +1,1144 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2017 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#define EXPORT_FCNS
+
+#include <Ice/Ice.h>
+#include "icematlab.h"
+#include "Future.h"
+#include "InputStream.h"
+#include "Util.h"
+
+#define DEREF(x) (*(reinterpret_cast<shared_ptr<Ice::ObjectPrx>*>(x)))
+#define SELF DEREF(self)
+
+using namespace std;
+using namespace IceMatlab;
+
+namespace
+{
+
+class InvocationFuture : public Future
+{
+public:
+
+ InvocationFuture(bool, bool);
+ ~InvocationFuture();
+
+ virtual void exception(exception_ptr);
+ virtual void sent();
+ virtual string state() const;
+
+ void finished(const std::shared_ptr<Ice::Communicator>&, const Ice::EncodingVersion&, bool,
+ std::pair<const Ice::Byte*, const Ice::Byte*>);
+ void getResults(bool&, void*&);
+
+protected:
+
+ virtual bool isFinished() const;
+
+private:
+
+ const bool _twoway;
+ enum State { Running, Sent, Finished };
+ State _state;
+ bool _ok; // True for success, false for user exception.
+ void* _stream; // The InputStream for reading the results.
+};
+
+#define IFSELF (*(reinterpret_cast<shared_ptr<InvocationFuture>*>(self)))
+
+InvocationFuture::InvocationFuture(bool twoway, bool batch) :
+ _twoway(twoway),
+ _state(batch ? State::Finished : State::Running),
+ _ok(false),
+ _stream(0)
+{
+}
+
+InvocationFuture::~InvocationFuture()
+{
+ if(_stream)
+ {
+ Ice_InputStream__release(_stream);
+ }
+}
+
+void
+InvocationFuture::sent()
+{
+ IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this);
+ if(_state == State::Running)
+ {
+ _state = _twoway ? State::Sent : State::Finished;
+ }
+}
+
+void
+InvocationFuture::exception(exception_ptr e)
+{
+ IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this);
+ _state = State::Finished;
+ _token = nullptr;
+ _exception = e;
+ notifyAll();
+}
+
+void
+InvocationFuture::finished(const std::shared_ptr<Ice::Communicator>& communicator,
+ const Ice::EncodingVersion& encoding, bool b, pair<const Ice::Byte*, const Ice::Byte*> p)
+{
+ IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this);
+ _ok = b;
+ _state = State::Finished;
+ _token = nullptr;
+ if(p.second > p.first)
+ {
+ vector<Ice::Byte> data(p.first, p.second);
+ _stream = createInputStream(communicator, encoding, data);
+ }
+ notifyAll();
+}
+
+string
+InvocationFuture::state() const
+{
+ IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this);
+ string st;
+ switch(_state)
+ {
+ case State::Running:
+ st = "running";
+ break;
+ case State::Sent:
+ st = "sent";
+ break;
+ case State::Finished:
+ st = "finished";
+ break;
+ }
+ return st;
+}
+
+void
+InvocationFuture::getResults(bool& ok, void*& stream)
+{
+ IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this);
+ assert(_twoway);
+ ok = _ok;
+ assert(_stream);
+ stream = _stream;
+ _stream = 0;
+}
+
+bool
+InvocationFuture::isFinished() const
+{
+ return _state == State::Finished;
+}
+
+class GetConnectionFuture : public Future
+{
+public:
+
+ virtual string state() const;
+
+ void finished(shared_ptr<Ice::Connection>);
+ shared_ptr<Ice::Connection> getConnection() const;
+
+protected:
+
+ virtual bool isFinished() const;
+
+private:
+
+ shared_ptr<Ice::Connection> _connection;
+};
+
+#define GCFSELF (*(reinterpret_cast<shared_ptr<GetConnectionFuture>*>(self)))
+
+string
+GetConnectionFuture::state() const
+{
+ IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this);
+ if(_exception || _connection)
+ {
+ return "finished";
+ }
+ else
+ {
+ return "running";
+ }
+}
+
+void
+GetConnectionFuture::finished(shared_ptr<Ice::Connection> con)
+{
+ IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this);
+ _token = nullptr;
+ _connection = con;
+ notifyAll();
+}
+
+shared_ptr<Ice::Connection>
+GetConnectionFuture::getConnection() const
+{
+ IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this);
+ return _connection;
+}
+
+bool
+GetConnectionFuture::isFinished() const
+{
+ return _connection || _exception;
+}
+
+}
+
+extern "C"
+{
+
+EXPORTED_FUNCTION mxArray*
+Ice_ObjectPrx__release(void* self)
+{
+ delete &SELF;
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_ObjectPrx_equals(void* self, void* other, unsigned char* r)
+{
+ assert(other); // Wrapper only calls this function for non-nil arguments.
+ try
+ {
+ *r = Ice::targetEqualTo(SELF, DEREF(other)) ? 1 : 0;
+ }
+ catch(const std::exception& ex)
+ {
+ return convertException(ex);
+ }
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_ObjectPrx_ice_createOutputStream(void* self, void** stream)
+{
+ *stream = new Ice::OutputStream(SELF->ice_getCommunicator(), SELF->ice_getEncodingVersion());
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_ObjectPrx_ice_invoke(void* self, const char* op, Ice_OperationMode m, void* inParams, mxArray* context,
+ unsigned char* result, void** outParams)
+{
+ Ice::OutputStream* out = reinterpret_cast<Ice::OutputStream*>(inParams);
+ Ice::OperationMode mode = static_cast<Ice::OperationMode>(m);
+ pair<const Ice::Byte*, const Ice::Byte*> params(0, 0);
+ if(out)
+ {
+ params = out->finished();
+ }
+ vector<Ice::Byte> v;
+
+ *outParams = 0;
+
+ try
+ {
+ Ice::Context ctx;
+ getStringMap(context, ctx);
+ *result = SELF->ice_invoke(op, mode, params, v, ctx) ? 1 : 0;
+ if(!v.empty())
+ {
+ *outParams = createInputStream(SELF->ice_getCommunicator(), SELF->ice_getEncodingVersion(), v);
+ }
+ }
+ catch(const std::exception& ex)
+ {
+ return convertException(ex);
+ }
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_ObjectPrx_ice_invokeNC(void* self, const char* op, Ice_OperationMode m, void* inParams, unsigned char* result,
+ void** outParams)
+{
+ Ice::OutputStream* out = reinterpret_cast<Ice::OutputStream*>(inParams);
+ Ice::OperationMode mode = static_cast<Ice::OperationMode>(m);
+ pair<const Ice::Byte*, const Ice::Byte*> params(0, 0);
+ if(out)
+ {
+ params = out->finished();
+ }
+ vector<Ice::Byte> v;
+
+ *outParams = 0;
+
+ try
+ {
+ *result = SELF->ice_invoke(op, mode, params, v) ? 1 : 0;
+ if(!v.empty())
+ {
+ *outParams = createInputStream(SELF->ice_getCommunicator(), SELF->ice_getEncodingVersion(), v);
+ }
+ }
+ catch(const std::exception& ex)
+ {
+ return convertException(ex);
+ }
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_ObjectPrx_ice_invokeAsync(void* self, const char* op, Ice_OperationMode m, void* inParams, mxArray* context,
+ void** future)
+{
+ const shared_ptr<Ice::ObjectPrx> proxy = SELF;
+ Ice::OutputStream* out = reinterpret_cast<Ice::OutputStream*>(inParams);
+ Ice::OperationMode mode = static_cast<Ice::OperationMode>(m);
+ pair<const Ice::Byte*, const Ice::Byte*> params(0, 0);
+ if(out)
+ {
+ params = out->finished();
+ }
+
+ *future = 0;
+ auto f = make_shared<InvocationFuture>(proxy->ice_isTwoway(),
+ proxy->ice_isBatchOneway() || proxy->ice_isBatchDatagram());
+
+ try
+ {
+ Ice::Context ctx;
+ getStringMap(context, ctx);
+ function<void()> token = proxy->ice_invokeAsync(
+ op, mode, params,
+ [proxy, f](bool ok, pair<const Ice::Byte*, const Ice::Byte*> outParams)
+ {
+ f->finished(proxy->ice_getCommunicator(), proxy->ice_getEncodingVersion(), ok, outParams);
+ },
+ [f](exception_ptr e)
+ {
+ f->exception(e);
+ },
+ [f](bool /*sentSynchronously*/)
+ {
+ f->sent();
+ },
+ ctx);
+ f->token(token);
+ *future = new shared_ptr<InvocationFuture>(f);
+ }
+ catch(const std::exception& ex)
+ {
+ return convertException(ex);
+ }
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_ObjectPrx_ice_invokeAsyncNC(void* self, const char* op, Ice_OperationMode m, void* inParams, void** future)
+{
+ const shared_ptr<Ice::ObjectPrx> proxy = SELF;
+ Ice::OutputStream* out = reinterpret_cast<Ice::OutputStream*>(inParams);
+ Ice::OperationMode mode = static_cast<Ice::OperationMode>(m);
+ pair<const Ice::Byte*, const Ice::Byte*> params(0, 0);
+ if(out)
+ {
+ params = out->finished();
+ }
+
+ *future = 0;
+ auto f = make_shared<InvocationFuture>(proxy->ice_isTwoway(),
+ proxy->ice_isBatchOneway() || proxy->ice_isBatchDatagram());
+
+ try
+ {
+ function<void()> token = proxy->ice_invokeAsync(
+ op, mode, params,
+ [proxy, f](bool ok, pair<const Ice::Byte*, const Ice::Byte*> outParams)
+ {
+ f->finished(proxy->ice_getCommunicator(),
+ proxy->ice_getEncodingVersion(), ok, outParams);
+ },
+ [f](exception_ptr e)
+ {
+ f->exception(e);
+ },
+ [f](bool /*sentSynchronously*/)
+ {
+ f->sent();
+ });
+ f->token(token);
+ *future = new shared_ptr<InvocationFuture>(f);
+ }
+ catch(const std::exception& ex)
+ {
+ return convertException(ex);
+ }
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_ObjectPrx_ice_toString(void* self)
+{
+ return createResultValue(createStringFromUTF8(SELF->ice_toString()));
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_ObjectPrx_ice_getCommunicator(void* self, void** r)
+{
+ *r = new shared_ptr<Ice::Communicator>(SELF->ice_getCommunicator());
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_ObjectPrx_ice_getIdentity(void* self)
+{
+ return createResultValue(createIdentity(SELF->ice_getIdentity()));
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_ObjectPrx_ice_identity(void* self, mxArray* id, void** r)
+{
+ try
+ {
+ Ice::Identity ident;
+ getIdentity(id, ident);
+ shared_ptr<Ice::ObjectPrx> newProxy = SELF->ice_identity(ident);
+ *r = newProxy.get() == SELF.get() ? 0 : new shared_ptr<Ice::ObjectPrx>(newProxy);
+ }
+ catch(const std::exception& ex)
+ {
+ return convertException(ex);
+ }
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_ObjectPrx_ice_getContext(void* self)
+{
+ return createResultValue(createStringMap(SELF->ice_getContext()));
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_ObjectPrx_ice_context(void* self, mxArray* c, void** r)
+{
+ try
+ {
+ Ice::Context ctx;
+ getStringMap(c, ctx);
+ shared_ptr<Ice::ObjectPrx> newProxy = SELF->ice_context(ctx);
+ *r = newProxy.get() == SELF.get() ? 0 : new shared_ptr<Ice::ObjectPrx>(newProxy);
+ }
+ catch(const std::exception& ex)
+ {
+ return convertException(ex);
+ }
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_ObjectPrx_ice_getFacet(void* self)
+{
+ const string f = SELF->ice_getFacet();
+ return createResultValue(createStringFromUTF8(f));
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_ObjectPrx_ice_facet(void* self, const char* f, void** r)
+{
+ try
+ {
+ shared_ptr<Ice::ObjectPrx> newProxy = SELF->ice_facet(f);
+ *r = newProxy.get() == SELF.get() ? 0 : new shared_ptr<Ice::ObjectPrx>(newProxy);
+ }
+ catch(const std::exception& ex)
+ {
+ return convertException(ex);
+ }
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_ObjectPrx_ice_getAdapterId(void* self)
+{
+ const string f = SELF->ice_getAdapterId();
+ return createResultValue(createStringFromUTF8(f));
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_ObjectPrx_ice_adapterId(void* self, const char* id, void** r)
+{
+ try
+ {
+ shared_ptr<Ice::ObjectPrx> newProxy = SELF->ice_adapterId(id);
+ *r = newProxy.get() == SELF.get() ? 0 : new shared_ptr<Ice::ObjectPrx>(newProxy);
+ }
+ catch(const std::exception& ex)
+ {
+ return convertException(ex);
+ }
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_ObjectPrx_ice_getEndpoints(void* self)
+{
+ // TBD
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_ObjectPrx_ice_endpoints(void* self, mxArray* endpts, void** r)
+{
+ // TBD
+#if 0
+ try
+ {
+ shared_ptr<Ice::ObjectPrx> newProxy = SELF->ice_endpoints(id);
+ *r = newProxy.get() == SELF.get() ? 0 : new shared_ptr<Ice::ObjectPrx>(newProxy);
+ }
+ catch(const std::exception& ex)
+ {
+ return convertException(ex);
+ }
+#endif
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_ObjectPrx_ice_getLocatorCacheTimeout(void* self, int* t)
+{
+ *t = SELF->ice_getLocatorCacheTimeout();
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_ObjectPrx_ice_locatorCacheTimeout(void* self, int t, void** r)
+{
+ try
+ {
+ shared_ptr<Ice::ObjectPrx> newProxy = SELF->ice_locatorCacheTimeout(t);
+ *r = newProxy.get() == SELF.get() ? 0 : new shared_ptr<Ice::ObjectPrx>(newProxy);
+ }
+ catch(const std::exception& ex)
+ {
+ return convertException(ex);
+ }
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_ObjectPrx_ice_getInvocationTimeout(void* self, int* t)
+{
+ *t = SELF->ice_getInvocationTimeout();
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_ObjectPrx_ice_invocationTimeout(void* self, int t, void** r)
+{
+ try
+ {
+ shared_ptr<Ice::ObjectPrx> newProxy = SELF->ice_invocationTimeout(t);
+ *r = newProxy.get() == SELF.get() ? 0 : new shared_ptr<Ice::ObjectPrx>(newProxy);
+ }
+ catch(const std::exception& ex)
+ {
+ return convertException(ex);
+ }
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_ObjectPrx_ice_getConnectionId(void* self)
+{
+ const string f = SELF->ice_getConnectionId();
+ return createResultValue(createStringFromUTF8(f));
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_ObjectPrx_ice_connectionId(void* self, const char* id, void** r)
+{
+ try
+ {
+ shared_ptr<Ice::ObjectPrx> newProxy = SELF->ice_connectionId(id);
+ *r = newProxy.get() == SELF.get() ? 0 : new shared_ptr<Ice::ObjectPrx>(newProxy);
+ }
+ catch(const std::exception& ex)
+ {
+ return convertException(ex);
+ }
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_ObjectPrx_ice_isConnectionCached(void* self, unsigned char* r)
+{
+ *r = SELF->ice_isConnectionCached() ? 1 : 0;
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_ObjectPrx_ice_connectionCached(void* self, unsigned char v, void** r)
+{
+ try
+ {
+ shared_ptr<Ice::ObjectPrx> newProxy = SELF->ice_connectionCached(v == 1);
+ *r = newProxy.get() == SELF.get() ? 0 : new shared_ptr<Ice::ObjectPrx>(newProxy);
+ }
+ catch(const std::exception& ex)
+ {
+ return convertException(ex);
+ }
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_ObjectPrx_ice_getEndpointSelection(void* self, Ice_EndpointSelectionType* r)
+{
+ *r = SELF->ice_getEndpointSelection() == Ice::EndpointSelectionType::Random ? Random : Ordered;
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_ObjectPrx_ice_endpointSelection(void* self, Ice_EndpointSelectionType v, void** r)
+{
+ try
+ {
+ Ice::EndpointSelectionType type = static_cast<Ice::EndpointSelectionType>(v);
+ shared_ptr<Ice::ObjectPrx> newProxy = SELF->ice_endpointSelection(type);
+ *r = newProxy.get() == SELF.get() ? 0 : new shared_ptr<Ice::ObjectPrx>(newProxy);
+ }
+ catch(const std::exception& ex)
+ {
+ return convertException(ex);
+ }
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_ObjectPrx_ice_getEncodingVersion(void* self)
+{
+ return createResultValue(createEncodingVersion(SELF->ice_getEncodingVersion()));
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_ObjectPrx_ice_encodingVersion(void* self, mxArray* v, void** r)
+{
+ try
+ {
+ Ice::EncodingVersion ev;
+ getEncodingVersion(v, ev);
+ shared_ptr<Ice::ObjectPrx> newProxy = SELF->ice_encodingVersion(ev);
+ *r = newProxy.get() == SELF.get() ? 0 : new shared_ptr<Ice::ObjectPrx>(newProxy);
+ }
+ catch(const std::exception& ex)
+ {
+ return convertException(ex);
+ }
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_ObjectPrx_ice_getRouter(void* self, void** r)
+{
+ shared_ptr<Ice::ObjectPrx> router = SELF->ice_getRouter();
+ *r = router ? new shared_ptr<Ice::ObjectPrx>(router) : 0;
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_ObjectPrx_ice_router(void* self, void* rtr, void** r)
+{
+ try
+ {
+ shared_ptr<Ice::ObjectPrx> router;
+ if(rtr)
+ {
+ router = *(reinterpret_cast<shared_ptr<Ice::ObjectPrx>*>(rtr));
+ }
+ shared_ptr<Ice::ObjectPrx> newProxy = SELF->ice_router(Ice::uncheckedCast<Ice::RouterPrx>(router));
+ *r = newProxy.get() == SELF.get() ? 0 : new shared_ptr<Ice::ObjectPrx>(newProxy);
+ }
+ catch(const std::exception& ex)
+ {
+ return convertException(ex);
+ }
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_ObjectPrx_ice_getLocator(void* self, void** r)
+{
+ shared_ptr<Ice::ObjectPrx> locator = SELF->ice_getLocator();
+ *r = locator ? new shared_ptr<Ice::ObjectPrx>(locator) : 0;
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_ObjectPrx_ice_locator(void* self, void* loc, void** r)
+{
+ try
+ {
+ shared_ptr<Ice::ObjectPrx> locator;
+ if(loc)
+ {
+ locator = *(reinterpret_cast<shared_ptr<Ice::ObjectPrx>*>(loc));
+ }
+ shared_ptr<Ice::ObjectPrx> newProxy = SELF->ice_locator(Ice::uncheckedCast<Ice::LocatorPrx>(locator));
+ *r = newProxy.get() == SELF.get() ? 0 : new shared_ptr<Ice::ObjectPrx>(newProxy);
+ }
+ catch(const std::exception& ex)
+ {
+ return convertException(ex);
+ }
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_ObjectPrx_ice_isSecure(void* self, unsigned char* r)
+{
+ *r = SELF->ice_isSecure() ? 1 : 0;
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_ObjectPrx_ice_secure(void* self, unsigned char b, void** r)
+{
+ try
+ {
+ shared_ptr<Ice::ObjectPrx> newProxy = SELF->ice_secure(b == 1);
+ *r = newProxy.get() == SELF.get() ? 0 : new shared_ptr<Ice::ObjectPrx>(newProxy);
+ }
+ catch(const std::exception& ex)
+ {
+ return convertException(ex);
+ }
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_ObjectPrx_ice_isPreferSecure(void* self, unsigned char* r)
+{
+ *r = SELF->ice_isPreferSecure() ? 1 : 0;
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_ObjectPrx_ice_preferSecure(void* self, unsigned char b, void** r)
+{
+ try
+ {
+ shared_ptr<Ice::ObjectPrx> newProxy = SELF->ice_preferSecure(b == 1);
+ *r = newProxy.get() == SELF.get() ? 0 : new shared_ptr<Ice::ObjectPrx>(newProxy);
+ }
+ catch(const std::exception& ex)
+ {
+ return convertException(ex);
+ }
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_ObjectPrx_ice_isTwoway(void* self, unsigned char* r)
+{
+ *r = SELF->ice_isTwoway() ? 1 : 0;
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_ObjectPrx_ice_twoway(void* self, void** r)
+{
+ try
+ {
+ shared_ptr<Ice::ObjectPrx> newProxy = SELF->ice_twoway();
+ *r = newProxy.get() == SELF.get() ? 0 : new shared_ptr<Ice::ObjectPrx>(newProxy);
+ }
+ catch(const std::exception& ex)
+ {
+ return convertException(ex);
+ }
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_ObjectPrx_ice_isOneway(void* self, unsigned char* r)
+{
+ *r = SELF->ice_isOneway() ? 1 : 0;
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_ObjectPrx_ice_oneway(void* self, void** r)
+{
+ try
+ {
+ shared_ptr<Ice::ObjectPrx> newProxy = SELF->ice_oneway();
+ *r = newProxy.get() == SELF.get() ? 0 : new shared_ptr<Ice::ObjectPrx>(newProxy);
+ }
+ catch(const std::exception& ex)
+ {
+ return convertException(ex);
+ }
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_ObjectPrx_ice_isBatchOneway(void* self, unsigned char* r)
+{
+ *r = SELF->ice_isBatchOneway() ? 1 : 0;
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_ObjectPrx_ice_batchOneway(void* self, void** r)
+{
+ try
+ {
+ shared_ptr<Ice::ObjectPrx> newProxy = SELF->ice_batchOneway();
+ *r = newProxy.get() == SELF.get() ? 0 : new shared_ptr<Ice::ObjectPrx>(newProxy);
+ }
+ catch(const std::exception& ex)
+ {
+ return convertException(ex);
+ }
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_ObjectPrx_ice_isDatagram(void* self, unsigned char* r)
+{
+ *r = SELF->ice_isDatagram() ? 1 : 0;
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_ObjectPrx_ice_datagram(void* self, void** r)
+{
+ try
+ {
+ shared_ptr<Ice::ObjectPrx> newProxy = SELF->ice_datagram();
+ *r = newProxy.get() == SELF.get() ? 0 : new shared_ptr<Ice::ObjectPrx>(newProxy);
+ }
+ catch(const std::exception& ex)
+ {
+ return convertException(ex);
+ }
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_ObjectPrx_ice_isBatchDatagram(void* self, unsigned char* r)
+{
+ *r = SELF->ice_isBatchDatagram() ? 1 : 0;
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_ObjectPrx_ice_batchDatagram(void* self, void** r)
+{
+ try
+ {
+ shared_ptr<Ice::ObjectPrx> newProxy = SELF->ice_batchDatagram();
+ *r = newProxy.get() == SELF.get() ? 0 : new shared_ptr<Ice::ObjectPrx>(newProxy);
+ }
+ catch(const std::exception& ex)
+ {
+ return convertException(ex);
+ }
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_ObjectPrx_ice_compress(void* self, unsigned char b, void** r)
+{
+ try
+ {
+ shared_ptr<Ice::ObjectPrx> newProxy = SELF->ice_compress(b == 1);
+ *r = newProxy.get() == SELF.get() ? 0 : new shared_ptr<Ice::ObjectPrx>(newProxy);
+ }
+ catch(const std::exception& ex)
+ {
+ return convertException(ex);
+ }
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_ObjectPrx_ice_timeout(void* self, int t, void** r)
+{
+ try
+ {
+ shared_ptr<Ice::ObjectPrx> newProxy = SELF->ice_timeout(t);
+ *r = newProxy.get() == SELF.get() ? 0 : new shared_ptr<Ice::ObjectPrx>(newProxy);
+ }
+ catch(const std::exception& ex)
+ {
+ return convertException(ex);
+ }
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_ObjectPrx_ice_getConnection(void* self, void** r)
+{
+ *r = 0;
+ try
+ {
+ shared_ptr<Ice::Connection> conn = SELF->ice_getConnection();
+ if(conn)
+ {
+ *r = new shared_ptr<Ice::Connection>(conn);
+ }
+ }
+ catch(const std::exception& ex)
+ {
+ return convertException(ex);
+ }
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_ObjectPrx_ice_getConnectionAsync(void* self, void** future)
+{
+ *future = 0;
+ auto f = make_shared<GetConnectionFuture>();
+
+ try
+ {
+ function<void()> token = SELF->ice_getConnectionAsync(
+ [f](shared_ptr<Ice::Connection> con)
+ {
+ f->finished(con);
+ },
+ [f](exception_ptr e)
+ {
+ f->exception(e);
+ },
+ nullptr);
+ f->token(token);
+ *future = new shared_ptr<GetConnectionFuture>(f);
+ }
+ catch(const std::exception& ex)
+ {
+ return convertException(ex);
+ }
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_ObjectPrx_ice_getCachedConnection(void* self, void** r)
+{
+ *r = 0;
+ try
+ {
+ shared_ptr<Ice::Connection> conn = SELF->ice_getCachedConnection();
+ if(conn)
+ {
+ *r = new shared_ptr<Ice::Connection>(conn);
+ }
+ }
+ catch(const std::exception& ex)
+ {
+ return convertException(ex);
+ }
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_ObjectPrx_ice_flushBatchRequests(void* self)
+{
+ try
+ {
+ SELF->ice_flushBatchRequests();
+ }
+ catch(const std::exception& ex)
+ {
+ return convertException(ex);
+ }
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_ObjectPrx_ice_flushBatchRequestsAsync(void* self, void** future)
+{
+ *future = 0;
+ auto f = make_shared<SentFuture>();
+
+ try
+ {
+ function<void()> token = SELF->ice_flushBatchRequestsAsync(
+ [f](exception_ptr e)
+ {
+ f->exception(e);
+ },
+ [f](bool /*sentSynchronously*/)
+ {
+ f->sent();
+ });
+ f->token(token);
+ *future = new shared_ptr<SentFuture>(f);
+ }
+ catch(const std::exception& ex)
+ {
+ return convertException(ex);
+ }
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_ObjectPrx_clone(void* self, void** r)
+{
+ shared_ptr<Ice::ObjectPrx> p = SELF;
+ *r = new shared_ptr<Ice::ObjectPrx>(p);
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_InvocationFuture__release(void* self)
+{
+ delete &IFSELF;
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_InvocationFuture_id(void* self, unsigned long long* id)
+{
+ *id = reinterpret_cast<unsigned long long>(self);
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_InvocationFuture_wait(void* self, unsigned char* ok)
+{
+ // TBD: Timeout?
+
+ bool b = IFSELF->waitUntilFinished();
+ *ok = b ? 1 : 0;
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_InvocationFuture_stream(void* self, unsigned char* ok, void** stream)
+{
+ // TBD: Timeout?
+
+ if(!IFSELF->waitUntilFinished())
+ {
+ assert(IFSELF->getException());
+ try
+ {
+ rethrow_exception(IFSELF->getException());
+ }
+ catch(const std::exception& ex)
+ {
+ return convertException(ex);
+ }
+ }
+
+ bool b;
+ IFSELF->getResults(b, *stream);
+ *ok = b ? 1 : 0;
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_InvocationFuture_state(void* self)
+{
+ return createResultValue(createStringFromUTF8(IFSELF->state()));
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_InvocationFuture_cancel(void* self)
+{
+ IFSELF->cancel();
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_InvocationFuture_check(void* self)
+{
+ if(!IFSELF->waitUntilFinished())
+ {
+ assert(IFSELF->getException());
+ try
+ {
+ rethrow_exception(IFSELF->getException());
+ }
+ catch(const std::exception& ex)
+ {
+ return convertException(ex);
+ }
+ }
+
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_GetConnectionFuture__release(void* self)
+{
+ delete &GCFSELF;
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_GetConnectionFuture_id(void* self, unsigned long long* id)
+{
+ *id = reinterpret_cast<unsigned long long>(self);
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_GetConnectionFuture_wait(void* self, unsigned char* ok)
+{
+ // TBD: Timeout?
+
+ bool b = GCFSELF->waitUntilFinished();
+ *ok = b ? 1 : 0;
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_GetConnectionFuture_fetch(void* self, void** con)
+{
+ // TBD: Timeout?
+
+ if(!GCFSELF->waitUntilFinished())
+ {
+ assert(GCFSELF->getException());
+ try
+ {
+ rethrow_exception(GCFSELF->getException());
+ }
+ catch(const std::exception& ex)
+ {
+ return convertException(ex);
+ }
+ }
+
+ assert(GCFSELF->connection());
+ *con = new shared_ptr<Ice::Connection>(GCFSELF->getConnection());
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_GetConnectionFuture_state(void* self)
+{
+ return createResultValue(createStringFromUTF8(GCFSELF->state()));
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_GetConnectionFuture_cancel(void* self)
+{
+ GCFSELF->cancel();
+ return 0;
+}
+
+}
diff --git a/matlab/src/IceMatlab/OutputStream.cpp b/matlab/src/IceMatlab/OutputStream.cpp
new file mode 100644
index 00000000000..61b9afedf03
--- /dev/null
+++ b/matlab/src/IceMatlab/OutputStream.cpp
@@ -0,0 +1,716 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2017 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#define EXPORT_FCNS
+
+#include <Ice/Ice.h>
+#include "icematlab.h"
+#include "Util.h"
+
+#define SELF (reinterpret_cast<Ice::OutputStream*>(self))
+
+using namespace std;
+using namespace IceMatlab;
+
+
+extern "C"
+{
+
+EXPORTED_FUNCTION mxArray*
+Ice_OutputStream__release(void* self)
+{
+ delete SELF;
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_OutputStream_writeBool(void* self, unsigned char v)
+{
+ try
+ {
+ SELF->write(v == 1);
+ }
+ catch(const std::exception& ex)
+ {
+ return convertException(ex);
+ }
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_OutputStream_writeBoolOpt(void* self, int tag, unsigned char v)
+{
+ try
+ {
+ SELF->writeAll({tag}, IceUtil::Optional<bool>(v == 1));
+ }
+ catch(const std::exception& ex)
+ {
+ return convertException(ex);
+ }
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_OutputStream_writeBoolSeq(void* self, const unsigned char* v, int size)
+{
+ const bool* p = reinterpret_cast<const bool*>(v);
+ try
+ {
+ SELF->write(p, p + size);
+ }
+ catch(const std::exception& ex)
+ {
+ return convertException(ex);
+ }
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_OutputStream_writeBoolSeqOpt(void* self, int tag, const unsigned char* v, int size)
+{
+ const bool* p = reinterpret_cast<const bool*>(v);
+ try
+ {
+ if(SELF->writeOptional(tag, Ice::OptionalFormat::VSize))
+ {
+ SELF->write(p, p + size);
+ }
+ }
+ catch(const std::exception& ex)
+ {
+ return convertException(ex);
+ }
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_OutputStream_writeByte(void* self, unsigned char v)
+{
+ try
+ {
+ SELF->write(static_cast<Ice::Byte>(v));
+ }
+ catch(const std::exception& ex)
+ {
+ return convertException(ex);
+ }
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_OutputStream_writeByteOpt(void* self, int tag, unsigned char v)
+{
+ try
+ {
+ SELF->writeAll({tag}, IceUtil::Optional<Ice::Byte>(static_cast<Ice::Byte>(v)));
+ }
+ catch(const std::exception& ex)
+ {
+ return convertException(ex);
+ }
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_OutputStream_writeByteSeq(void* self, const unsigned char* v, int size)
+{
+ const Ice::Byte* p = reinterpret_cast<const Ice::Byte*>(v);
+ try
+ {
+ SELF->write(p, p + size);
+ }
+ catch(const std::exception& ex)
+ {
+ return convertException(ex);
+ }
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_OutputStream_writeByteSeqOpt(void* self, int tag, const unsigned char* v, int size)
+{
+ const Ice::Byte* p = reinterpret_cast<const Ice::Byte*>(v);
+ try
+ {
+ if(SELF->writeOptional(tag, Ice::OptionalFormat::VSize))
+ {
+ SELF->write(p, p + size);
+ }
+ }
+ catch(const std::exception& ex)
+ {
+ return convertException(ex);
+ }
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_OutputStream_writeShort(void* self, short v)
+{
+ try
+ {
+ SELF->write(v);
+ }
+ catch(const std::exception& ex)
+ {
+ return convertException(ex);
+ }
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_OutputStream_writeShortOpt(void* self, int tag, short v)
+{
+ try
+ {
+ SELF->writeAll({tag}, IceUtil::Optional<short>(v));
+ }
+ catch(const std::exception& ex)
+ {
+ return convertException(ex);
+ }
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_OutputStream_writeShortSeq(void* self, const short* v, int size)
+{
+ try
+ {
+ SELF->write(v, v + size);
+ }
+ catch(const std::exception& ex)
+ {
+ return convertException(ex);
+ }
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_OutputStream_writeShortSeqOpt(void* self, int tag, const short* v, int size)
+{
+ try
+ {
+ if(SELF->writeOptional(tag, Ice::OptionalFormat::VSize))
+ {
+ SELF->write(v, v + size);
+ }
+ }
+ catch(const std::exception& ex)
+ {
+ return convertException(ex);
+ }
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_OutputStream_writeInt(void* self, int v)
+{
+ try
+ {
+ SELF->write(v);
+ }
+ catch(const std::exception& ex)
+ {
+ return convertException(ex);
+ }
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_OutputStream_writeIntOpt(void* self, int tag, int v)
+{
+ try
+ {
+ SELF->writeAll({tag}, IceUtil::Optional<int>(v));
+ }
+ catch(const std::exception& ex)
+ {
+ return convertException(ex);
+ }
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_OutputStream_writeIntSeq(void* self, const int* v, int size)
+{
+ try
+ {
+ SELF->write(v, v + size);
+ }
+ catch(const std::exception& ex)
+ {
+ return convertException(ex);
+ }
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_OutputStream_writeIntSeqOpt(void* self, int tag, const int* v, int size)
+{
+ try
+ {
+ if(SELF->writeOptional(tag, Ice::OptionalFormat::VSize))
+ {
+ SELF->write(v, v + size);
+ }
+ }
+ catch(const std::exception& ex)
+ {
+ return convertException(ex);
+ }
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_OutputStream_writeLong(void* self, long long v)
+{
+ try
+ {
+ SELF->write(v);
+ }
+ catch(const std::exception& ex)
+ {
+ return convertException(ex);
+ }
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_OutputStream_writeLongOpt(void* self, int tag, long long v)
+{
+ try
+ {
+ SELF->writeAll({tag}, IceUtil::Optional<long long>(v));
+ }
+ catch(const std::exception& ex)
+ {
+ return convertException(ex);
+ }
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_OutputStream_writeLongSeq(void* self, const long long* v, int size)
+{
+ try
+ {
+ SELF->write(v, v + size);
+ }
+ catch(const std::exception& ex)
+ {
+ return convertException(ex);
+ }
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_OutputStream_writeLongSeqOpt(void* self, int tag, const long long* v, int size)
+{
+ try
+ {
+ if(SELF->writeOptional(tag, Ice::OptionalFormat::VSize))
+ {
+ SELF->write(v, v + size);
+ }
+ }
+ catch(const std::exception& ex)
+ {
+ return convertException(ex);
+ }
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_OutputStream_writeFloat(void* self, float v)
+{
+ try
+ {
+ SELF->write(v);
+ }
+ catch(const std::exception& ex)
+ {
+ return convertException(ex);
+ }
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_OutputStream_writeFloatOpt(void* self, int tag, float v)
+{
+ try
+ {
+ SELF->writeAll({tag}, IceUtil::Optional<float>(v));
+ }
+ catch(const std::exception& ex)
+ {
+ return convertException(ex);
+ }
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_OutputStream_writeFloatSeq(void* self, const float* v, int size)
+{
+ try
+ {
+ SELF->write(v, v + size);
+ }
+ catch(const std::exception& ex)
+ {
+ return convertException(ex);
+ }
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_OutputStream_writeFloatSeqOpt(void* self, int tag, const float* v, int size)
+{
+ try
+ {
+ if(SELF->writeOptional(tag, Ice::OptionalFormat::VSize))
+ {
+ SELF->write(v, v + size);
+ }
+ }
+ catch(const std::exception& ex)
+ {
+ return convertException(ex);
+ }
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_OutputStream_writeDouble(void* self, double v)
+{
+ try
+ {
+ SELF->write(v);
+ }
+ catch(const std::exception& ex)
+ {
+ return convertException(ex);
+ }
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_OutputStream_writeDoubleOpt(void* self, int tag, double v)
+{
+ try
+ {
+ SELF->writeAll({tag}, IceUtil::Optional<double>(v));
+ }
+ catch(const std::exception& ex)
+ {
+ return convertException(ex);
+ }
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_OutputStream_writeDoubleSeq(void* self, const double* v, int size)
+{
+ try
+ {
+ SELF->write(v, v + size);
+ }
+ catch(const std::exception& ex)
+ {
+ return convertException(ex);
+ }
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_OutputStream_writeDoubleSeqOpt(void* self, int tag, const double* v, int size)
+{
+ try
+ {
+ if(SELF->writeOptional(tag, Ice::OptionalFormat::VSize))
+ {
+ SELF->write(v, v + size);
+ }
+ }
+ catch(const std::exception& ex)
+ {
+ return convertException(ex);
+ }
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_OutputStream_writeString(void* self, mxArray* str)
+{
+ try
+ {
+ SELF->write(getStringFromUTF16(str), false);
+ }
+ catch(const std::exception& ex)
+ {
+ return convertException(ex);
+ }
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_OutputStream_writeStringOpt(void* self, int tag, mxArray* str)
+{
+ try
+ {
+ if(SELF->writeOptional(tag, Ice::OptionalFormat::VSize))
+ {
+ SELF->write(getStringFromUTF16(str), false);
+ }
+ }
+ catch(const std::exception& ex)
+ {
+ return convertException(ex);
+ }
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_OutputStream_writeStringSeq(void* self, mxArray* v)
+{
+ try
+ {
+ if(mxIsEmpty(v))
+ {
+ SELF->writeSize(0);
+ }
+ else if(!mxIsCell(v))
+ {
+ throw invalid_argument("value is not a cell array");
+ }
+ else
+ {
+ size_t m = mxGetM(v);
+ size_t n = mxGetN(v);
+ if(m != 1)
+ {
+ throw invalid_argument("cell array must be a 1xN matrix");
+ }
+ SELF->writeSize(n);
+ for(size_t i = 0; i < n; ++i)
+ {
+ mxArray* e = mxGetCell(v, i);
+ SELF->write(getStringFromUTF16(e), false);
+ }
+ }
+ }
+ catch(const std::exception& ex)
+ {
+ return convertException(ex);
+ }
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_OutputStream_writeStringSeqOpt(void* self, int tag, mxArray* v)
+{
+ try
+ {
+ if(SELF->writeOptional(tag, Ice::OptionalFormat::FSize))
+ {
+ Ice::OutputStream::size_type pos = SELF->startSize();
+ mxArray* ex = Ice_OutputStream_writeStringSeq(self, v);
+ if(ex)
+ {
+ return ex;
+ }
+ SELF->endSize(pos);
+ }
+ }
+ catch(const std::exception& ex)
+ {
+ return convertException(ex);
+ }
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_OutputStream_writeSize(void* self, int size)
+{
+ try
+ {
+ SELF->writeSize(size);
+ }
+ catch(const std::exception& ex)
+ {
+ return convertException(ex);
+ }
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_OutputStream_writeProxy(void* self, void* proxy)
+{
+ shared_ptr<Ice::ObjectPrx> p;
+ if(proxy)
+ {
+ p = *(reinterpret_cast<shared_ptr<Ice::ObjectPrx>*>(proxy));
+ }
+ try
+ {
+ SELF->writeProxy(p);
+ }
+ catch(const std::exception& ex)
+ {
+ return convertException(ex);
+ }
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_OutputStream_writeProxyOpt(void* self, int tag, void* proxy)
+{
+ assert(proxy); // Wrapper only calls this function for a non-nil value.
+ shared_ptr<Ice::ObjectPrx> p = *(reinterpret_cast<shared_ptr<Ice::ObjectPrx>*>(proxy));
+ try
+ {
+ SELF->writeAll({tag}, IceUtil::Optional<shared_ptr<Ice::ObjectPrx>>(p));
+ }
+ catch(const std::exception& ex)
+ {
+ return convertException(ex);
+ }
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_OutputStream_writeEnum(void* self, int val, int maxValue)
+{
+ try
+ {
+ SELF->writeEnum(val, maxValue);
+ }
+ catch(const std::exception& ex)
+ {
+ return convertException(ex);
+ }
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_OutputStream_startEncapsulation(void* self)
+{
+ try
+ {
+ SELF->startEncapsulation();
+ }
+ catch(const std::exception& ex)
+ {
+ return convertException(ex);
+ }
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_OutputStream_startEncapsulationWithFormat(void* self, Ice_FormatType t)
+{
+ Ice::FormatType type = static_cast<Ice::FormatType>(t);
+ try
+ {
+ SELF->startEncapsulation(SELF->getEncoding(), type);
+ }
+ catch(const std::exception& ex)
+ {
+ return convertException(ex);
+ }
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_OutputStream_endEncapsulation(void* self)
+{
+ try
+ {
+ SELF->endEncapsulation();
+ }
+ catch(const std::exception& ex)
+ {
+ return convertException(ex);
+ }
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_OutputStream_startSlice(void* self, const char* typeId, int compactId, unsigned char last)
+{
+ try
+ {
+ SELF->startSlice(typeId, compactId, last == 1);
+ }
+ catch(const std::exception& ex)
+ {
+ return convertException(ex);
+ }
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_OutputStream_endSlice(void* self)
+{
+ try
+ {
+ SELF->endSlice();
+ }
+ catch(const std::exception& ex)
+ {
+ return convertException(ex);
+ }
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_OutputStream_writeOptional(void* self, int tag, Ice_OptionalFormat f, unsigned char* supportsOptionals)
+{
+ Ice::OptionalFormat fmt = static_cast<Ice::OptionalFormat>(f);
+ try
+ {
+ *supportsOptionals = SELF->writeOptional(tag, fmt);
+ }
+ catch(const std::exception& ex)
+ {
+ return convertException(ex);
+ }
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_OutputStream_startSize(void* self, unsigned int* pos)
+{
+ try
+ {
+ *pos = static_cast<unsigned int>(SELF->startSize());
+ }
+ catch(const std::exception& ex)
+ {
+ return convertException(ex);
+ }
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_OutputStream_endSize(void* self, unsigned int pos)
+{
+ try
+ {
+ SELF->endSize(pos);
+ }
+ catch(const std::exception& ex)
+ {
+ return convertException(ex);
+ }
+ return 0;
+}
+
+}
diff --git a/matlab/src/IceMatlab/Properties.cpp b/matlab/src/IceMatlab/Properties.cpp
new file mode 100644
index 00000000000..87dd2c1dd77
--- /dev/null
+++ b/matlab/src/IceMatlab/Properties.cpp
@@ -0,0 +1,254 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2017 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#define EXPORT_FCNS
+
+#include <Ice/Properties.h>
+#include <Ice/Initialize.h>
+#include "icematlab.h"
+#include "Util.h"
+
+#define SELF (*(reinterpret_cast<shared_ptr<Ice::Properties>*>(self)))
+
+using namespace std;
+using namespace IceMatlab;
+
+extern "C"
+{
+
+//
+// Implementation note: We need to pass the implementation object from MATLAB code for the defaults argument.
+// If we passed the wrapper object instead, there is no way to extract the void pointer from the mxArray object.
+//
+EXPORTED_FUNCTION mxArray*
+Ice_createProperties(mxArray* args, void* defaultsImpl, void** r)
+{
+ try
+ {
+ vector<string> a;
+ getStringList(args, a);
+ shared_ptr<Ice::Properties> def;
+ if(defaultsImpl)
+ {
+ def = *(reinterpret_cast<shared_ptr<Ice::Properties>*>(defaultsImpl));
+ }
+ shared_ptr<Ice::Properties> props = Ice::createProperties(a, def);
+ *r = new shared_ptr<Ice::Properties>(props);
+ return createResultValue(createStringList(a));
+ }
+ catch(const std::exception& ex)
+ {
+ return createResultException(convertException(ex));
+ }
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_Properties__release(void* self)
+{
+ delete &SELF;
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_Properties_getProperty(void* self, const char* key)
+{
+ try
+ {
+ return createResultValue(createStringFromUTF8(SELF->getProperty(key)));
+ }
+ catch(const std::exception& ex)
+ {
+ return createResultException(convertException(ex));
+ }
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_Properties_getPropertyWithDefault(void* self, const char* key, const char* dflt)
+{
+ try
+ {
+ return createResultValue(createStringFromUTF8(SELF->getPropertyWithDefault(key, dflt)));
+ }
+ catch(const std::exception& ex)
+ {
+ return createResultException(convertException(ex));
+ }
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_Properties_getPropertyAsInt(void* self, const char* key, int* r)
+{
+ try
+ {
+ *r = SELF->getPropertyAsInt(key);
+ }
+ catch(const std::exception& ex)
+ {
+ return convertException(ex);
+ }
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_Properties_getPropertyAsIntWithDefault(void* self, const char* key, int dflt, int* r)
+{
+ try
+ {
+ *r = SELF->getPropertyAsIntWithDefault(key, dflt);
+ }
+ catch(const std::exception& ex)
+ {
+ return convertException(ex);
+ }
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_Properties_getPropertyAsList(void* self, const char* key)
+{
+ try
+ {
+ Ice::StringSeq l = SELF->getPropertyAsList(key);
+ return createResultValue(createStringList(l));
+ }
+ catch(const std::exception& ex)
+ {
+ return createResultException(convertException(ex));
+ }
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_Properties_getPropertyAsListWithDefault(void* self, const char* key, mxArray* dflt)
+{
+ try
+ {
+ Ice::StringSeq d;
+ getStringList(dflt, d);
+ Ice::StringSeq l = SELF->getPropertyAsListWithDefault(key, d);
+ return createResultValue(createStringList(l));
+ }
+ catch(const std::exception& ex)
+ {
+ return createResultException(convertException(ex));
+ }
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_Properties_getPropertiesForPrefix(void* self, const char* prefix)
+{
+ try
+ {
+ Ice::PropertyDict d = SELF->getPropertiesForPrefix(prefix);
+ return createResultValue(createStringMap(d));
+ }
+ catch(const std::exception& ex)
+ {
+ return createResultException(convertException(ex));
+ }
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_Properties_setProperty(void* self, const char* key, const char* value)
+{
+ try
+ {
+ SELF->setProperty(key, value);
+ }
+ catch(const std::exception& ex)
+ {
+ return convertException(ex);
+ }
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_Properties_getCommandLineOptions(void* self)
+{
+ try
+ {
+ Ice::StringSeq opts = SELF->getCommandLineOptions();
+ return createResultValue(createStringList(opts));
+ }
+ catch(const std::exception& ex)
+ {
+ return createResultException(convertException(ex));
+ }
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_Properties_parseCommandLineOptions(void* self, const char* prefix, mxArray* options)
+{
+ try
+ {
+ Ice::StringSeq opts;
+ getStringList(options, opts);
+ Ice::StringSeq rem = SELF->parseCommandLineOptions(prefix, opts);
+ return createResultValue(createStringList(rem));
+ }
+ catch(const std::exception& ex)
+ {
+ return createResultException(convertException(ex));
+ }
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_Properties_parseIceCommandLineOptions(void* self, mxArray* options)
+{
+ try
+ {
+ Ice::StringSeq opts;
+ getStringList(options, opts);
+ Ice::StringSeq rem = SELF->parseIceCommandLineOptions(opts);
+ return createResultValue(createStringList(rem));
+ }
+ catch(const std::exception& ex)
+ {
+ return createResultException(convertException(ex));
+ }
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_Properties_load(void* self, const char* file)
+{
+ try
+ {
+ SELF->load(file);
+ }
+ catch(const std::exception& ex)
+ {
+ return convertException(ex);
+ }
+ return 0;
+}
+
+EXPORTED_FUNCTION mxArray*
+Ice_Properties_clone(void* self, void** r)
+{
+ try
+ {
+ shared_ptr<Ice::Properties> c = SELF->clone();
+ *r = new shared_ptr<Ice::Properties>(c);
+ }
+ catch(const std::exception& ex)
+ {
+ return convertException(ex);
+ }
+ return 0;
+}
+
+}
diff --git a/matlab/src/IceMatlab/Util.cpp b/matlab/src/IceMatlab/Util.cpp
new file mode 100644
index 00000000000..d4c15b7255e
--- /dev/null
+++ b/matlab/src/IceMatlab/Util.cpp
@@ -0,0 +1,648 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2017 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#include <Ice/LocalException.h>
+#include <iostream>
+#include <string>
+#include <locale>
+#include <codecvt>
+#include "icematlab.h"
+#include "Util.h"
+
+using namespace std;
+
+namespace
+{
+
+string
+replace(string s, string patt, string val)
+{
+ string r = s;
+ string::size_type pos = r.find(patt);
+ while(pos != string::npos)
+ {
+ r.replace(pos, patt.size(), val);
+ pos += val.size();
+ pos = r.find(patt, pos);
+ }
+ return r;
+}
+
+void
+getMajorMinor(mxArray* p, Ice::Byte& major, Ice::Byte& minor)
+{
+ mxArray* maj = mxGetProperty(p, 0, "major");
+ assert(maj);
+ if(!mxIsScalar(maj))
+ {
+ throw std::invalid_argument("major is not a scalar");
+ }
+ major = static_cast<Ice::Byte>(mxGetScalar(maj));
+ mxArray* min = mxGetProperty(p, 0, "minor");
+ assert(min);
+ if(!mxIsScalar(min))
+ {
+ throw std::invalid_argument("minor is not a scalar");
+ }
+ minor = static_cast<Ice::Byte>(mxGetScalar(min));
+}
+
+}
+
+mxArray*
+IceMatlab::createStringFromUTF8(const string& s)
+{
+#ifdef _MSC_VER
+ //
+ // Workaround for Visual Studio bug that causes a link error when using char16_t.
+ //
+ wstring utf16 = wstring_convert<codecvt_utf8_utf16<wchar_t>, wchar_t>{}.from_bytes(s.data());
+#else
+ u16string utf16 = wstring_convert<codecvt_utf8_utf16<char16_t>, char16_t>{}.from_bytes(s.data());
+#endif
+ mwSize dims[2] = { 1, utf16.size() };
+ mxArray* r = mxCreateCharArray(2, dims);
+ mxChar* buf = mxGetChars(r);
+ int i = 0;
+#ifdef _MSC_VER
+ for(wchar_t c : utf16)
+#else
+ for(char16_t c : utf16)
+#endif
+ {
+ buf[i++] = static_cast<mxChar>(c);
+ }
+ return r;
+}
+
+string
+IceMatlab::getStringFromUTF16(mxArray* p)
+{
+ char* s = mxArrayToUTF8String(p);
+ if(!s)
+ {
+ throw std::invalid_argument("value is not a char array");
+ }
+ string str(s);
+ mxFree(s);
+ return str;
+}
+
+mxArray*
+IceMatlab::createEmpty()
+{
+ return mxCreateNumericMatrix(0, 0, mxDOUBLE_CLASS, mxREAL);
+}
+
+mxArray*
+IceMatlab::createBool(bool v)
+{
+ mxArray* r = mxCreateNumericMatrix(1, 1, mxLOGICAL_CLASS, mxREAL);
+ bool* p = reinterpret_cast<bool*>(mxGetPr(r));
+ *p = v;
+ return r;
+}
+
+mxArray*
+IceMatlab::createByte(Ice::Byte v)
+{
+ mxArray* r = mxCreateNumericMatrix(1, 1, mxUINT8_CLASS, mxREAL);
+ Ice::Byte* p = reinterpret_cast<Ice::Byte*>(mxGetPr(r));
+ *p = v;
+ return r;
+}
+
+mxArray*
+IceMatlab::createShort(short v)
+{
+ mxArray* r = mxCreateNumericMatrix(1, 1, mxINT16_CLASS, mxREAL);
+ short* p = reinterpret_cast<short*>(mxGetPr(r));
+ *p = v;
+ return r;
+}
+
+mxArray*
+IceMatlab::createInt(int v)
+{
+ mxArray* r = mxCreateNumericMatrix(1, 1, mxINT32_CLASS, mxREAL);
+ int* p = reinterpret_cast<int*>(mxGetPr(r));
+ *p = v;
+ return r;
+}
+
+mxArray*
+IceMatlab::createLong(long long v)
+{
+ mxArray* r = mxCreateNumericMatrix(1, 1, mxINT64_CLASS, mxREAL);
+ long long* p = reinterpret_cast<long long*>(mxGetPr(r));
+ *p = v;
+ return r;
+}
+
+mxArray*
+IceMatlab::createFloat(float v)
+{
+ mxArray* r = mxCreateNumericMatrix(1, 1, mxSINGLE_CLASS, mxREAL);
+ float* p = reinterpret_cast<float*>(mxGetPr(r));
+ *p = v;
+ return r;
+}
+
+mxArray*
+IceMatlab::createDouble(double v)
+{
+ mxArray* r = mxCreateNumericMatrix(1, 1, mxDOUBLE_CLASS, mxREAL);
+ double* p = reinterpret_cast<double*>(mxGetPr(r));
+ *p = v;
+ return r;
+}
+
+mxArray*
+IceMatlab::createEnumerator(const string& type, int v)
+{
+ string func = type + ".ice_getValue";
+ mxArray* param = createInt(v);
+ mxArray* r;
+ mexCallMATLAB(1, &r, 1, &param, func.c_str());
+ mxFree(param);
+ return r;
+}
+
+int
+IceMatlab::getEnumerator(mxArray* p, const string& type)
+{
+ if(!mxIsClass(p, type.c_str()))
+ {
+ throw invalid_argument("expected enumerator of type " + type);
+ }
+ return static_cast<int>(mxGetScalar(p));
+}
+
+mxArray*
+IceMatlab::createIdentity(const Ice::Identity& id)
+{
+ mxArray* params[2];
+ params[0] = createStringFromUTF8(id.name);
+ params[1] = createStringFromUTF8(id.category);
+ mxArray* r;
+ mexCallMATLAB(1, &r, 2, params, "Ice.Identity");
+ return r;
+}
+
+void
+IceMatlab::getIdentity(mxArray* p, Ice::Identity& id)
+{
+ if(!mxIsClass(p, "Ice.Identity"))
+ {
+ throw std::invalid_argument("argument is not Ice.Identity");
+ }
+ mxArray* name = mxGetProperty(p, 0, "name");
+ assert(name);
+ id.name = getStringFromUTF16(name);
+ mxArray* category = mxGetProperty(p, 0, "category");
+ assert(category);
+ id.category = getStringFromUTF16(category);
+}
+
+mxArray*
+IceMatlab::createStringMap(const map<string, string>& m)
+{
+ mxArray* r;
+ if(m.empty())
+ {
+ mexCallMATLAB(1, &r, 0, 0, "containers.Map");
+ }
+ else
+ {
+ mwSize dims[2] = {1, 0};
+ dims[1] = m.size();
+ mxArray* keys = mxCreateCellArray(2, dims);
+ mxArray* values = mxCreateCellArray(2, dims);
+ int idx = 0;
+ for(map<string, string>::const_iterator p = m.begin(); p != m.end(); ++p)
+ {
+ mxSetCell(keys, idx, createStringFromUTF8(p->first));
+ mxSetCell(values, idx, createStringFromUTF8(p->second));
+ idx++;
+ }
+ mxArray* params[2];
+ params[0] = keys;
+ params[1] = values;
+ mexCallMATLAB(1, &r, 2, params, "containers.Map");
+ }
+ return r;
+}
+
+void
+IceMatlab::getStringMap(mxArray* p, map<string, string>& m)
+{
+ if(mxIsEmpty(p))
+ {
+ m.clear();
+ }
+ else if(!mxIsClass(p, "containers.Map"))
+ {
+ throw std::invalid_argument("argument is not a containers.Map");
+ }
+ else
+ {
+ mxArray* params[1];
+ params[0] = p;
+ mxArray* keys;
+ mexCallMATLAB(1, &keys, 1, params, "keys");
+ mxArray* values;
+ mexCallMATLAB(1, &values, 1, params, "values");
+ assert(mxGetM(keys) == 1 && mxGetM(values) == 1);
+ assert(mxGetN(keys) == mxGetN(values));
+ const size_t n = mxGetN(keys);
+ try
+ {
+ for(size_t i = 0; i < n; ++i)
+ {
+ string k = getStringFromUTF16(mxGetCell(keys, i));
+ string v = getStringFromUTF16(mxGetCell(values, i));
+ m[k] = v;
+ }
+ mxDestroyArray(keys);
+ mxDestroyArray(values);
+ }
+ catch(...)
+ {
+ mxDestroyArray(keys);
+ mxDestroyArray(values);
+ throw;
+ }
+ }
+}
+
+mxArray*
+IceMatlab::createEncodingVersion(const Ice::EncodingVersion& v)
+{
+ mxArray* params[2];
+ params[0] = mxCreateDoubleScalar(v.major);
+ params[1] = mxCreateDoubleScalar(v.minor);
+ mxArray* r;
+ mexCallMATLAB(1, &r, 2, params, "Ice.EncodingVersion");
+ return r;
+}
+
+void
+IceMatlab::getEncodingVersion(mxArray* p, Ice::EncodingVersion& v)
+{
+ if(!mxIsClass(p, "Ice.EncodingVersion"))
+ {
+ throw std::invalid_argument("argument is not Ice.EncodingVersion");
+ }
+ getMajorMinor(p, v.major, v.minor);
+}
+
+mxArray*
+IceMatlab::createProtocolVersion(const Ice::ProtocolVersion& v)
+{
+ mxArray* params[2];
+ params[0] = mxCreateDoubleScalar(v.major);
+ params[1] = mxCreateDoubleScalar(v.minor);
+ mxArray* r;
+ mexCallMATLAB(1, &r, 2, params, "Ice.ProtocolVersion");
+ return r;
+}
+
+void
+IceMatlab::getProtocolVersion(mxArray* p, Ice::ProtocolVersion& v)
+{
+ if(!mxIsClass(p, "Ice.ProtocolVersion"))
+ {
+ throw std::invalid_argument("argument is not Ice.ProtocolVersion");
+ }
+ getMajorMinor(p, v.major, v.minor);
+}
+
+mxArray*
+IceMatlab::convertException(const std::exception& exc)
+{
+ mxArray* ex;
+ if(dynamic_cast<const Ice::LocalException*>(&exc))
+ {
+ const Ice::LocalException* iceEx = dynamic_cast<const Ice::LocalException*>(&exc);
+ const string typeId = iceEx->ice_id();
+ //
+ // The exception ID uses single colon separators.
+ //
+ string id = typeId.substr(2); // Remove leading "::" from type ID
+ id = replace(id, "::", ":");
+
+ string cls = typeId.substr(2); // Remove leading "::" from type ID
+ cls = replace(cls, "::", ".");
+
+ mxArray* params[10];
+ params[0] = createStringFromUTF8(id);
+ int idx = 2;
+ string msg = typeId; // Use the type ID as the default exception message
+
+ try
+ {
+ iceEx->ice_throw();
+ }
+ catch(const Ice::InitializationException& e)
+ {
+ msg = e.reason;
+ params[idx++] = createStringFromUTF8(e.reason);
+ }
+ catch(const Ice::PluginInitializationException& e)
+ {
+ msg = e.reason;
+ params[idx++] = createStringFromUTF8(e.reason);
+ }
+ catch(const Ice::AlreadyRegisteredException& e)
+ {
+ params[idx++] = createStringFromUTF8(e.kindOfObject);
+ params[idx++] = createStringFromUTF8(e.id);
+ }
+ catch(const Ice::NotRegisteredException& e)
+ {
+ params[idx++] = createStringFromUTF8(e.kindOfObject);
+ params[idx++] = createStringFromUTF8(e.id);
+ }
+ catch(const Ice::TwowayOnlyException& e)
+ {
+ params[idx++] = createStringFromUTF8(e.operation);
+ }
+ catch(const Ice::UnknownException& e)
+ {
+ params[idx++] = createStringFromUTF8(e.unknown);
+ }
+ catch(const Ice::ObjectAdapterDeactivatedException& e)
+ {
+ params[idx++] = createStringFromUTF8(e.name);
+ }
+ catch(const Ice::ObjectAdapterIdInUseException& e)
+ {
+ params[idx++] = createStringFromUTF8(e.id);
+ }
+ catch(const Ice::NoEndpointException& e)
+ {
+ params[idx++] = createStringFromUTF8(e.proxy);
+ }
+ catch(const Ice::EndpointParseException& e)
+ {
+ params[idx++] = createStringFromUTF8(e.str);
+ }
+ catch(const Ice::EndpointSelectionTypeParseException& e)
+ {
+ params[idx++] = createStringFromUTF8(e.str);
+ }
+ catch(const Ice::VersionParseException& e)
+ {
+ params[idx++] = createStringFromUTF8(e.str);
+ }
+ catch(const Ice::IdentityParseException& e)
+ {
+ params[idx++] = createStringFromUTF8(e.str);
+ }
+ catch(const Ice::ProxyParseException& e)
+ {
+ params[idx++] = createStringFromUTF8(e.str);
+ }
+ catch(const Ice::IllegalIdentityException& e)
+ {
+ params[idx++] = createIdentity(e.id);
+ }
+ catch(const Ice::RequestFailedException& e)
+ {
+ params[idx++] = createIdentity(e.id);
+ params[idx++] = createStringFromUTF8(e.facet);
+ params[idx++] = createStringFromUTF8(e.operation);
+ }
+ catch(const Ice::FileException& e)
+ {
+ params[idx++] = mxCreateDoubleScalar(e.error);
+ params[idx++] = createStringFromUTF8(e.path);
+ }
+ catch(const Ice::SyscallException& e) // This must appear after all subclasses of SyscallException.
+ {
+ params[idx++] = mxCreateDoubleScalar(e.error);
+ }
+ catch(const Ice::DNSException& e)
+ {
+ params[idx++] = mxCreateDoubleScalar(e.error);
+ params[idx++] = createStringFromUTF8(e.host);
+ }
+ catch(const Ice::UnsupportedProtocolException& e)
+ {
+ params[idx++] = createProtocolVersion(e.bad);
+ params[idx++] = createProtocolVersion(e.supported);
+ }
+ catch(const Ice::UnsupportedEncodingException& e)
+ {
+ params[idx++] = createEncodingVersion(e.bad);
+ params[idx++] = createEncodingVersion(e.supported);
+ }
+ catch(const Ice::ConnectionManuallyClosedException& e)
+ {
+ params[idx++] = mxCreateLogicalScalar(e.graceful ? 1 : 0);
+ }
+ catch(const Ice::NoValueFactoryException& e)
+ {
+ params[idx++] = createStringFromUTF8(e.reason);
+ params[idx++] = createStringFromUTF8(e.type);
+ }
+ catch(const Ice::UnexpectedObjectException& e)
+ {
+ params[idx++] = createStringFromUTF8(e.reason);
+ params[idx++] = createStringFromUTF8(e.type);
+ params[idx++] = createStringFromUTF8(e.expectedType);
+ }
+ catch(const Ice::ProtocolException& e) // This must appear after all subclasses of ProtocolException.
+ {
+ params[idx++] = createStringFromUTF8(e.reason);
+ }
+ catch(const Ice::FeatureNotSupportedException& e)
+ {
+ params[idx++] = createStringFromUTF8(e.unsupportedFeature);
+ }
+ catch(const Ice::SecurityException& e)
+ {
+ params[idx++] = createStringFromUTF8(e.reason);
+ }
+ catch(const Ice::IllegalServantException& e)
+ {
+ params[idx++] = createStringFromUTF8(e.reason);
+ }
+ catch(const Ice::LocalException&)
+ {
+ //
+ // Nothing to do.
+ //
+ }
+
+ //
+ // NOTE: Matlab interprets the msg argument as an sprintf format string. It will complain if it
+ // finds invalid syntax.
+ //
+ params[1] = createStringFromUTF8(msg);
+ mexCallMATLAB(1, &ex, idx, params, cls.c_str());
+ }
+ else
+ {
+ mxArray* params[2];
+ params[0] = createStringFromUTF8("Ice:CppException");
+ params[1] = createStringFromUTF8(exc.what());
+ mexCallMATLAB(1, &ex, 2, params, "MException");
+ }
+ return ex;
+}
+
+static const char* resultFields[] = {"exception", "result"};
+
+mxArray*
+IceMatlab::createResultValue(mxArray* result)
+{
+ mwSize dims[2] = {1, 1};
+ mxArray* r = mxCreateStructArray(2, dims, 2, resultFields);
+ mxSetFieldByNumber(r, 0, 1, result);
+ return r;
+}
+
+mxArray*
+IceMatlab::createResultException(mxArray* ex)
+{
+ mwSize dims[2] = {1, 1};
+ mxArray* r = mxCreateStructArray(2, dims, 2, resultFields);
+ mxSetFieldByNumber(r, 0, 0, ex);
+ return r;
+}
+
+mxArray*
+IceMatlab::createStringList(const vector<string>& v)
+{
+ mxArray* r = mxCreateCellMatrix(1, v.size());
+ mwIndex i = 0;
+ for(vector<string>::const_iterator p = v.begin(); p != v.end(); ++p, ++i)
+ {
+ mxSetCell(r, i, createStringFromUTF8(*p));
+ }
+ return r;
+}
+
+void
+IceMatlab::getStringList(mxArray* m, vector<string>& v)
+{
+ if(!mxIsCell(m))
+ {
+ throw std::invalid_argument("argument is not a cell array");
+ }
+ if(mxGetM(m) > 1)
+ {
+ throw std::invalid_argument("invalid dimension in cell array");
+ }
+ size_t n = mxGetN(m);
+ v.clear();
+ for(size_t i = 0; i < n; ++i)
+ {
+ mxArray* c = mxGetCell(m, i);
+ v.push_back(getStringFromUTF16(c));
+ }
+}
+
+#if 0
+void*
+IceMatlab::getImpl(mxArray* obj, const std::string& className)
+{
+ void* p = 0;
+ if(!mxIsEmpty(obj))
+ {
+ if(!mxIsClass(obj, className.c_str()))
+ {
+ throw std::invalid_argument("expecting object of type " + className);
+ }
+ mxArray* implProp = mxGetProperty(obj, 0, "impl");
+ assert(implProp);
+ mxArray* value = mxGetProperty(implProp, 0, "value");
+ assert(value);
+ p = mxGetData(value);
+ }
+ return p;
+}
+#endif
+
+namespace
+{
+
+string
+lookupKwd(const string& name)
+{
+ //
+ // Keyword list. *Must* be kept in alphabetical order.
+ //
+ // This list must match the one in slice2matlab.
+ //
+ static const string keywordList[] =
+ {
+ "break", "case", "catch", "classdef", "continue", "else", "elseif", "end", "for", "function", "global",
+ "if", "otherwise", "parfor", "persistent", "return", "spmd", "switch", "try", "while"
+ };
+ bool found = binary_search(&keywordList[0],
+ &keywordList[sizeof(keywordList) / sizeof(*keywordList)],
+ name);
+ return found ? "slice_" + name : name;
+}
+
+//
+// Split a scoped name into its components and return the components as a list of (unscoped) identifiers.
+//
+vector<string>
+splitScopedName(const string& scoped)
+{
+ assert(scoped[0] == ':');
+ vector<string> ids;
+ string::size_type next = 0;
+ string::size_type pos;
+ while((pos = scoped.find("::", next)) != string::npos)
+ {
+ pos += 2;
+ if(pos != scoped.size())
+ {
+ string::size_type endpos = scoped.find("::", pos);
+ if(endpos != string::npos)
+ {
+ ids.push_back(scoped.substr(pos, endpos - pos));
+ }
+ }
+ next = pos;
+ }
+ if(next != scoped.size())
+ {
+ ids.push_back(scoped.substr(next));
+ }
+ else
+ {
+ ids.push_back("");
+ }
+
+ return ids;
+}
+
+}
+
+string
+IceMatlab::idToClass(const string& id)
+{
+ vector<string> ids = splitScopedName(id);
+ transform(ids.begin(), ids.end(), ids.begin(), ptr_fun(lookupKwd));
+ stringstream result;
+ for(vector<string>::const_iterator i = ids.begin(); i != ids.end(); ++i)
+ {
+ if(i != ids.begin())
+ {
+ result << ".";
+ }
+ result << *i;
+ }
+ return result.str();
+}
diff --git a/matlab/src/IceMatlab/Util.h b/matlab/src/IceMatlab/Util.h
new file mode 100644
index 00000000000..60ba9a2c038
--- /dev/null
+++ b/matlab/src/IceMatlab/Util.h
@@ -0,0 +1,47 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2017 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#include <Ice/Identity.h>
+#include <Ice/Version.h>
+#include <mex.h>
+
+typedef struct mxArray_tag mxArray; // Forward declaration to avoid importing mex.h here
+
+namespace IceMatlab
+{
+
+mxArray* createStringFromUTF8(const std::string&);
+std::string getStringFromUTF16(mxArray*);
+mxArray* createEmpty();
+mxArray* createBool(bool);
+mxArray* createByte(Ice::Byte);
+mxArray* createShort(short);
+mxArray* createInt(int);
+mxArray* createLong(long long);
+mxArray* createFloat(float);
+mxArray* createDouble(double);
+mxArray* createEnumerator(const std::string&, int);
+int getEnumerator(mxArray*, const std::string&);
+mxArray* createIdentity(const Ice::Identity&);
+void getIdentity(mxArray*, Ice::Identity&);
+mxArray* createStringMap(const std::map<std::string, std::string>&);
+void getStringMap(mxArray*, std::map<std::string, std::string>&);
+mxArray* createProtocolVersion(const Ice::ProtocolVersion&);
+void getProtocolVersion(mxArray*, Ice::ProtocolVersion&);
+mxArray* createEncodingVersion(const Ice::EncodingVersion&);
+void getEncodingVersion(mxArray*, Ice::EncodingVersion&);
+mxArray* convertException(const std::exception&);
+mxArray* createResultValue(mxArray*);
+mxArray* createResultException(mxArray*);
+mxArray* createStringList(const std::vector<std::string>&);
+void getStringList(mxArray*, std::vector<std::string>&);
+
+std::string idToClass(const std::string&);
+
+}
diff --git a/matlab/src/IceMatlab/icematlab.h b/matlab/src/IceMatlab/icematlab.h
new file mode 100644
index 00000000000..5226c61bd41
--- /dev/null
+++ b/matlab/src/IceMatlab/icematlab.h
@@ -0,0 +1,280 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2017 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#ifdef _WIN32
+#ifdef EXPORT_FCNS
+#define EXPORTED_FUNCTION __declspec(dllexport)
+#else
+#define EXPORTED_FUNCTION __declspec(dllimport)
+#endif
+#else
+#define EXPORTED_FUNCTION
+#endif
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+typedef struct mxArray_tag mxArray; // Forward declaration to avoid importing mex.h here
+
+EXPORTED_FUNCTION mxArray* Ice_initialize(mxArray*, void*, void**);
+EXPORTED_FUNCTION mxArray* Ice_stringToIdentity(mxArray*);
+EXPORTED_FUNCTION mxArray* Ice_identityToString(mxArray*);
+
+EXPORTED_FUNCTION mxArray* Ice_Communicator__release(void*);
+EXPORTED_FUNCTION mxArray* Ice_Communicator_stringToProxy(void*, const char*, void**);
+EXPORTED_FUNCTION mxArray* Ice_Communicator_getProperties(void*, void**);
+EXPORTED_FUNCTION mxArray* Ice_Communicator_createOutputStream(void*, mxArray*, void**);
+EXPORTED_FUNCTION mxArray* Ice_Communicator_destroy(void*);
+
+typedef enum
+{
+ Normal,
+ Nonmutating,
+ Idempotent
+} Ice_OperationMode;
+
+typedef enum
+{
+ Random,
+ Ordered
+} Ice_EndpointSelectionType;
+
+EXPORTED_FUNCTION mxArray* Ice_ObjectPrx__release(void*);
+EXPORTED_FUNCTION mxArray* Ice_ObjectPrx_equals(void*, void*, unsigned char*);
+EXPORTED_FUNCTION mxArray* Ice_ObjectPrx_ice_createOutputStream(void*, void**);
+EXPORTED_FUNCTION mxArray* Ice_ObjectPrx_ice_invoke(void*, const char*, Ice_OperationMode, void*, mxArray*,
+ unsigned char*, void**);
+EXPORTED_FUNCTION mxArray* Ice_ObjectPrx_ice_invokeNC(void*, const char*, Ice_OperationMode, void*, unsigned char*,
+ void**);
+EXPORTED_FUNCTION mxArray* Ice_ObjectPrx_ice_invokeAsync(void*, const char*, Ice_OperationMode, void*, mxArray*,
+ void**);
+EXPORTED_FUNCTION mxArray* Ice_ObjectPrx_ice_invokeAsyncNC(void*, const char*, Ice_OperationMode, void*, void**);
+EXPORTED_FUNCTION mxArray* Ice_ObjectPrx_ice_toString(void*);
+EXPORTED_FUNCTION mxArray* Ice_ObjectPrx_ice_getCommunicator(void*, void**);
+EXPORTED_FUNCTION mxArray* Ice_ObjectPrx_ice_getIdentity(void*);
+EXPORTED_FUNCTION mxArray* Ice_ObjectPrx_ice_identity(void*, mxArray*, void**);
+EXPORTED_FUNCTION mxArray* Ice_ObjectPrx_ice_getContext(void*);
+EXPORTED_FUNCTION mxArray* Ice_ObjectPrx_ice_context(void*, mxArray*, void**);
+EXPORTED_FUNCTION mxArray* Ice_ObjectPrx_ice_getFacet(void*);
+EXPORTED_FUNCTION mxArray* Ice_ObjectPrx_ice_facet(void*, const char*, void**);
+EXPORTED_FUNCTION mxArray* Ice_ObjectPrx_ice_getAdapterId(void*);
+EXPORTED_FUNCTION mxArray* Ice_ObjectPrx_ice_adapterId(void*, const char*, void**);
+EXPORTED_FUNCTION mxArray* Ice_ObjectPrx_ice_getEndpoints(void*);
+EXPORTED_FUNCTION mxArray* Ice_ObjectPrx_ice_endpoints(void*, mxArray*, void**);
+EXPORTED_FUNCTION mxArray* Ice_ObjectPrx_ice_getLocatorCacheTimeout(void*, int*);
+EXPORTED_FUNCTION mxArray* Ice_ObjectPrx_ice_locatorCacheTimeout(void*, int, void**);
+EXPORTED_FUNCTION mxArray* Ice_ObjectPrx_ice_getInvocationTimeout(void*, int*);
+EXPORTED_FUNCTION mxArray* Ice_ObjectPrx_ice_invocationTimeout(void*, int, void**);
+EXPORTED_FUNCTION mxArray* Ice_ObjectPrx_ice_getConnectionId(void*);
+EXPORTED_FUNCTION mxArray* Ice_ObjectPrx_ice_connectionId(void*, const char*, void**);
+EXPORTED_FUNCTION mxArray* Ice_ObjectPrx_ice_isConnectionCached(void*, unsigned char*);
+EXPORTED_FUNCTION mxArray* Ice_ObjectPrx_ice_connectionCached(void*, unsigned char, void**);
+EXPORTED_FUNCTION mxArray* Ice_ObjectPrx_ice_getEndpointSelection(void*, Ice_EndpointSelectionType*);
+EXPORTED_FUNCTION mxArray* Ice_ObjectPrx_ice_endpointSelection(void*, Ice_EndpointSelectionType, void**);
+EXPORTED_FUNCTION mxArray* Ice_ObjectPrx_ice_getEncodingVersion(void*);
+EXPORTED_FUNCTION mxArray* Ice_ObjectPrx_ice_encodingVersion(void*, mxArray*, void**);
+EXPORTED_FUNCTION mxArray* Ice_ObjectPrx_ice_getRouter(void*, void**);
+EXPORTED_FUNCTION mxArray* Ice_ObjectPrx_ice_router(void*, void*, void**);
+EXPORTED_FUNCTION mxArray* Ice_ObjectPrx_ice_getLocator(void*, void**);
+EXPORTED_FUNCTION mxArray* Ice_ObjectPrx_ice_locator(void*, void*, void**);
+EXPORTED_FUNCTION mxArray* Ice_ObjectPrx_ice_isSecure(void*, unsigned char*);
+EXPORTED_FUNCTION mxArray* Ice_ObjectPrx_ice_secure(void*, unsigned char, void**);
+EXPORTED_FUNCTION mxArray* Ice_ObjectPrx_ice_isPreferSecure(void*, unsigned char*);
+EXPORTED_FUNCTION mxArray* Ice_ObjectPrx_ice_preferSecure(void*, unsigned char, void**);
+EXPORTED_FUNCTION mxArray* Ice_ObjectPrx_ice_isTwoway(void*, unsigned char*);
+EXPORTED_FUNCTION mxArray* Ice_ObjectPrx_ice_twoway(void*, void**);
+EXPORTED_FUNCTION mxArray* Ice_ObjectPrx_ice_isOneway(void*, unsigned char*);
+EXPORTED_FUNCTION mxArray* Ice_ObjectPrx_ice_oneway(void*, void**);
+EXPORTED_FUNCTION mxArray* Ice_ObjectPrx_ice_isBatchOneway(void*, unsigned char*);
+EXPORTED_FUNCTION mxArray* Ice_ObjectPrx_ice_batchOneway(void*, void**);
+EXPORTED_FUNCTION mxArray* Ice_ObjectPrx_ice_isDatagram(void*, unsigned char*);
+EXPORTED_FUNCTION mxArray* Ice_ObjectPrx_ice_datagram(void*, void**);
+EXPORTED_FUNCTION mxArray* Ice_ObjectPrx_ice_compress(void*, unsigned char, void**);
+EXPORTED_FUNCTION mxArray* Ice_ObjectPrx_ice_timeout(void*, int, void**);
+EXPORTED_FUNCTION mxArray* Ice_ObjectPrx_ice_getConnection(void*, void**);
+EXPORTED_FUNCTION mxArray* Ice_ObjectPrx_ice_getConnectionAsync(void*, void**);
+EXPORTED_FUNCTION mxArray* Ice_ObjectPrx_ice_getCachedConnection(void*, void**);
+EXPORTED_FUNCTION mxArray* Ice_ObjectPrx_ice_flushBatchRequests(void*);
+EXPORTED_FUNCTION mxArray* Ice_ObjectPrx_ice_flushBatchRequestsAsync(void*, void**);
+EXPORTED_FUNCTION mxArray* Ice_ObjectPrx_clone(void*, void**);
+
+EXPORTED_FUNCTION mxArray* Ice_InvocationFuture__release(void*);
+EXPORTED_FUNCTION mxArray* Ice_InvocationFuture_id(void*, unsigned long long*);
+EXPORTED_FUNCTION mxArray* Ice_InvocationFuture_wait(void*, unsigned char*);
+EXPORTED_FUNCTION mxArray* Ice_InvocationFuture_stream(void*, unsigned char*, void**);
+EXPORTED_FUNCTION mxArray* Ice_InvocationFuture_state(void*);
+EXPORTED_FUNCTION mxArray* Ice_InvocationFuture_cancel(void*);
+EXPORTED_FUNCTION mxArray* Ice_InvocationFuture_check(void*);
+
+EXPORTED_FUNCTION mxArray* Ice_GetConnectionFuture__release(void*);
+EXPORTED_FUNCTION mxArray* Ice_GetConnectionFuture_id(void*, unsigned long long*);
+EXPORTED_FUNCTION mxArray* Ice_GetConnectionFuture_wait(void*, unsigned char*);
+EXPORTED_FUNCTION mxArray* Ice_GetConnectionFuture_fetch(void*, void**);
+EXPORTED_FUNCTION mxArray* Ice_GetConnectionFuture_state(void*);
+EXPORTED_FUNCTION mxArray* Ice_GetConnectionFuture_cancel(void*);
+
+EXPORTED_FUNCTION mxArray* Ice_SentFuture__release(void*);
+EXPORTED_FUNCTION mxArray* Ice_SentFuture_id(void*, unsigned long long*);
+EXPORTED_FUNCTION mxArray* Ice_SentFuture_wait(void*, unsigned char*);
+EXPORTED_FUNCTION mxArray* Ice_SentFuture_state(void*);
+EXPORTED_FUNCTION mxArray* Ice_SentFuture_cancel(void*);
+EXPORTED_FUNCTION mxArray* Ice_SentFuture_check(void*);
+
+typedef enum
+{
+ DefaultFormat,
+ CompactFormat,
+ SlicedFormat
+} Ice_FormatType;
+
+typedef enum
+{
+ OptionalFormatF1 = 0,
+ OptionalFormatF2 = 1,
+ OptionalFormatF4 = 2,
+ OptionalFormatF8 = 3,
+ OptionalFormatSize = 4,
+ OptionalFormatVSize = 5,
+ OptionalFormatFSize = 6,
+ OptionalFormatClass = 7
+} Ice_OptionalFormat;
+
+EXPORTED_FUNCTION mxArray* Ice_OutputStream__release(void*);
+EXPORTED_FUNCTION mxArray* Ice_OutputStream_writeBool(void*, unsigned char);
+EXPORTED_FUNCTION mxArray* Ice_OutputStream_writeBoolOpt(void*, int, unsigned char);
+EXPORTED_FUNCTION mxArray* Ice_OutputStream_writeBoolSeq(void*, const unsigned char*, int);
+EXPORTED_FUNCTION mxArray* Ice_OutputStream_writeBoolSeqOpt(void*, int, const unsigned char*, int);
+EXPORTED_FUNCTION mxArray* Ice_OutputStream_writeByte(void*, unsigned char);
+EXPORTED_FUNCTION mxArray* Ice_OutputStream_writeByteOpt(void*, int, unsigned char);
+EXPORTED_FUNCTION mxArray* Ice_OutputStream_writeByteSeq(void*, const unsigned char*, int);
+EXPORTED_FUNCTION mxArray* Ice_OutputStream_writeByteSeqOpt(void*, int, const unsigned char*, int);
+EXPORTED_FUNCTION mxArray* Ice_OutputStream_writeShort(void*, short);
+EXPORTED_FUNCTION mxArray* Ice_OutputStream_writeShortOpt(void*, int, short);
+EXPORTED_FUNCTION mxArray* Ice_OutputStream_writeShortSeq(void*, const short*, int);
+EXPORTED_FUNCTION mxArray* Ice_OutputStream_writeShortSeqOpt(void*, int, const short*, int);
+EXPORTED_FUNCTION mxArray* Ice_OutputStream_writeInt(void*, int);
+EXPORTED_FUNCTION mxArray* Ice_OutputStream_writeIntOpt(void*, int, int);
+EXPORTED_FUNCTION mxArray* Ice_OutputStream_writeIntSeq(void*, const int*, int);
+EXPORTED_FUNCTION mxArray* Ice_OutputStream_writeIntSeqOpt(void*, int, const int*, int);
+EXPORTED_FUNCTION mxArray* Ice_OutputStream_writeLong(void*, long long);
+EXPORTED_FUNCTION mxArray* Ice_OutputStream_writeLongOpt(void*, int, long long);
+EXPORTED_FUNCTION mxArray* Ice_OutputStream_writeLongSeq(void*, const long long*, int);
+EXPORTED_FUNCTION mxArray* Ice_OutputStream_writeLongSeqOpt(void*, int, const long long*, int);
+EXPORTED_FUNCTION mxArray* Ice_OutputStream_writeFloat(void*, float);
+EXPORTED_FUNCTION mxArray* Ice_OutputStream_writeFloatOpt(void*, int, float);
+EXPORTED_FUNCTION mxArray* Ice_OutputStream_writeFloatSeq(void*, const float*, int);
+EXPORTED_FUNCTION mxArray* Ice_OutputStream_writeFloatSeqOpt(void*, int, const float*, int);
+EXPORTED_FUNCTION mxArray* Ice_OutputStream_writeDouble(void*, double);
+EXPORTED_FUNCTION mxArray* Ice_OutputStream_writeDoubleOpt(void*, int, double);
+EXPORTED_FUNCTION mxArray* Ice_OutputStream_writeDoubleSeq(void*, const double*, int);
+EXPORTED_FUNCTION mxArray* Ice_OutputStream_writeDoubleSeqOpt(void*, int, const double*, int);
+EXPORTED_FUNCTION mxArray* Ice_OutputStream_writeString(void*, mxArray*);
+EXPORTED_FUNCTION mxArray* Ice_OutputStream_writeStringOpt(void*, int, mxArray*);
+EXPORTED_FUNCTION mxArray* Ice_OutputStream_writeStringSeq(void*, mxArray*);
+EXPORTED_FUNCTION mxArray* Ice_OutputStream_writeStringSeqOpt(void*, int, mxArray*);
+EXPORTED_FUNCTION mxArray* Ice_OutputStream_writeSize(void*, int);
+EXPORTED_FUNCTION mxArray* Ice_OutputStream_writeProxy(void*, void*);
+EXPORTED_FUNCTION mxArray* Ice_OutputStream_writeProxyOpt(void*, int, void*);
+EXPORTED_FUNCTION mxArray* Ice_OutputStream_writeEnum(void*, int, int);
+EXPORTED_FUNCTION mxArray* Ice_OutputStream_startEncapsulation(void*);
+EXPORTED_FUNCTION mxArray* Ice_OutputStream_startEncapsulationWithFormat(void*, Ice_FormatType);
+EXPORTED_FUNCTION mxArray* Ice_OutputStream_endEncapsulation(void*);
+EXPORTED_FUNCTION mxArray* Ice_OutputStream_startSlice(void*, const char*, int, unsigned char);
+EXPORTED_FUNCTION mxArray* Ice_OutputStream_endSlice(void*);
+EXPORTED_FUNCTION mxArray* Ice_OutputStream_writeOptional(void*, int, Ice_OptionalFormat, unsigned char*);
+EXPORTED_FUNCTION mxArray* Ice_OutputStream_startSize(void*, unsigned int*);
+EXPORTED_FUNCTION mxArray* Ice_OutputStream_endSize(void*, unsigned int);
+
+EXPORTED_FUNCTION mxArray* Ice_InputStream__release(void*);
+EXPORTED_FUNCTION mxArray* Ice_InputStream_readBool(void*, unsigned char*);
+EXPORTED_FUNCTION mxArray* Ice_InputStream_readBoolSeq(void*);
+EXPORTED_FUNCTION mxArray* Ice_InputStream_readBoolOpt(void*, int);
+EXPORTED_FUNCTION mxArray* Ice_InputStream_readBoolSeqOpt(void*, int);
+EXPORTED_FUNCTION mxArray* Ice_InputStream_readByte(void*, unsigned char*);
+EXPORTED_FUNCTION mxArray* Ice_InputStream_readByteSeq(void*);
+EXPORTED_FUNCTION mxArray* Ice_InputStream_readByteOpt(void*, int);
+EXPORTED_FUNCTION mxArray* Ice_InputStream_readByteSeqOpt(void*, int);
+EXPORTED_FUNCTION mxArray* Ice_InputStream_readShort(void*, short*);
+EXPORTED_FUNCTION mxArray* Ice_InputStream_readShortSeq(void*);
+EXPORTED_FUNCTION mxArray* Ice_InputStream_readShortOpt(void*, int);
+EXPORTED_FUNCTION mxArray* Ice_InputStream_readShortSeqOpt(void*, int);
+EXPORTED_FUNCTION mxArray* Ice_InputStream_readInt(void*, int*);
+EXPORTED_FUNCTION mxArray* Ice_InputStream_readIntSeq(void*);
+EXPORTED_FUNCTION mxArray* Ice_InputStream_readIntOpt(void*, int);
+EXPORTED_FUNCTION mxArray* Ice_InputStream_readIntSeqOpt(void*, int);
+EXPORTED_FUNCTION mxArray* Ice_InputStream_readLong(void*, long long*);
+EXPORTED_FUNCTION mxArray* Ice_InputStream_readLongSeq(void*);
+EXPORTED_FUNCTION mxArray* Ice_InputStream_readLongOpt(void*, int);
+EXPORTED_FUNCTION mxArray* Ice_InputStream_readLongSeqOpt(void*, int);
+EXPORTED_FUNCTION mxArray* Ice_InputStream_readFloat(void*, float*);
+EXPORTED_FUNCTION mxArray* Ice_InputStream_readFloatSeq(void*);
+EXPORTED_FUNCTION mxArray* Ice_InputStream_readFloatOpt(void*, int);
+EXPORTED_FUNCTION mxArray* Ice_InputStream_readFloatSeqOpt(void*, int);
+EXPORTED_FUNCTION mxArray* Ice_InputStream_readDouble(void*, double*);
+EXPORTED_FUNCTION mxArray* Ice_InputStream_readDoubleSeq(void*);
+EXPORTED_FUNCTION mxArray* Ice_InputStream_readDoubleOpt(void*, int);
+EXPORTED_FUNCTION mxArray* Ice_InputStream_readDoubleSeqOpt(void*, int);
+EXPORTED_FUNCTION mxArray* Ice_InputStream_readString(void*);
+EXPORTED_FUNCTION mxArray* Ice_InputStream_readStringSeq(void*);
+EXPORTED_FUNCTION mxArray* Ice_InputStream_readStringOpt(void*, int);
+EXPORTED_FUNCTION mxArray* Ice_InputStream_readStringSeqOpt(void*, int);
+EXPORTED_FUNCTION mxArray* Ice_InputStream_skip(void*, int);
+EXPORTED_FUNCTION mxArray* Ice_InputStream_startException(void*);
+EXPORTED_FUNCTION mxArray* Ice_InputStream_endException(void*);
+EXPORTED_FUNCTION mxArray* Ice_InputStream_startEncapsulation(void*);
+EXPORTED_FUNCTION mxArray* Ice_InputStream_endEncapsulation(void*);
+EXPORTED_FUNCTION mxArray* Ice_InputStream_skipEmptyEncapsulation(void*);
+EXPORTED_FUNCTION mxArray* Ice_InputStream_skipEncapsulation(void*);
+EXPORTED_FUNCTION mxArray* Ice_InputStream_getEncoding(void*);
+EXPORTED_FUNCTION mxArray* Ice_InputStream_startSlice(void*);
+EXPORTED_FUNCTION mxArray* Ice_InputStream_endSlice(void*);
+EXPORTED_FUNCTION mxArray* Ice_InputStream_skipSlice(void*);
+EXPORTED_FUNCTION mxArray* Ice_InputStream_readSize(void*, int*);
+EXPORTED_FUNCTION mxArray* Ice_InputStream_readOptional(void*, int, Ice_OptionalFormat, unsigned char*);
+EXPORTED_FUNCTION mxArray* Ice_InputStream_readProxy(void*, void**);
+EXPORTED_FUNCTION mxArray* Ice_InputStream_readProxyOpt(void*, int, void**);
+EXPORTED_FUNCTION mxArray* Ice_InputStream_readEnum(void*, int, int*);
+EXPORTED_FUNCTION mxArray* Ice_InputStream_throwException(void*, mxArray*);
+
+EXPORTED_FUNCTION mxArray* Ice_createProperties(mxArray*, void*, void**);
+EXPORTED_FUNCTION mxArray* Ice_Properties__release(void*);
+EXPORTED_FUNCTION mxArray* Ice_Properties_getProperty(void*, const char*);
+EXPORTED_FUNCTION mxArray* Ice_Properties_getPropertyWithDefault(void*, const char*, const char*);
+EXPORTED_FUNCTION mxArray* Ice_Properties_getPropertyAsInt(void*, const char*, int*);
+EXPORTED_FUNCTION mxArray* Ice_Properties_getPropertyAsIntWithDefault(void*, const char*, int, int*);
+EXPORTED_FUNCTION mxArray* Ice_Properties_getPropertyAsList(void*, const char*);
+EXPORTED_FUNCTION mxArray* Ice_Properties_getPropertyAsListWithDefault(void*, const char*, mxArray*);
+EXPORTED_FUNCTION mxArray* Ice_Properties_getPropertiesForPrefix(void*, const char*);
+EXPORTED_FUNCTION mxArray* Ice_Properties_setProperty(void*, const char*, const char*);
+EXPORTED_FUNCTION mxArray* Ice_Properties_getCommandLineOptions(void*);
+EXPORTED_FUNCTION mxArray* Ice_Properties_parseCommandLineOptions(void*, const char*, mxArray*);
+EXPORTED_FUNCTION mxArray* Ice_Properties_parseIceCommandLineOptions(void*, mxArray*);
+EXPORTED_FUNCTION mxArray* Ice_Properties_load(void*, const char*);
+EXPORTED_FUNCTION mxArray* Ice_Properties_clone(void*, void**);
+
+EXPORTED_FUNCTION mxArray* Ice_Connection__release(void*);
+EXPORTED_FUNCTION mxArray* Ice_Connection_close(void*, mxArray*);
+EXPORTED_FUNCTION mxArray* Ice_Connection_createProxy(void*, mxArray*, void**);
+EXPORTED_FUNCTION mxArray* Ice_Connection_flushBatchRequests(void*, mxArray*);
+EXPORTED_FUNCTION mxArray* Ice_Connection_flushBatchRequestsAsync(void*, mxArray*, void**);
+EXPORTED_FUNCTION mxArray* Ice_Connection_heartbeat(void*);
+EXPORTED_FUNCTION mxArray* Ice_Connection_heartbeatAsync(void*, void**);
+EXPORTED_FUNCTION mxArray* Ice_Connection_setACM(void*, mxArray*, mxArray*, mxArray*);
+EXPORTED_FUNCTION mxArray* Ice_Connection_getACM(void*);
+EXPORTED_FUNCTION mxArray* Ice_Connection_type(void*);
+EXPORTED_FUNCTION mxArray* Ice_Connection_timeout(void*, int*);
+EXPORTED_FUNCTION mxArray* Ice_Connection_toString(void*);
+EXPORTED_FUNCTION mxArray* Ice_Connection_setBufferSize(void*, int, int);
+EXPORTED_FUNCTION mxArray* Ice_Connection_throwException(void*);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/matlab/test/Ice/operations/AllTests.m b/matlab/test/Ice/operations/AllTests.m
new file mode 100644
index 00000000000..294c4ac6b23
--- /dev/null
+++ b/matlab/test/Ice/operations/AllTests.m
@@ -0,0 +1,53 @@
+%{
+**********************************************************************
+
+Copyright (c) 2003-2017 ZeroC, Inc. All rights reserved.
+
+This copy of Ice is licensed to you under the terms described in the
+ICE_LICENSE file included in this distribution.
+
+**********************************************************************
+%}
+
+classdef AllTests
+ methods(Static)
+ function r = allTests(app)
+ communicator = app.communicator();
+ ref = ['test:', app.getTestEndpoint(0, '')];
+ base = communicator.stringToProxy(ref);
+ cl = Test.MyClassPrx.checkedCast(base);
+ derived = Test.MyDerivedClassPrx.checkedCast(cl);
+
+ fprintf('testing twoway operations... ');
+ Twoways.twoways(app, cl);
+ Twoways.twoways(app, derived);
+ derived.opDerived();
+ fprintf('ok\n');
+
+ fprintf('testing oneway operations... ');
+ Oneways.oneways(app, cl);
+ fprintf('ok\n');
+
+ fprintf('testing twoway operations with AMI... ');
+ TwowaysAMI.twowaysAMI(app, cl);
+ TwowaysAMI.twowaysAMI(app, derived);
+ fprintf('ok\n');
+
+ fprintf('testing oneway operations with AMI... ');
+ OnewaysAMI.onewaysAMI(app, cl);
+ fprintf('ok\n');
+
+ fprintf('testing batch oneway operations... ');
+ BatchOneways.batchOneways(app, cl);
+ BatchOneways.batchOneways(app, derived);
+ fprintf('ok\n');
+
+ fprintf('testing batch AMI oneway operations... ');
+ BatchOnewaysAMI.batchOneways(app, cl);
+ BatchOnewaysAMI.batchOneways(app, derived);
+ fprintf('ok\n');
+
+ r = cl;
+ end
+ end
+end
diff --git a/matlab/test/Ice/operations/Application.m b/matlab/test/Ice/operations/Application.m
new file mode 100644
index 00000000000..9ffff601346
--- /dev/null
+++ b/matlab/test/Ice/operations/Application.m
@@ -0,0 +1,157 @@
+%{
+**********************************************************************
+
+Copyright (c) 2003-2017 ZeroC, Inc. All rights reserved.
+
+This copy of Ice is licensed to you under the terms described in the
+ICE_LICENSE file included in this distribution.
+
+**********************************************************************
+%}
+
+classdef (Abstract) Application < handle
+ methods(Sealed)
+ %
+ % main() initializes the Communicator, calls run(), and destroys
+ % the Communicator upon return from run(). It thereby handles
+ % all exceptions properly, i.e., error messages are printed
+ % if exceptions propagate to main(), and the Communicator is
+ % always destroyed, regardless of exceptions.
+ %
+ function r = main(obj, appName, varargin)
+ if ~isempty(obj.communicator_)
+ printf('%s: only one instance of the Application class can be used', appName);
+ r = 1;
+ return;
+ end
+
+ obj.testName_ = appName;
+
+ args = {};
+ initializationData = [];
+
+ if length(varargin) >= 1
+ args = varargin{1};
+ end
+ if length(varargin) >= 2
+ initializationData = varargin{2};
+ end
+
+ %
+ % We parse the properties here to extract Ice.ProgramName.
+ %
+ if isempty(initializationData)
+ [initializationData, args] = obj.getInitData(args);
+ end
+
+ if ~isempty(initializationData)
+ initData = initializationData.clone();
+ else
+ initData = Ice.InitializationData();
+ end
+
+ [initData.properties_, args] = Ice.createProperties(args, initData.properties_);
+
+ %TBD
+ % If the process logger is the default logger, we replace it with a
+ % a logger that uses the program name as the prefix.
+ %
+ %if(Util.getProcessLogger() instanceof LoggerI)
+ %{
+ % Util.setProcessLogger(new LoggerI(initData.properties_.getProperty('Ice.ProgramName'), ''));
+ %}
+
+ status = 0;
+
+ try
+ [communicator, args] = Ice.initialize(args, initData);
+ obj.communicator_ = communicator;
+
+ status = obj.run(args);
+ catch ex
+ fprintf('%s: caught %s', obj.testName_, ex.identifier);
+ disp(getReport(ex,'extended'));
+ status = 1;
+ end
+ obj.communicator_.destroy();
+ obj.communicator_ = [];
+
+ r = status;
+ end
+ function r = initialize(obj, varargin)
+ assert(length(varargin) <= 1);
+ if length(varargin) == 0
+ r = Ice.initialize();
+ else
+ r = Ice.initialize(varargin{1});
+ end
+ end
+ function setLogger(obj, logger)
+ obj.logger_ = logger;
+ end
+ function r = appName(obj)
+ r = obj.testName_;
+ end
+ function r = communicator(obj)
+ r = obj.communicator_;
+ end
+ function r = createInitializationData(obj)
+ initData = Ice.InitializationData();
+ initData.logger = obj.logger_;
+ r = initData;
+ end
+ function r = getTestEndpoint(obj, num, prot)
+ r = Application.getTestEndpointWithProperties(obj.communicator_.getProperties(), num, prot);
+ end
+ function r = getTestHost(obj)
+ r = Application.getTestHostWithProperties(obj.communicator_.getProperties());
+ end
+ function r = getTestProtocol(obj)
+ r = Application.getTestProtocolWithProperties(obj.communicator_.getProperties());
+ end
+ function r = getTestPort(obj, num)
+ r = Application.getTestPortWithProperties(obj.communicator_.getProperties(), num);
+ end
+ end
+ methods(Static)
+ function r = getTestEndpointWithProperties(props, num, prot)
+ protocol = prot;
+ if length(protocol) == 0
+ protocol = props.getPropertyWithDefault('Ice.Default.Protocol', 'default');
+ end
+
+ basePort = props.getPropertyAsIntWithDefault('Test.BasePort', 12010);
+
+ r = sprintf('%s -p %d', protocol, basePort + num);
+ end
+ function r = getTestHostWithProperties(props)
+ r = props.getPropertyWithDefault('Ice.Default.Host', '127.0.0.1');
+ end
+ function r = getTestProtocolWithProperties(props)
+ r = props.getPropertyWithDefault('Ice.Default.Protocol', 'tcp');
+ end
+ function r = getTestPortWithProperties(props, num)
+ r = props.getPropertyAsIntWithDefault('Test.BasePort', 12010) + num;
+ end
+ end
+ methods(Abstract)
+ r = run(obj, args)
+ end
+ methods(Access=protected)
+ %
+ % Hook to override the initialization data. This hook is
+ % necessary because some properties must be set prior to
+ % communicator initialization.
+ %
+ function [initData, remArgs] = getInitData(obj, args)
+ initData = obj.createInitializationData();
+ [initData.properties_, remArgs] = Ice.createProperties(args);
+ remArgs = initData.properties_.parseCommandLineOptions('Test', remArgs);
+ end
+ end
+ properties(Access=private)
+ testName_
+ communicator_
+ logger_
+ end
+end
diff --git a/matlab/test/Ice/operations/BatchOneways.m b/matlab/test/Ice/operations/BatchOneways.m
new file mode 100644
index 00000000000..83e9843ce4c
--- /dev/null
+++ b/matlab/test/Ice/operations/BatchOneways.m
@@ -0,0 +1,114 @@
+%{
+**********************************************************************
+
+Copyright (c) 2003-2017 ZeroC, Inc. All rights reserved.
+
+This copy of Ice is licensed to you under the terms described in the
+ICE_LICENSE file included in this distribution.
+
+**********************************************************************
+%}
+
+classdef BatchOneways
+ methods(Static)
+ function batchOneways(app, p)
+ communicator = app.communicator();
+ properties = communicator.getProperties();
+ bs1 = zeros(1, 10 * 1024);
+
+ batch = p.ice_batchOneway();
+ batch.ice_flushBatchRequests(); % Empty flush
+
+ if ~isempty(batch.ice_getConnection())
+ batch.ice_getConnection().flushBatchRequests(Ice.CompressBatch.BasedOnProxy);
+ end
+ %communicator.flushBatchRequests(com.zeroc.Ice.CompressBatch.BasedOnProxy);
+
+ p.opByteSOnewayCallCount(); % Reset the call count
+
+ for i = 1:30
+ try
+ batch.opByteSOneway(bs1);
+ catch ex
+ if isa(ex, 'Ice.MemoryLimitException')
+ assert(false);
+ else
+ rethrow(ex);
+ end
+ end
+ end
+
+ count = 0;
+ while count < 27 % 3 * 9 requests auto-flushed.
+ count = count + p.opByteSOnewayCallCount();
+ pause(0.1);
+ end
+
+ if ~isempty(batch.ice_getConnection())
+ batch1 = p.ice_batchOneway();
+ batch2 = p.ice_batchOneway();
+
+ batch1.ice_ping();
+ batch2.ice_ping();
+ batch1.ice_flushBatchRequests();
+ batch1.ice_getConnection().close(Ice.ConnectionClose.GracefullyWithWait);
+ batch1.ice_ping();
+ batch2.ice_ping();
+
+ batch1.ice_getConnection();
+ batch2.ice_getConnection();
+
+ batch1.ice_ping();
+ batch1.ice_getConnection().close(Ice.ConnectionClose.GracefullyWithWait);
+ batch1.ice_ping();
+ batch2.ice_ping();
+ end
+
+ identity = Ice.Identity();
+ identity.name = "invalid";
+ batch3 = batch.ice_identity(identity);
+ batch3.ice_ping();
+ batch3.ice_flushBatchRequests();
+
+ % Make sure that a bogus batch request doesn't cause troubles to other ones.
+ batch3.ice_ping();
+ batch.ice_ping();
+ batch.ice_flushBatchRequests();
+ batch.ice_ping();
+
+ p.ice_ping();
+ if ~isempty(p.ice_getConnection()) && isempty(properties.getProperty('Ice.Override.Compress'))
+ prx = p.ice_getConnection().createProxy(p.ice_getIdentity()).ice_batchOneway();
+
+ batchC1 = Test.MyClassPrx.uncheckedCast(prx.ice_compress(false));
+ batchC2 = Test.MyClassPrx.uncheckedCast(prx.ice_compress(true));
+ batchC3 = Test.MyClassPrx.uncheckedCast(prx.ice_identity(identity));
+
+ batchC1.opByteSOneway(bs1);
+ batchC1.opByteSOneway(bs1);
+ batchC1.opByteSOneway(bs1);
+ batchC1.ice_getConnection().flushBatchRequests(Ice.CompressBatch.Yes);
+
+ batchC2.opByteSOneway(bs1);
+ batchC2.opByteSOneway(bs1);
+ batchC2.opByteSOneway(bs1);
+ batchC1.ice_getConnection().flushBatchRequests(Ice.CompressBatch.No);
+
+ batchC1.opByteSOneway(bs1);
+ batchC1.opByteSOneway(bs1);
+ batchC1.opByteSOneway(bs1);
+ batchC1.ice_getConnection().flushBatchRequests(Ice.CompressBatch.BasedOnProxy);
+
+ batchC1.opByteSOneway(bs1);
+ batchC2.opByteSOneway(bs1);
+ batchC1.opByteSOneway(bs1);
+ batchC1.ice_getConnection().flushBatchRequests(Ice.CompressBatch.BasedOnProxy);
+
+ batchC1.opByteSOneway(bs1);
+ batchC3.opByteSOneway(bs1);
+ batchC1.opByteSOneway(bs1);
+ batchC1.ice_getConnection().flushBatchRequests(Ice.CompressBatch.BasedOnProxy);
+ end
+ end
+ end
+end
diff --git a/matlab/test/Ice/operations/BatchOnewaysAMI.m b/matlab/test/Ice/operations/BatchOnewaysAMI.m
new file mode 100644
index 00000000000..85720f5285b
--- /dev/null
+++ b/matlab/test/Ice/operations/BatchOnewaysAMI.m
@@ -0,0 +1,70 @@
+%{
+**********************************************************************
+
+Copyright (c) 2003-2017 ZeroC, Inc. All rights reserved.
+
+This copy of Ice is licensed to you under the terms described in the
+ICE_LICENSE file included in this distribution.
+
+**********************************************************************
+%}
+
+classdef BatchOnewaysAMI
+ methods(Static)
+ function batchOneways(app, p)
+ communicator = app.communicator();
+ properties = communicator.getProperties();
+ bs1 = zeros(1, 10 * 1024);
+
+ batch = p.ice_batchOneway();
+ future = batch.ice_flushBatchRequestsAsync(); % Empty flush
+ future.wait();
+ assert(strcmp(future.State, 'finished'));
+
+ futures = {};
+ for i = 1:30
+ futures{i} = batch.opByteSOnewayAsync(bs1);
+ end
+ for i = 1:30
+ assert(futures{i}.wait());
+ end
+
+ count = 0;
+ while count < 27 % 3 * 9 requests auto-flushed.
+ count = count + p.opByteSOnewayCallCount();
+ pause(0.1);
+ end
+
+ if ~isempty(batch.ice_getConnection())
+ batch2 = p.ice_batchOneway();
+
+ batch.ice_pingAsync();
+ batch2.ice_pingAsync();
+ assert(batch.ice_flushBatchRequestsAsync().wait());
+ batch.ice_getConnection().close(Ice.ConnectionClose.GracefullyWithWait);
+ batch.ice_pingAsync();
+ batch2.ice_pingAsync();
+
+ batch.ice_getConnection();
+ batch2.ice_getConnection();
+
+ batch.ice_pingAsync();
+ batch.ice_getConnection().close(Ice.ConnectionClose.GracefullyWithWait);
+ assert(batch.ice_pingAsync().wait());
+ assert(batch2.ice_pingAsync().wait());
+ end
+
+ identity = Ice.Identity();
+ identity.name = 'invalid';
+ batch3 = batch.ice_identity(identity);
+ batch3.ice_pingAsync();
+ assert(batch3.ice_flushBatchRequestsAsync().wait());
+
+ % Make sure that a bogus batch request doesn't cause troubles to other ones.
+ batch3.ice_pingAsync();
+ batch.ice_pingAsync();
+ assert(batch.ice_flushBatchRequestsAsync().wait());
+ batch.ice_pingAsync();
+ end
+ end
+end
diff --git a/matlab/test/Ice/operations/Client.m b/matlab/test/Ice/operations/Client.m
new file mode 100644
index 00000000000..79e1771d502
--- /dev/null
+++ b/matlab/test/Ice/operations/Client.m
@@ -0,0 +1,52 @@
+%{
+**********************************************************************
+
+Copyright (c) 2003-2017 ZeroC, Inc. All rights reserved.
+
+This copy of Ice is licensed to you under the terms described in the
+ICE_LICENSE file included in this distribution.
+
+**********************************************************************
+%}
+
+classdef Client < Application
+ methods
+ function r = run(obj, args)
+ myClass = AllTests.allTests(obj);
+
+ fprintf('testing server shutdown... ');
+ myClass.shutdown();
+ try
+ myClass.ice_timeout(100).ice_ping(); % Use timeout to speed up testing on Windows
+ throw(MException());
+ catch ex
+ if isa(ex, 'Ice.LocalException')
+ fprintf('ok\n');
+ else
+ rethrow(ex);
+ end
+ end
+
+ r = 0;
+ end
+ end
+ methods(Access=protected)
+ function [r, remArgs] = getInitData(obj, args)
+ [initData, remArgs] = getInitData@Application(obj, args);
+ initData.properties_.setProperty('Ice.ThreadPool.Client.Size', '2');
+ initData.properties_.setProperty('Ice.ThreadPool.Client.SizeWarn', '0');
+ initData.properties_.setProperty('Ice.BatchAutoFlushSize', '100');
+ r = initData;
+ end
+ end
+ methods(Static)
+ function start(args)
+ addpath('generated');
+ if ~libisloaded('icematlab')
+ loadlibrary('icematlab')
+ end
+ c = Client();
+ status = c.main('Client', args);
+ end
+ end
+end
diff --git a/matlab/test/Ice/operations/Oneways.m b/matlab/test/Ice/operations/Oneways.m
new file mode 100644
index 00000000000..d6b00720b87
--- /dev/null
+++ b/matlab/test/Ice/operations/Oneways.m
@@ -0,0 +1,33 @@
+%{
+**********************************************************************
+
+Copyright (c) 2003-2017 ZeroC, Inc. All rights reserved.
+
+This copy of Ice is licensed to you under the terms described in the
+ICE_LICENSE file included in this distribution.
+
+**********************************************************************
+%}
+
+classdef Oneways
+ methods(Static)
+ function oneways(app, p)
+ p = p.ice_oneway();
+
+ p.ice_ping();
+
+ p.opVoid();
+
+ p.opIdempotent();
+
+ p.opNonmutating();
+
+ try
+ p.opByte(hex2dec('ff'), hex2dec('0f'));
+ assert(false);
+ catch ex
+ assert(isa(ex, 'Ice.TwowayOnlyException'));
+ end
+ end
+ end
+end
diff --git a/matlab/test/Ice/operations/OnewaysAMI.m b/matlab/test/Ice/operations/OnewaysAMI.m
new file mode 100644
index 00000000000..bb5dc3ee223
--- /dev/null
+++ b/matlab/test/Ice/operations/OnewaysAMI.m
@@ -0,0 +1,63 @@
+%{
+**********************************************************************
+
+Copyright (c) 2003-2017 ZeroC, Inc. All rights reserved.
+
+This copy of Ice is licensed to you under the terms described in the
+ICE_LICENSE file included in this distribution.
+
+**********************************************************************
+%}
+
+classdef OnewaysAMI
+ methods(Static)
+ function onewaysAMI(app, p)
+ p = p.ice_oneway();
+
+ call(p, 'ice_ping');
+
+ try
+ p.ice_isAAsync(Test.MyClassPrx.ice_staticId());
+ catch ex
+ assert(isa(ex, 'Ice.TwowayOnlyException'));
+ end
+
+ try
+ p.ice_idAsync();
+ catch ex
+ assert(isa(ex, 'Ice.TwowayOnlyException'));
+ end
+
+ try
+ p.ice_idsAsync();
+ catch ex
+ assert(isa(ex, 'Ice.TwowayOnlyException'));
+ end
+
+ call(p, 'opVoid');
+
+ call(p, 'opIdempotent');
+
+ call(p, 'opNonmutating');
+
+ try
+ p.opByteAsync(hex2dec('ff'), hex2dec('0f'));
+ catch ex
+ assert(isa(ex, 'Ice.TwowayOnlyException'));
+ end
+ end
+ end
+end
+
+function varargout = call(p, op, varargin)
+ try
+ name = [op, 'Async'];
+ future = p.(name)(varargin{:});
+ assert(strcmp(future.Operation, op));
+ assert(future.wait());
+ assert(strcmp(future.State, 'finished'));
+ catch ex
+ disp(getReport(ex, 'extended'));
+ assert(false);
+ end
+end
diff --git a/matlab/test/Ice/operations/Test.ice b/matlab/test/Ice/operations/Test.ice
new file mode 100644
index 00000000000..4ae52d91ca9
--- /dev/null
+++ b/matlab/test/Ice/operations/Test.ice
@@ -0,0 +1,377 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2017 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#pragma once
+
+#include <Ice/Current.ice>
+
+module Test
+{
+
+enum MyEnum
+{
+ enum1,
+ enum2,
+ enum3
+}
+
+interface MyClass;
+
+struct AnotherStruct
+{
+ string s;
+}
+
+struct Structure
+{
+ MyClass* p;
+ MyEnum e;
+ AnotherStruct s;
+}
+
+sequence<byte> ByteS;
+sequence<bool> BoolS;
+sequence<short> ShortS;
+sequence<int> IntS;
+sequence<long> LongS;
+sequence<float> FloatS;
+sequence<double> DoubleS;
+sequence<string> StringS;
+sequence<MyEnum> MyEnumS;
+sequence<MyClass*> MyClassS;
+
+sequence<ByteS> ByteSS;
+sequence<BoolS> BoolSS;
+sequence<ShortS> ShortSS;
+sequence<IntS> IntSS;
+sequence<LongS> LongSS;
+sequence<FloatS> FloatSS;
+sequence<DoubleS> DoubleSS;
+sequence<StringS> StringSS;
+sequence<MyEnumS> MyEnumSS;
+sequence<MyClassS> MyClassSS;
+
+sequence<StringSS> StringSSS;
+
+struct MyStruct
+{
+ int i;
+ int j;
+}
+
+dictionary<byte, bool> ByteBoolD;
+dictionary<short, int> ShortIntD;
+dictionary<long, float> LongFloatD;
+dictionary<string, string> StringStringD;
+dictionary<string, MyEnum> StringMyEnumD;
+dictionary<MyEnum, string> MyEnumStringD;
+dictionary<MyStruct, MyEnum> MyStructMyEnumD;
+
+sequence<ByteBoolD> ByteBoolDS;
+sequence<ShortIntD> ShortIntDS;
+sequence<LongFloatD> LongFloatDS;
+sequence<StringStringD> StringStringDS;
+sequence<StringMyEnumD> StringMyEnumDS;
+sequence<MyEnumStringD> MyEnumStringDS;
+sequence<MyStructMyEnumD> MyStructMyEnumDS;
+
+dictionary<byte, ByteS> ByteByteSD;
+dictionary<bool, BoolS> BoolBoolSD;
+dictionary<short, ShortS> ShortShortSD;
+dictionary<int, IntS> IntIntSD;
+dictionary<long, LongS> LongLongSD;
+dictionary<string, FloatS> StringFloatSD;
+dictionary<string, DoubleS> StringDoubleSD;
+dictionary<string, StringS> StringStringSD;
+dictionary<MyEnum, MyEnumS> MyEnumMyEnumSD;
+
+exception SomeException {}
+
+interface MyClass
+{
+ void shutdown();
+
+ void opVoid();
+
+ byte opByte(byte p1, byte p2,
+ out byte p3);
+
+ bool opBool(bool p1, bool p2,
+ out bool p3);
+
+ long opShortIntLong(short p1, int p2, long p3,
+ out short p4, out int p5, out long p6);
+
+ double opFloatDouble(float p1, double p2,
+ out float p3, out double p4);
+
+ string opString(string p1, string p2,
+ out string p3);
+
+ MyEnum opMyEnum(MyEnum p1, out MyEnum p2);
+
+ MyClass* opMyClass(MyClass* p1, out MyClass* p2, out MyClass* p3);
+
+ Structure opStruct(Structure p1, Structure p2,
+ out Structure p3);
+
+ ByteS opByteS(ByteS p1, ByteS p2,
+ out ByteS p3);
+
+ BoolS opBoolS(BoolS p1, BoolS p2,
+ out BoolS p3);
+
+ LongS opShortIntLongS(Test::ShortS p1, IntS p2, LongS p3,
+ out ::Test::ShortS p4, out IntS p5, out LongS p6);
+
+ DoubleS opFloatDoubleS(FloatS p1, DoubleS p2,
+ out FloatS p3, out DoubleS p4);
+
+ StringS opStringS(StringS p1, StringS p2,
+ out StringS p3);
+
+ ByteSS opByteSS(ByteSS p1, ByteSS p2,
+ out ByteSS p3);
+
+ BoolSS opBoolSS(BoolSS p1, BoolSS p2,
+ out BoolSS p3);
+
+ LongSS opShortIntLongSS(ShortSS p1, IntSS p2, LongSS p3,
+ out ShortSS p4, out IntSS p5, out LongSS p6);
+
+ DoubleSS opFloatDoubleSS(FloatSS p1, DoubleSS p2,
+ out FloatSS p3, out DoubleSS p4);
+
+ StringSS opStringSS(StringSS p1, StringSS p2,
+ out StringSS p3);
+
+ StringSSS opStringSSS(StringSSS p1, StringSSS p2,
+ out StringSSS p3);
+
+ ByteBoolD opByteBoolD(ByteBoolD p1, ByteBoolD p2,
+ out ByteBoolD p3);
+
+ ShortIntD opShortIntD(ShortIntD p1, ShortIntD p2,
+ out ShortIntD p3);
+
+ LongFloatD opLongFloatD(LongFloatD p1, LongFloatD p2,
+ out LongFloatD p3);
+
+ StringStringD opStringStringD(StringStringD p1, StringStringD p2,
+ out StringStringD p3);
+
+ StringMyEnumD opStringMyEnumD(StringMyEnumD p1, StringMyEnumD p2,
+ out StringMyEnumD p3);
+
+ MyEnumStringD opMyEnumStringD(MyEnumStringD p1, MyEnumStringD p2,
+ out MyEnumStringD p3);
+
+ MyStructMyEnumD opMyStructMyEnumD(MyStructMyEnumD p1, MyStructMyEnumD p2,
+ out MyStructMyEnumD p3);
+
+ ByteBoolDS opByteBoolDS(ByteBoolDS p1, ByteBoolDS p2,
+ out ByteBoolDS p3);
+
+ ShortIntDS opShortIntDS(ShortIntDS p1, ShortIntDS p2,
+ out ShortIntDS p3);
+
+ LongFloatDS opLongFloatDS(LongFloatDS p1, LongFloatDS p2,
+ out LongFloatDS p3);
+
+ StringStringDS opStringStringDS(StringStringDS p1, StringStringDS p2,
+ out StringStringDS p3);
+
+ StringMyEnumDS opStringMyEnumDS(StringMyEnumDS p1, StringMyEnumDS p2,
+ out StringMyEnumDS p3);
+
+ MyEnumStringDS opMyEnumStringDS(MyEnumStringDS p1, MyEnumStringDS p2,
+ out MyEnumStringDS p3);
+
+ MyStructMyEnumDS opMyStructMyEnumDS(MyStructMyEnumDS p1, MyStructMyEnumDS p2,
+ out MyStructMyEnumDS p3);
+
+ ByteByteSD opByteByteSD(ByteByteSD p1, ByteByteSD p2,
+ out ByteByteSD p3);
+
+ BoolBoolSD opBoolBoolSD(BoolBoolSD p1, BoolBoolSD p2,
+ out BoolBoolSD p3);
+
+ ShortShortSD opShortShortSD(ShortShortSD p1, ShortShortSD p2,
+ out ShortShortSD p3);
+
+ IntIntSD opIntIntSD(IntIntSD p1, IntIntSD p2,
+ out IntIntSD p3);
+
+ LongLongSD opLongLongSD(LongLongSD p1, LongLongSD p2,
+ out LongLongSD p3);
+
+ StringFloatSD opStringFloatSD(StringFloatSD p1, StringFloatSD p2,
+ out StringFloatSD p3);
+
+ StringDoubleSD opStringDoubleSD(StringDoubleSD p1, StringDoubleSD p2,
+ out StringDoubleSD p3);
+
+ StringStringSD opStringStringSD(StringStringSD p1, StringStringSD p2,
+ out StringStringSD p3);
+
+ MyEnumMyEnumSD opMyEnumMyEnumSD(MyEnumMyEnumSD p1, MyEnumMyEnumSD p2,
+ out MyEnumMyEnumSD p3);
+
+ IntS opIntS(IntS s);
+
+ void opByteSOneway(ByteS s);
+
+ int opByteSOnewayCallCount();
+
+ Ice::Context opContext();
+
+ void opDoubleMarshaling(double p1, DoubleS p2);
+
+ idempotent void opIdempotent();
+
+ ["nonmutating"] idempotent void opNonmutating();
+
+ byte opByte1(byte opByte1);
+ short opShort1(short opShort1);
+ int opInt1(int opInt1);
+ long opLong1(long opLong1);
+ float opFloat1(float opFloat1);
+ double opDouble1(double opDouble1);
+ string opString1(string opString1);
+ StringS opStringS1(StringS opStringS1);
+ ByteBoolD opByteBoolD1(ByteBoolD opByteBoolD1);
+ StringS opStringS2(StringS stringS);
+ ByteBoolD opByteBoolD2(ByteBoolD byteBoolD);
+
+ StringS opStringLiterals();
+
+ ["marshaled-result"] Structure opMStruct1();
+ ["marshaled-result"] Structure opMStruct2(Structure p1, out Structure p2);
+
+ ["marshaled-result"] StringS opMSeq1();
+ ["marshaled-result"] StringS opMSeq2(StringS p1, out StringS p2);
+
+ ["marshaled-result"] StringStringD opMDict1();
+ ["marshaled-result"] StringStringD opMDict2(StringStringD p1, out StringStringD p2);
+}
+
+struct MyStruct1
+{
+ string tesT; // Same name as the enclosing module
+ MyClass* myClass; // Same name as an already defined class
+ string myStruct1; // Same name as the enclosing struct
+}
+
+class MyClass1
+{
+ string tesT; // Same name as the enclosing module
+ MyClass* myClass; // Same name as an already defined class
+ string myClass1; // Same name as the enclosing class
+}
+
+interface MyDerivedClass extends MyClass
+{
+ void opDerived();
+ MyClass1 opMyClass1(MyClass1 opMyClass1);
+ MyStruct1 opMyStruct1(MyStruct1 opMyStruct1);
+}
+
+//
+// String literals
+//
+
+const string s0 = "\u005c"; // backslash
+const string s1 = "\u0041"; // A
+const string s2 = "\u0049\u0063\u0065"; // Ice
+const string s3 = "\u004121"; // A21
+const string s4 = "\\u0041 \\U00000041"; // \\u0041 \\U00000041
+const string s5 = "\u00FF"; // ÿ
+const string s6 = "\u03FF"; // GREEK CAPITAL REVERSED DOTTED LUNATE SIGMA SYMBOL (U+03FF)
+const string s7 = "\u05F0"; // HEBREW LIGATURE YIDDISH DOUBLE VAV (U+05F0)
+const string s8 = "\U00010000"; // LINEAR B SYLLABLE B008 A (U+10000)
+const string s9 = "\U0001F34C"; // BANANA (U+1F34C)
+const string s10 = "\u0DA7"; // Sinhala Letter Alpapraana Ttayanna
+const string s11 = "\xE2\x82\xac\342\202\254\342\x82\254"; // 3 euro signs (U+20AC) in UTF-8
+const string s12 = "\x5C101"; // \101 (not an octal escape)
+const string s13 = "\U0001F34C0123"; // \xd83c\xdf4c\060\061\062\063
+const string s14 = "\U0001F34Cabcd"; // \xd83c\xdf4c\141bcd
+const string s15 = "\U0001F34CABCD"; // \xd83c\xdf4c\141BCD
+const string s16 = "\x7fabcd"; // \177abcd
+const string s17 = "\x7fABCD"; // \177ABCD
+const string s18 = "\x011238"; // \001\061\062\0638
+const string s19 = "abc\x011238\x08abcd"; // abc\001\061\062\0638\babcd
+
+const string sw0 = "\U0000005c"; // backslash
+const string sw1 = "\U00000041"; // A
+const string sw2 = "\U00000049\U00000063\U00000065"; // Ice
+const string sw3 = "\U0000004121"; // A21
+const string sw4 = "\\u0041 \\U00000041"; // \\u0041 \\U00000041
+const string sw5 = "\U000000FF"; // ÿ
+const string sw6 = "\U000003FF"; // GREEK CAPITAL REVERSED DOTTED LUNATE SIGMA SYMBOL (U+03FF)
+const string sw7 = "\U000005F0"; // HEBREW LIGATURE YIDDISH DOUBLE VAV (U+05F0)
+const string sw8 = "\U00010000"; // LINEAR B SYLLABLE B008 A (U+10000)
+const string sw9 = "\U0001F34C"; // BANANA (U+1F34C)
+const string sw10 = "\U00000DA7"; // Sinhala Letter Alpapraana Ttayanna
+
+/**
+\' single quote byte 0x27 in ASCII encoding
+\" double quote byte 0x22 in ASCII encoding
+\? question mark byte 0x3f in ASCII encoding
+\\ backslash byte 0x5c in ASCII encoding
+\a audible bell byte 0x07 in ASCII encoding
+\b backspace byte 0x08 in ASCII encoding
+\f form feed - new page byte 0x0c in ASCII encoding
+\n line feed - new line byte 0x0a in ASCII encoding
+\r carriage return byte 0x0d in ASCII encoding
+\t horizontal tab byte 0x09 in ASCII encoding
+\v vertical tab byte 0x0b in ASCII encoding
+**/
+
+const string ss0 = "\'\"\?\\\a\b\f\n\r\t\v\6";
+const string ss1 = "\u0027\u0022\u003f\u005c\u0007\u0008\u000c\u000a\u000d\u0009\u000b\u0006";
+const string ss2 = "\U00000027\U00000022\U0000003f\U0000005c\U00000007\U00000008\U0000000c\U0000000a\U0000000d\U00000009\U0000000b\U00000006";
+
+const string ss3 = "\\\\U\\u\\"; /* \\U\u\ */
+const string ss4 = "\\\u0041\\"; /* \A\ */
+const string ss5 = "\\u0041\\"; /* \u0041\ */
+
+//
+// Ĩ - Unicode Character 'LATIN CAPITAL LETTER I WITH TILDE' (U+0128)
+// Ÿ - Unicode Character 'LATIN CAPITAL LETTER Y WITH DIAERESIS' (U+0178)
+// ÿ - Unicode Character 'LATIN SMALL LETTER Y WITH DIAERESIS' (U+00FF)
+// Ā - Unicode Character 'LATIN CAPITAL LETTER A WITH MACRON' (U+0100)
+// ἀ - Unicode Character 'GREEK SMALL LETTER ALPHA WITH PSILI' (U+1F00)
+// 𐆔 - Unicode Character 'ROMAN DIMIDIA SEXTULA SIGN' (U+10194)
+// 𐅪 - Unicode Character 'GREEK ACROPHONIC THESPIAN ONE HUNDRED' (U+1016A)
+// 𐆘 - Unicode Character 'ROMAN SESTERTIUS SIGN' (U+10198)
+// 🍀 - Unicode Character 'FOUR LEAF CLOVER' (U+1F340)
+// 🍁 - Unicode Character 'MAPLE LEAF' (U+1F341)
+// 🍂 - Unicode Character 'FALLEN LEAF' (U+1F342)
+// 🍃 - Unicode Character 'LEAF FLUTTERING IN WIND' (U+1F343)
+//
+const string su0 = "ĨŸÿĀἀ𐆔𐅪𐆘🍀🍁🍂🍃";
+const string su1 = "\u0128\u0178\u00FF\u0100\u1F00\U00010194\U0001016A\U00010198\U0001F340\U0001F341\U0001F342\U0001F343";
+const string su2 = "\U00000128\U00000178\U000000FF\U00000100\U00001F00\U00010194\U0001016A\U00010198\U0001F340\U0001F341\U0001F342\U0001F343";
+
+}
+
+module Test2
+{
+
+/**
+ *
+ * Makes sure that proxy operations are correctly generated when extending an interface from
+ * a different module (ICE-7639).
+ *
+ **/
+interface MyDerivedClass extends Test::MyClass
+{
+}
+
+}
diff --git a/matlab/test/Ice/operations/Twoways.m b/matlab/test/Ice/operations/Twoways.m
new file mode 100644
index 00000000000..a10439c4d23
--- /dev/null
+++ b/matlab/test/Ice/operations/Twoways.m
@@ -0,0 +1,1407 @@
+%{
+**********************************************************************
+
+Copyright (c) 2003-2017 ZeroC, Inc. All rights reserved.
+
+This copy of Ice is licensed to you under the terms described in the
+ICE_LICENSE file included in this distribution.
+
+**********************************************************************
+%}
+
+classdef Twoways
+ methods(Static)
+ function twoways(app, p)
+ communicator = app.communicator();
+
+ literals = p.opStringLiterals();
+
+ assert(strcmp(Test.s0.value, sprintf('\\')) && ...
+ strcmp(Test.s0.value, Test.sw0.value) && ...
+ strcmp(Test.s0.value, literals{1}) && ...
+ strcmp(Test.s0.value, literals{12}));
+
+ assert(strcmp(Test.s1.value, sprintf('A')) && ...
+ strcmp(Test.s1.value, Test.sw1.value) && ...
+ strcmp(Test.s1.value, literals{2}) && ...
+ strcmp(Test.s1.value, literals{13}));
+
+ assert(strcmp(Test.s2.value, sprintf('Ice')) && ...
+ strcmp(Test.s2.value, Test.sw2.value) && ...
+ strcmp(Test.s2.value, literals{3}) && ...
+ strcmp(Test.s2.value, literals{14}));
+
+ assert(strcmp(Test.s3.value, sprintf('A21')) && ...
+ strcmp(Test.s3.value, Test.sw3.value) && ...
+ strcmp(Test.s3.value, literals{4}) && ...
+ strcmp(Test.s3.value, literals{15}));
+
+ assert(strcmp(Test.s4.value, sprintf('\\u0041 \\U00000041')) && ...
+ strcmp(Test.s4.value, Test.sw4.value) && ...
+ strcmp(Test.s4.value, literals{5}) && ...
+ strcmp(Test.s4.value, literals{16}));
+
+ assert(strcmp(Test.s5.value, sprintf('\x00FF')) && ...
+ strcmp(Test.s5.value, Test.sw5.value) && ...
+ strcmp(Test.s5.value, literals{6}) && ...
+ strcmp(Test.s5.value, literals{17}));
+
+ assert(strcmp(Test.s6.value, sprintf('\x03FF')) && ...
+ strcmp(Test.s6.value, Test.sw6.value) && ...
+ strcmp(Test.s6.value, literals{7}) && ...
+ strcmp(Test.s6.value, literals{18}));
+
+ assert(strcmp(Test.s7.value, sprintf('\x05F0')) && ...
+ strcmp(Test.s7.value, Test.sw7.value) && ...
+ strcmp(Test.s7.value, literals{8}) && ...
+ strcmp(Test.s7.value, literals{19}));
+
+ assert(strcmp(Test.s8.value, sprintf('\xD800\xDC00')) && ...
+ strcmp(Test.s8.value, Test.sw8.value) && ...
+ strcmp(Test.s8.value, literals{9}) && ...
+ strcmp(Test.s8.value, literals{20}));
+
+ assert(strcmp(Test.s9.value, sprintf('\xD83C\xDF4C')) && ...
+ strcmp(Test.s9.value, Test.sw9.value) && ...
+ strcmp(Test.s9.value, literals{10}) && ...
+ strcmp(Test.s9.value, literals{21}));
+
+ assert(strcmp(Test.s10.value, sprintf('\x0DA7')) && ...
+ strcmp(Test.s10.value, Test.sw10.value) && ...
+ strcmp(Test.s10.value, literals{11}) && ...
+ strcmp(Test.s10.value, literals{22}));
+
+ assert(strcmp(Test.s11.value, sprintf('\x20ac\x20ac\x20ac')));
+
+ assert(strcmp(Test.s12.value, sprintf('\\101')));
+
+ assert(strcmp(Test.s13.value, sprintf('\xd83c\xdf4c\060\061\062\063')));
+
+ assert(strcmp(Test.s14.value, sprintf('\xd83c\xdf4c\141bcd')));
+
+ assert(strcmp(Test.s15.value, sprintf('\xd83c\xdf4c\101BCD')));
+
+ assert(strcmp(Test.s16.value, sprintf('\177abcd')));
+
+ assert(strcmp(Test.s17.value, sprintf('\177ABCD')));
+
+ assert(strcmp(Test.s18.value, sprintf('\001\061\062\0638')));
+
+ assert(strcmp(Test.s19.value, sprintf('abc\001\061\062\0638\babcd')));
+
+ assert(strcmp(Test.ss0.value, sprintf('''"\x003f\\\x0007\b\f\n\r\t\x000b\6')) && ...
+ strcmp(Test.ss0.value, Test.ss1.value) && ...
+ strcmp(Test.ss0.value, Test.ss2.value) && ...
+ strcmp(Test.ss0.value, literals{23}) && ...
+ strcmp(Test.ss0.value, literals{24}) && ...
+ strcmp(Test.ss0.value, literals{25}));
+
+ assert(strcmp(Test.ss3.value, sprintf('\\\\U\\u\\')) && ...
+ strcmp(Test.ss3.value, literals{26}));
+
+ assert(strcmp(Test.ss4.value, sprintf('\\A\\')) && ...
+ strcmp(Test.ss4.value, literals{27}));
+
+ assert(strcmp(Test.ss5.value, sprintf('\\u0041\\')) && ...
+ strcmp(Test.ss5.value, literals{28}));
+
+ assert(strcmp(Test.su0.value, Test.su1.value) && ...
+ strcmp(Test.su0.value, Test.su2.value) && ...
+ strcmp(Test.su0.value, literals{29}) && ...
+ strcmp(Test.su0.value, literals{30}) && ...
+ strcmp(Test.su0.value, literals{31}));
+
+ p.ice_ping();
+
+ assert(p.ice_isA(Test.MyClassPrx.ice_staticId()));
+
+ assert(strcmp(p.ice_id(), Test.MyDerivedClassPrx.ice_staticId()));
+
+ ids = p.ice_ids();
+ assert(length(ids) == 3);
+ assert(strcmp(ids{1}, '::Ice::Object'));
+ assert(strcmp(ids{2}, '::Test::MyClass'));
+ assert(strcmp(ids{3}, '::Test::MyDerivedClass'));
+
+ p.opVoid();
+
+ [r, p3] = p.opByte(hex2dec('ff'), hex2dec('0f'));
+ assert(p3 == hex2dec('f0'));
+ assert(r == hex2dec('ff'));
+
+ [r, p3] = p.opBool(true, false);
+ assert(p3);
+ assert(~r);
+
+ [r, p4, p5, p6] = p.opShortIntLong(10, 11, 12);
+ assert(p4 == 10);
+ assert(p5 == 11);
+ assert(p6 == 12);
+ assert(r == 12);
+
+ [r, p4, p5, p6] = p.opShortIntLong(intmin('int16'), intmin('int32'), intmin('int64'));
+ assert(p4 == intmin('int16'));
+ assert(p5 == intmin('int32'));
+ assert(p6 == intmin('int64'));
+ assert(r == intmin('int64'));
+
+ [r, p4, p5, p6] = p.opShortIntLong(intmax('int16'), intmax('int32'), intmax('int64'));
+ assert(p4 == intmax('int16'));
+ assert(p5 == intmax('int32'));
+ assert(p6 == intmax('int64'));
+ assert(r == intmax('int64'));
+
+ [r, p3, p4] = p.opFloatDouble(3.14, 1.1E10);
+ assert(p3 == single(3.14));
+ assert(p4 == 1.1E10);
+ assert(r == 1.1E10);
+
+ [r, p3, p4] = p.opFloatDouble(realmin('single'), realmin('double'));
+ assert(p3 == realmin('single'));
+ assert(p4 == realmin('double'));
+ assert(r == realmin('double'));
+
+ [r, p3, p4] = p.opFloatDouble(realmax('single'), realmax('double'));
+ assert(p3 == realmax('single'));
+ assert(p4 == realmax('double'));
+ assert(r == realmax('double'));
+
+ [r, p3] = p.opString('hello', 'world');
+ assert(strcmp(p3, 'world hello'));
+ assert(strcmp(r, 'hello world'));
+
+ [r, p2] = p.opMyEnum(Test.MyEnum.enum2);
+ assert(p2 == Test.MyEnum.enum2);
+ assert(r == Test.MyEnum.enum3);
+
+ %
+ % Test marshalling of null enum (first enum value is
+ % marshalled in this case).
+ %
+ [r, p2] = p.opMyEnum([]);
+ assert(p2 == Test.MyEnum.enum1);
+ assert(r == Test.MyEnum.enum3);
+
+ [r, p2, p3] = p.opMyClass(p);
+ assert(Ice.proxyIdentityAndFacetCompare(p2, p) == 0);
+ assert(Ice.proxyIdentityAndFacetCompare(p3, p) ~= 0);
+ assert(Ice.proxyIdentityAndFacetCompare(r, p) == 0);
+ assert(isequal(p2.ice_getIdentity(), Ice.stringToIdentity('test')));
+ assert(isequal(p3.ice_getIdentity(), Ice.stringToIdentity('noSuchIdentity')));
+ assert(isequal(r.ice_getIdentity(), Ice.stringToIdentity('test')));
+ r.opVoid();
+ p2.opVoid();
+ try
+ p3.opVoid();
+ assert(false);
+ catch ex
+ assert(isa(ex, 'Ice.ObjectNotExistException'));
+ end
+
+ [r, p2, p3] = p.opMyClass([]);
+ assert(isempty(p2));
+ assert(~isempty(p3));
+ assert(Ice.proxyIdentityAndFacetCompare(r, p) == 0);
+ r.opVoid();
+
+ si1 = Test.Structure();
+ si1.p = p;
+ si1.e = Test.MyEnum.enum3;
+ si1.s = Test.AnotherStruct();
+ si1.s.s = 'abc';
+ si2 = Test.Structure();
+ si2.p = [];
+ si2.e = Test.MyEnum.enum2;
+ si2.s = Test.AnotherStruct();
+ si2.s.s = 'def';
+
+ [r, p3] = p.opStruct(si1, si2);
+ assert(isempty(r.p));
+ assert(r.e == Test.MyEnum.enum2);
+ assert(strcmp(r.s.s, 'def'));
+ assert(p3.p == p);
+ assert(p3.e == Test.MyEnum.enum3);
+ assert(strcmp(p3.s.s, 'a new string'));
+ p3.p.opVoid();
+
+ %
+ % Test marshalling of null structs and structs with default member values.
+ %
+ si1 = Test.Structure();
+ si2 = [];
+
+ [r, p3] = p.opStruct(si1, si2);
+ assert(isempty(r.p));
+ assert(r.e == Test.MyEnum.enum1);
+ assert(isempty(r.s.s));
+ assert(isempty(p3.p));
+ assert(p3.e == Test.MyEnum.enum1);
+ assert(strcmp(p3.s.s, 'a new string'));
+
+ bsi1 = ...
+ [ ...
+ hex2dec('01'), ...
+ hex2dec('11'), ...
+ hex2dec('12'), ...
+ hex2dec('22') ...
+ ];
+ bsi2 = ...
+ [
+ hex2dec('f1'), ...
+ hex2dec('f2'), ...
+ hex2dec('f3'), ...
+ hex2dec('f4') ...
+ ];
+
+ [r, p3] = p.opByteS(bsi1, bsi2);
+ assert(length(p3) == 4);
+ assert(p3(1) == hex2dec('22'));
+ assert(p3(2) == hex2dec('12'));
+ assert(p3(3) == hex2dec('11'));
+ assert(p3(4) == hex2dec('01'));
+ assert(length(r) == 8);
+ assert(r(1) == hex2dec('01'));
+ assert(r(2) == hex2dec('11'));
+ assert(r(3) == hex2dec('12'));
+ assert(r(4) == hex2dec('22'));
+ assert(r(5) == hex2dec('f1'));
+ assert(r(6) == hex2dec('f2'));
+ assert(r(7) == hex2dec('f3'));
+ assert(r(8) == hex2dec('f4'));
+
+ bsi1 = [true, true, false];
+ bsi2 = [false];
+
+ [r, p3] = p.opBoolS(bsi1, bsi2);
+ assert(length(p3) == 4);
+ assert(p3(1));
+ assert(p3(2));
+ assert(~p3(3));
+ assert(~p3(4));
+ assert(length(r) == 3);
+ assert(~r(1));
+ assert(r(2));
+ assert(r(3));
+
+ ssi = [1, 2, 3];
+ isi = [5, 6, 7, 8];
+ lsi = [10, 30, 20];
+
+ [r, p4, p5, p6] = p.opShortIntLongS(ssi, isi, lsi);
+ assert(length(p4) == 3);
+ assert(p4(1) == 1);
+ assert(p4(2) == 2);
+ assert(p4(3) == 3);
+ assert(length(p5) == 4);
+ assert(p5(1) == 8);
+ assert(p5(2) == 7);
+ assert(p5(3) == 6);
+ assert(p5(4) == 5);
+ assert(length(p6) == 6);
+ assert(p6(1) == 10);
+ assert(p6(2) == 30);
+ assert(p6(3) == 20);
+ assert(p6(4) == 10);
+ assert(p6(5) == 30);
+ assert(p6(6) == 20);
+ assert(length(r) == 3);
+ assert(r(1) == 10);
+ assert(r(2) == 30);
+ assert(r(3) == 20);
+
+ fsi = [3.14, 1.11];
+ dsi = [1.1E10, 1.2E10, 1.3E10];
+
+ [r, p3, p4] = p.opFloatDoubleS(fsi, dsi);
+ assert(length(p3) == 2);
+ assert(p3(1) == single(3.14));
+ assert(p3(2) == single(1.11));
+ assert(length(p4) == 3);
+ assert(p4(1) == 1.3E10);
+ assert(p4(2) == 1.2E10);
+ assert(p4(3) == 1.1E10);
+ assert(length(r) == 5);
+ assert(r(1) == 1.1E10);
+ assert(r(2) == 1.2E10);
+ assert(r(3) == 1.3E10);
+ assert(r(4) == single(3.14));
+ assert(r(5) == single(1.11));
+
+ ssi1 = {'abc', 'de', 'fghi'};
+ ssi2 = {'xyz'};
+
+ [r, p3] = p.opStringS(ssi1, ssi2);
+ assert(length(p3) == 4);
+ assert(strcmp(p3{1}, 'abc'));
+ assert(strcmp(p3{2}, 'de'));
+ assert(strcmp(p3{3}, 'fghi'));
+ assert(strcmp(p3{4}, 'xyz'));
+ assert(length(r) == 3);
+ assert(strcmp(r{1}, 'fghi'));
+ assert(strcmp(r{2}, 'de'));
+ assert(strcmp(r{3}, 'abc'));
+
+ bsi1 = ...
+ { ...
+ [hex2dec('01'), hex2dec('11'), hex2dec('12')], ...
+ [hex2dec('ff')] ...
+ };
+ bsi2 = ...
+ { ...
+ [hex2dec('0e')], ...
+ [hex2dec('f2'), hex2dec('f1')] ...
+ };
+
+ [r, p3] = p.opByteSS(bsi1, bsi2);
+ assert(length(p3) == 2);
+ assert(length(p3{1}) == 1);
+ assert(p3{1}(1) == hex2dec('ff'));
+ assert(length(p3{2}) == 3);
+ assert(p3{2}(1) == hex2dec('01'));
+ assert(p3{2}(2) == hex2dec('11'));
+ assert(p3{2}(3) == hex2dec('12'));
+ assert(length(r) == 4);
+ assert(length(r{1}) == 3);
+ assert(r{1}(1) == hex2dec('01'));
+ assert(r{1}(2) == hex2dec('11'));
+ assert(r{1}(3) == hex2dec('12'));
+ assert(length(r{2}) == 1);
+ assert(r{2}(1) == hex2dec('ff'));
+ assert(length(r{3}) == 1);
+ assert(r{3}(1) == hex2dec('0e'));
+ assert(length(r{4}) == 2);
+ assert(r{4}(1) == hex2dec('f2'));
+ assert(r{4}(2) == hex2dec('f1'));
+
+ bsi1 = ...
+ { ...
+ [true], ...
+ [false], ...
+ [true, true] ...
+ };
+
+ bsi2 = ...
+ { ...
+ [false, false, true] ...
+ };
+
+ [r, p3] = p.opBoolSS(bsi1, bsi2);
+ assert(length(p3) == 4);
+ assert(length(p3{1}) == 1);
+ assert(p3{1}(1));
+ assert(length(p3{2}) == 1);
+ assert(~p3{2}(1));
+ assert(length(p3{3}) == 2);
+ assert(p3{3}(1));
+ assert(p3{3}(2));
+ assert(length(p3{4}) == 3);
+ assert(~p3{4}(1));
+ assert(~p3{4}(2));
+ assert(p3{4}(3));
+ assert(length(r) == 3);
+ assert(length(r{1}) == 2);
+ assert(r{1}(1));
+ assert(r{1}(2));
+ assert(length(r{2}) == 1);
+ assert(~r{2}(1));
+ assert(length(r{3}) == 1);
+ assert(r{3}(1));
+
+ ssi = ...
+ { ...
+ [1, 2, 5], ...
+ [13], ...
+ [] ...
+ };
+ isi = ...
+ { ...
+ [24, 98], ...
+ [42] ...
+ };
+ lsi = ...
+ { ...
+ [496, 1729], ...
+ };
+
+ [r, p4, p5, p6] = p.opShortIntLongSS(ssi, isi, lsi);
+ assert(length(r) == 1);
+ assert(length(r{1}) == 2);
+ assert(r{1}(1) == 496);
+ assert(r{1}(2) == 1729);
+ assert(length(p4) == 3);
+ assert(length(p4{1}) == 3);
+ assert(p4{1}(1) == 1);
+ assert(p4{1}(2) == 2);
+ assert(p4{1}(3) == 5);
+ assert(length(p4{2}) == 1);
+ assert(p4{2}(1) == 13);
+ assert(length(p4{3}) == 0);
+ assert(length(p5) == 2);
+ assert(length(p5{1}) == 1);
+ assert(p5{1}(1) == 42);
+ assert(length(p5{2}) == 2);
+ assert(p5{2}(1) == 24);
+ assert(p5{2}(2) == 98);
+ assert(length(p6) == 2);
+ assert(length(p6{1}) == 2);
+ assert(p6{1}(1) == 496);
+ assert(p6{1}(2) == 1729);
+ assert(length(p6{2}) == 2);
+ assert(p6{2}(1) == 496);
+ assert(p6{2}(2) == 1729);
+
+ fsi = ...
+ { ...
+ [3.14], ...
+ [1.11], ...
+ [], ...
+ };
+ dsi = ...
+ { ...
+ [1.1E10, 1.2E10, 1.3E10] ...
+ };
+
+ [r, p3, p4] = p.opFloatDoubleSS(fsi, dsi);
+ assert(length(p3) == 3);
+ assert(length(p3{1}) == 1);
+ assert(p3{1}(1) == single(3.14));
+ assert(length(p3{2}) == 1);
+ assert(p3{2}(1) == single(1.11));
+ assert(length(p3{3}) == 0);
+ assert(length(p4) == 1);
+ assert(length(p4{1}) == 3);
+ assert(p4{1}(1) == 1.1E10);
+ assert(p4{1}(2) == 1.2E10);
+ assert(p4{1}(3) == 1.3E10);
+ assert(length(r) == 2);
+ assert(length(r{1}) == 3);
+ assert(r{1}(1) == 1.1E10);
+ assert(r{1}(2) == 1.2E10);
+ assert(r{1}(3) == 1.3E10);
+ assert(length(r{2}) == 3);
+ assert(r{2}(1) == 1.1E10);
+ assert(r{2}(2) == 1.2E10);
+ assert(r{2}(3) == 1.3E10);
+
+ ssi1 = ...
+ { ...
+ {'abc'}, ...
+ {'de', 'fghi'} ...
+ };
+ ssi2 = ...
+ { ...
+ {}, ...
+ {}, ...
+ {'xyz'} ...
+ };
+
+ [r, p3] = p.opStringSS(ssi1, ssi2);
+ assert(length(p3) == 5);
+ assert(length(p3{1}) == 1);
+ assert(strcmp(p3{1}(1), 'abc'));
+ assert(length(p3{2}) == 2);
+ assert(strcmp(p3{2}(1), 'de'));
+ assert(strcmp(p3{2}(2), 'fghi'));
+ assert(length(p3{3}) == 0);
+ assert(length(p3{4}) == 0);
+ assert(length(p3{5}) == 1);
+ assert(strcmp(p3{5}(1), 'xyz'));
+ assert(length(r) == 3);
+ assert(length(r{1}) == 1);
+ assert(strcmp(r{1}(1), 'xyz'));
+ assert(length(r{2}) == 0);
+ assert(length(r{3}) == 0);
+
+ sssi1 = ...
+ { ...
+ { ...
+ { ...
+ 'abc', 'de' ...
+ }, ...
+ { ...
+ 'xyz' ...
+ } ...
+ }, ...
+ { ...
+ { ...
+ 'hello' ...
+ } ...
+ } ...
+ };
+
+ sssi2 = ...
+ { ...
+ { ...
+ { ...
+ '', '' ...
+ }, ...
+ { ...
+ 'abcd' ...
+ } ...
+ }, ...
+ { ...
+ { ...
+ '' ...
+ } ...
+ }, ...
+ { ...
+ } ...
+ };
+
+ [r, p3] = p.opStringSSS(sssi1, sssi2);
+ assert(length(p3) == 5);
+ assert(length(p3{1}) == 2);
+ assert(length(p3{1}{1}) == 2);
+ assert(length(p3{1}{2}) == 1);
+ assert(length(p3{2}) == 1);
+ assert(length(p3{2}{1}) == 1);
+ assert(length(p3{3}) == 2);
+ assert(length(p3{3}{1}) == 2);
+ assert(length(p3{3}{2}) == 1);
+ assert(length(p3{4}) == 1);
+ assert(length(p3{4}{1}) == 1);
+ assert(length(p3{5}) == 0);
+ assert(strcmp(p3{1}{1}(1), 'abc'));
+ assert(strcmp(p3{1}{1}(2), 'de'));
+ assert(strcmp(p3{1}{2}(1), 'xyz'));
+ assert(strcmp(p3{2}{1}(1), 'hello'));
+ assert(strcmp(p3{3}{1}(1), ''));
+ assert(strcmp(p3{3}{1}(2), ''));
+ assert(strcmp(p3{3}{2}(1), 'abcd'));
+ assert(strcmp(p3{4}{1}(1), ''));
+
+ assert(length(r) == 3);
+ assert(length(r{1}) == 0);
+ assert(length(r{2}) == 1);
+ assert(length(r{2}{1}) == 1);
+ assert(length(r{3}) == 2);
+ assert(length(r{3}{1}) == 2);
+ assert(length(r{3}{2}) == 1);
+ assert(strcmp(r{2}{1}(1), ''));
+ assert(strcmp(r{3}{1}(1), ''));
+ assert(strcmp(r{3}{1}(2), ''));
+ assert(strcmp(r{3}{2}(1), 'abcd'));
+
+ di1 = Test.ByteBoolD.new();
+ di1(10) = true;
+ di1(100) = false;
+ di2 = Test.ByteBoolD.new();
+ di2(10) = true;
+ di2(11) = false;
+ di2(101) = true;
+
+ [r, p3] = p.opByteBoolD(di1, di2);
+
+ assert(isequal(p3, di1));
+ assert(r.Count == 4);
+ assert(r(10));
+ assert(~r(11));
+ assert(~r(100));
+ assert(r(101));
+
+ di1 = Test.ShortIntD.new();
+ di1(110) = -1;
+ di1(1100) = 123123;
+ di2 = Test.ShortIntD.new();
+ di2(110) = -1;
+ di2(111) = -100;
+ di2(1101) = 0;
+
+ [r, p3] = p.opShortIntD(di1, di2);
+
+ assert(isequal(p3, di1));
+ assert(r.Count == 4);
+ assert(r(110) == -1);
+ assert(r(111) == -100);
+ assert(r(1100) == 123123);
+ assert(r(1101) == 0);
+
+ di1 = Test.LongFloatD.new();
+ di1(999999110) = -1.1;
+ di1(999999111) = 123123.2;
+ di2 = Test.LongFloatD.new();
+ di2(999999110) = -1.1;
+ di2(999999120) = -100.4;
+ di2(999999130) = 0.5;
+
+ [r, p3] = p.opLongFloatD(di1, di2);
+
+ assert(isequal(p3, di1));
+ assert(r.Count == 4);
+ assert(r(999999110) == single(-1.1));
+ assert(r(999999120) == single(-100.4));
+ assert(r(999999111) == single(123123.2));
+ assert(r(999999130) == single(0.5));
+
+ di1 = Test.StringStringD.new();
+ di1('foo') = 'abc -1.1';
+ di1('bar') = 'abc 123123.2';
+ di2 = Test.StringStringD.new();
+ di2('foo') = 'abc -1.1';
+ di2('FOO') = 'abc -100.4';
+ di2('BAR') = 'abc 0.5';
+
+ [r, p3] = p.opStringStringD(di1, di2);
+
+ assert(isequal(p3, di1));
+ assert(r.Count == 4);
+ assert(strcmp(r('foo'), 'abc -1.1'));
+ assert(strcmp(r('FOO'), 'abc -100.4'));
+ assert(strcmp(r('bar'), 'abc 123123.2'));
+ assert(strcmp(r('BAR'), 'abc 0.5'));
+
+ di1 = Test.StringMyEnumD.new();
+ di1('abc') = Test.MyEnum.enum1;
+ di1('') = Test.MyEnum.enum2;
+ di2 = Test.StringMyEnumD.new();
+ di2('abc') = Test.MyEnum.enum1;
+ di2('qwerty') = Test.MyEnum.enum3;
+ di2('Hello!!') = Test.MyEnum.enum2;
+
+ [r, p3] = p.opStringMyEnumD(di1, di2);
+
+ assert(isequal(p3, di1));
+ assert(r.Count == 4);
+ assert(r('abc') == Test.MyEnum.enum1);
+ assert(r('qwerty') == Test.MyEnum.enum3);
+ assert(r('') == Test.MyEnum.enum2);
+ assert(r('Hello!!') == Test.MyEnum.enum2);
+
+ di1 = Test.MyEnumStringD.new();
+ di1(int32(Test.MyEnum.enum1)) = 'abc';
+ di2 = Test.MyEnumStringD.new();
+ di2(int32(Test.MyEnum.enum2)) = 'Hello!!';
+ di2(int32(Test.MyEnum.enum3)) = 'qwerty';
+
+ [r, p3] = p.opMyEnumStringD(di1, di2);
+
+ assert(isequal(p3, di1));
+ assert(r.Count == 3);
+ assert(strcmp(r(int32(Test.MyEnum.enum1)), 'abc'));
+ assert(strcmp(r(int32(Test.MyEnum.enum2)), 'Hello!!'));
+ assert(strcmp(r(int32(Test.MyEnum.enum3)), 'qwerty'));
+
+ s11 = Test.MyStruct(1, 1);
+ s12 = Test.MyStruct(1, 2);
+ di1 = Test.MyStructMyEnumD.new();
+ di1(1).key = s11;
+ di1(1).value = Test.MyEnum.enum1;
+ di1(2).key = s12;
+ di1(2).value = Test.MyEnum.enum2;
+
+ s22 = Test.MyStruct(2, 2);
+ s23 = Test.MyStruct(2, 3);
+ di2 = Test.MyStructMyEnumD.new();
+ di2(1).key = s11;
+ di2(1).value = Test.MyEnum.enum1;
+ di2(2).key = s22;
+ di2(2).value = Test.MyEnum.enum3;
+ di2(3).key = s23;
+ di2(3).value = Test.MyEnum.enum2;
+
+ [r, p3] = p.opMyStructMyEnumD(di1, di2);
+
+ assert(isequal(p3, di1));
+ assert(length(r) == 4);
+ for i = 1:length(r)
+ if isequal(r(i).key, s11)
+ assert(r(i).value == Test.MyEnum.enum1);
+ elseif isequal(r(i).key, s12)
+ assert(r(i).value == Test.MyEnum.enum2);
+ elseif isequal(r(i).key, s22)
+ assert(r(i).value == Test.MyEnum.enum3);
+ elseif isequal(r(i).key, s23)
+ assert(r(i).value == Test.MyEnum.enum2);
+ else
+ assert(false);
+ end
+ end
+
+ di1 = Test.ByteBoolD.new();
+ di1(10) = true;
+ di1(100) = false;
+ di2 = Test.ByteBoolD.new();
+ di2(10) = true;
+ di2(11) = false;
+ di2(101) = true;
+ di3 = Test.ByteBoolD.new();
+ di3(100) = false;
+ di3(101) = false;
+
+ dsi1 = {di1, di2};
+ dsi2 = {di3};
+
+ [r, p3] = p.opByteBoolDS(dsi1, dsi2);
+
+ assert(length(r) == 2);
+ assert(r{1}.Count == 3);
+ assert(r{1}(10));
+ assert(~r{1}(11));
+ assert(r{1}(101));
+ assert(r{2}.Count == 2);
+ assert(r{2}(10));
+ assert(~r{2}(100));
+
+ assert(length(p3) == 3);
+ assert(p3{1}.Count == 2);
+ assert(~p3{1}(100));
+ assert(~p3{1}(101));
+ assert(p3{2}.Count == 2);
+ assert(p3{2}(10));
+ assert(~p3{2}(100));
+ assert(p3{3}.Count == 3);
+ assert(p3{3}(10));
+ assert(~p3{3}(11));
+ assert(p3{3}(101));
+
+ di1 = Test.ShortIntD.new();
+ di1(110) = -1;
+ di1(1100) = 123123;
+ di2 = Test.ShortIntD.new();
+ di2(110) = -1;
+ di2(111) = -100;
+ di2(1101) = 0;
+ di3 = Test.ShortIntD.new();
+ di3(100) = -1001;
+
+ dsi1 = {di1, di2};
+ dsi2 = {di3};
+
+ [r, p3] = p.opShortIntDS(dsi1, dsi2);
+
+ assert(length(r) == 2);
+ assert(r{1}.Count == 3);
+ assert(r{1}(110) == -1);
+ assert(r{1}(111) == -100);
+ assert(r{1}(1101) == 0);
+ assert(r{2}.Count == 2);
+ assert(r{2}(110) == -1);
+ assert(r{2}(1100) == 123123);
+
+ assert(length(p3) == 3);
+ assert(p3{1}.Count == 1);
+ assert(p3{1}(100) == -1001);
+ assert(p3{2}.Count == 2);
+ assert(p3{2}(110) == -1);
+ assert(p3{2}(1100) == 123123);
+ assert(p3{3}.Count == 3);
+ assert(p3{3}(110) == -1);
+ assert(p3{3}(111) == -100);
+ assert(p3{3}(1101) == 0);
+
+ di1 = Test.LongFloatD.new();
+ di1(999999110) = -1.1;
+ di1(999999111) = 123123.2;
+ di2 = Test.LongFloatD.new();
+ di2(999999110) = -1.1;
+ di2(999999120) = -100.4;
+ di2(999999130) = 0.5;
+ di3 = Test.LongFloatD.new();
+ di3(999999140) = 3.14;
+
+ dsi1 = {di1, di2};
+ dsi2 = {di3};
+
+ [r, p3] = p.opLongFloatDS(dsi1, dsi2);
+
+ assert(length(r) == 2);
+ assert(r{1}.Count == 3);
+ assert(r{1}(999999110) == single(-1.1));
+ assert(r{1}(999999120) == single(-100.4));
+ assert(r{1}(999999130) == single(0.5));
+ assert(r{2}.Count == 2);
+ assert(r{2}(999999110) == single(-1.1));
+ assert(r{2}(999999111) == single(123123.2));
+
+ assert(length(p3) == 3);
+ assert(p3{1}.Count == 1);
+ assert(p3{1}(999999140) == single(3.14));
+ assert(p3{2}.Count == 2);
+ assert(p3{2}(999999110) == single(-1.1));
+ assert(p3{2}(999999111) == single(123123.2));
+ assert(p3{3}.Count == 3);
+ assert(p3{3}(999999110) == single(-1.1));
+ assert(p3{3}(999999120) == single(-100.4));
+ assert(p3{3}(999999130) == single(0.5));
+
+ di1 = Test.StringStringD.new();
+ di1('foo') = 'abc -1.1';
+ di1('bar') = 'abc 123123.2';
+ di2 = Test.StringStringD.new();
+ di2('foo') = 'abc -1.1';
+ di2('FOO') = 'abc -100.4';
+ di2('BAR') = 'abc 0.5';
+ di3 = Test.StringStringD.new();
+ di3('f00') = 'ABC -3.14';
+
+ dsi1 = {di1, di2};
+ dsi2 = {di3};
+
+ [r, p3] = p.opStringStringDS(dsi1, dsi2);
+
+ assert(length(r) == 2);
+ assert(r{1}.Count == 3);
+ assert(strcmp(r{1}('foo'), 'abc -1.1'));
+ assert(strcmp(r{1}('FOO'), 'abc -100.4'));
+ assert(strcmp(r{1}('BAR'), 'abc 0.5'));
+ assert(r{2}.Count == 2);
+ assert(strcmp(r{2}('foo'), 'abc -1.1'));
+ assert(strcmp(r{2}('bar'), 'abc 123123.2'));
+
+ assert(length(p3) == 3);
+ assert(p3{1}.Count == 1);
+ assert(strcmp(p3{1}('f00'), 'ABC -3.14'));
+ assert(p3{2}.Count == 2);
+ assert(strcmp(p3{2}('foo'), 'abc -1.1'));
+ assert(strcmp(p3{2}('bar'), 'abc 123123.2'));
+ assert(p3{3}.Count == 3);
+ assert(strcmp(p3{3}('foo'), 'abc -1.1'));
+ assert(strcmp(p3{3}('FOO'), 'abc -100.4'));
+ assert(strcmp(p3{3}('BAR'), 'abc 0.5'));
+
+ di1 = Test.StringMyEnumD.new();
+ di1('abc') = Test.MyEnum.enum1;
+ di1('') = Test.MyEnum.enum2;
+ di2 = Test.StringMyEnumD.new();
+ di2('abc') = Test.MyEnum.enum1;
+ di2('qwerty') = Test.MyEnum.enum3;
+ di2('Hello!!') = Test.MyEnum.enum2;
+ di3 = Test.StringMyEnumD.new();
+ di3('Goodbye') = Test.MyEnum.enum1;
+
+ dsi1 = {di1, di2};
+ dsi2 = {di3};
+
+ [r, p3] = p.opStringMyEnumDS(dsi1, dsi2);
+
+ assert(length(r) == 2);
+ assert(r{1}.Count == 3);
+ assert(r{1}('abc') == Test.MyEnum.enum1);
+ assert(r{1}('qwerty') == Test.MyEnum.enum3);
+ assert(r{1}('Hello!!') == Test.MyEnum.enum2);
+ assert(r{2}.Count == 2);
+ assert(r{2}('abc') == Test.MyEnum.enum1);
+ assert(r{2}('') == Test.MyEnum.enum2);
+
+ assert(length(p3) == 3);
+ assert(p3{1}.Count == 1);
+ assert(p3{1}('Goodbye') == Test.MyEnum.enum1);
+ assert(p3{2}.Count == 2);
+ assert(p3{2}('abc') == Test.MyEnum.enum1);
+ assert(p3{2}('') == Test.MyEnum.enum2);
+ assert(p3{3}.Count == 3);
+ assert(p3{3}('abc') == Test.MyEnum.enum1);
+ assert(p3{3}('qwerty') == Test.MyEnum.enum3);
+ assert(p3{3}('Hello!!') == Test.MyEnum.enum2);
+
+ di1 = Test.MyEnumStringD.new();
+ di1(int32(Test.MyEnum.enum1)) = 'abc';
+ di2 = Test.MyEnumStringD.new();
+ di2(int32(Test.MyEnum.enum2)) = 'Hello!!';
+ di2(int32(Test.MyEnum.enum3)) = 'qwerty';
+ di3 = Test.MyEnumStringD.new();
+ di3(int32(Test.MyEnum.enum1)) = 'Goodbye';
+
+ dsi1 = {di1, di2};
+ dsi2 = {di3};
+
+ [r, p3] = p.opMyEnumStringDS(dsi1, dsi2);
+
+ assert(length(r) == 2);
+ assert(r{1}.Count == 2);
+ assert(strcmp(r{1}(int32(Test.MyEnum.enum2)), 'Hello!!'));
+ assert(strcmp(r{1}(int32(Test.MyEnum.enum3)), 'qwerty'));
+ assert(r{2}.Count == 1);
+ assert(strcmp(r{2}(int32(Test.MyEnum.enum1)), 'abc'));
+
+ assert(length(p3) == 3);
+ assert(p3{1}.Count == 1);
+ assert(strcmp(p3{1}(int32(Test.MyEnum.enum1)), 'Goodbye'));
+ assert(p3{2}.Count == 1);
+ assert(strcmp(p3{2}(int32(Test.MyEnum.enum1)), 'abc'));
+ assert(p3{3}.Count == 2);
+ assert(strcmp(p3{3}(int32(Test.MyEnum.enum2)), 'Hello!!'));
+ assert(strcmp(p3{3}(int32(Test.MyEnum.enum3)), 'qwerty'));
+
+ s11 = Test.MyStruct(1, 1);
+ s12 = Test.MyStruct(1, 2);
+ di1 = Test.MyStructMyEnumD.new();
+ di1(1).key = s11;
+ di1(1).value = Test.MyEnum.enum1;
+ di1(2).key = s12;
+ di1(2).value = Test.MyEnum.enum2;
+
+ s22 = Test.MyStruct(2, 2);
+ s23 = Test.MyStruct(2, 3);
+ di2 = Test.MyStructMyEnumD.new();
+ di2(1).key = s11;
+ di2(1).value = Test.MyEnum.enum1;
+ di2(2).key = s22;
+ di2(2).value = Test.MyEnum.enum3;
+ di2(3).key = s23;
+ di2(3).value = Test.MyEnum.enum2;
+
+ di3 = Test.MyStructMyEnumD.new();
+ di3(1).key = s23;
+ di3(1).value = Test.MyEnum.enum2;
+
+ dsi1 = {di1, di2};
+ dsi2 = {di3};
+
+ [r, p3] = p.opMyStructMyEnumDS(dsi1, dsi2);
+
+ function checkStructDict(d)
+ for i = 1:length(d)
+ if isequal(d(i).key, s11)
+ assert(d(i).value == Test.MyEnum.enum1);
+ elseif isequal(d(i).key, s12)
+ assert(d(i).value == Test.MyEnum.enum2);
+ elseif isequal(d(i).key, s22)
+ assert(d(i).value == Test.MyEnum.enum3);
+ elseif isequal(d(i).key, s23)
+ assert(d(i).value == Test.MyEnum.enum2);
+ else
+ assert(false);
+ end
+ end
+ end
+ assert(length(r) == 2);
+ assert(length(r{1}) == 3);
+ checkStructDict(r{1});
+ checkStructDict(r{2});
+
+ assert(length(p3) == 3);
+ assert(length(p3{1}) == 1);
+ checkStructDict(p3{1});
+ assert(length(p3{2}) == 2);
+ checkStructDict(p3{2});
+ assert(length(p3{3}) == 3);
+ checkStructDict(p3{3});
+
+ sdi1 = Test.ByteByteSD.new();
+ sdi2 = Test.ByteByteSD.new();
+
+ si1 = [hex2dec('01'), hex2dec('11')];
+ si2 = [hex2dec('12')];
+ si3 = [hex2dec('f2'), hex2dec('f3')];
+
+ sdi1(hex2dec('01')) = si1;
+ sdi1(hex2dec('22')) = si2;
+ sdi2(hex2dec('f1')) = si3;
+
+ [r, p3] = p.opByteByteSD(sdi1, sdi2);
+
+ assert(p3.Count == 1);
+ a = p3(hex2dec('f1')); % Need to use a temp
+ assert(length(a) == 2);
+ assert(a(1) == hex2dec('f2'));
+ assert(a(2) == hex2dec('f3'));
+ assert(r.Count == 3);
+ a = r(hex2dec('01')); % Need to use a temp
+ assert(length(a) == 2);
+ assert(a(1) == hex2dec('01'));
+ assert(a(2) == hex2dec('11'));
+ a = r(hex2dec('22')); % Need to use a temp
+ assert(length(a) == 1);
+ assert(a(1) == hex2dec('12'));
+ a = r(hex2dec('f1')); % Need to use a temp
+ assert(length(a) == 2);
+ assert(a(1) == hex2dec('f2'));
+ assert(a(2) == hex2dec('f3'));
+
+ sdi1 = Test.BoolBoolSD.new();
+ sdi2 = Test.BoolBoolSD.new();
+
+ si1 = [true, false];
+ si2 = [false, true, true];
+
+ sdi1(false) = si1;
+ sdi1(true) = si2;
+ sdi2(false) = si1;
+
+ [r, p3] = p.opBoolBoolSD(sdi1, sdi2);
+
+ assert(p3.Count == 1);
+ a = p3(false); % Need to use temp
+ assert(length(a) == 2);
+ assert(a(1));
+ assert(~a(2));
+ assert(r.Count == 2);
+ a = r(false); % Need to use temp
+ assert(length(a) == 2);
+ assert(a(1));
+ assert(~a(2));
+ a = r(true); % Need to use temp
+ assert(length(a) == 3);
+ assert(~a(1));
+ assert(a(2));
+ assert(a(3));
+
+ sdi1 = Test.ShortShortSD.new();
+ sdi2 = Test.ShortShortSD.new();
+
+ si1 = [1, 2, 3];
+ si2 = [4, 5];
+ si3 = [6, 7];
+
+ sdi1(1) = si1;
+ sdi1(2) = si2;
+ sdi2(4) = si3;
+
+ [r, p3] = p.opShortShortSD(sdi1, sdi2);
+
+ assert(p3.Count == 1);
+ a = p3(4); % Need to use temp
+ assert(length(a) == 2);
+ assert(a(1) == 6);
+ assert(a(2) == 7);
+ assert(r.Count == 3);
+ a = r(1); % Need to use temp
+ assert(length(a) == 3);
+ assert(a(1) == 1);
+ assert(a(2) == 2);
+ assert(a(3) == 3);
+ a = r(2); % Need to use temp
+ assert(length(a) == 2);
+ assert(a(1) == 4);
+ assert(a(2) == 5);
+ a = r(4); % Need to use temp
+ assert(length(a) == 2);
+ assert(a(1) == 6);
+ assert(a(2) == 7);
+
+ sdi1 = Test.IntIntSD.new();
+ sdi2 = Test.IntIntSD.new();
+
+ si1 = [100, 200, 300];
+ si2 = [400, 500];
+ si3 = [600, 700];
+
+ sdi1(100) = si1;
+ sdi1(200) = si2;
+ sdi2(400) = si3;
+
+ [r, p3] = p.opIntIntSD(sdi1, sdi2);
+
+ assert(p3.Count == 1);
+ a = p3(400); % Need to use temp
+ assert(length(a) == 2);
+ assert(a(1) == 600);
+ assert(a(2) == 700);
+ assert(r.Count == 3);
+ a = r(100); % Need to use temp
+ assert(length(a) == 3);
+ assert(a(1) == 100);
+ assert(a(2) == 200);
+ assert(a(3) == 300);
+ a = r(200); % Need to use temp
+ assert(length(a) == 2);
+ assert(a(1) == 400);
+ assert(a(2) == 500);
+ a = r(400); % Need to use temp
+ assert(length(a) == 2);
+ assert(a(1) == 600);
+ assert(a(2) == 700);
+
+ sdi1 = Test.LongLongSD.new();
+ sdi2 = Test.LongLongSD.new();
+
+ si1 = [999999110, 999999111, 999999110];
+ si2 = [999999120, 999999130];
+ si3 = [999999110, 999999120];
+
+ sdi1(999999990) = si1;
+ sdi1(999999991) = si2;
+ sdi2(999999992) = si3;
+
+ [r, p3] = p.opLongLongSD(sdi1, sdi2);
+
+ assert(p3.Count == 1);
+ a = p3(999999992); % Need to use temp
+ assert(length(a) == 2);
+ assert(a(1) == 999999110);
+ assert(a(2) == 999999120);
+ assert(r.Count == 3);
+ a = r(999999990); % Need to use temp
+ assert(length(a) == 3);
+ assert(a(1) == 999999110);
+ assert(a(2) == 999999111);
+ assert(a(3) == 999999110);
+ a = r(999999991); % Need to use temp
+ assert(length(a) == 2);
+ assert(a(1) == 999999120);
+ assert(a(2) == 999999130);
+ a = r(999999992); % Need to use temp
+ assert(length(a) == 2);
+ assert(a(1) == 999999110);
+ assert(a(2) == 999999120);
+
+ sdi1 = Test.StringFloatSD.new();
+ sdi2 = Test.StringFloatSD.new();
+
+ si1 = [-1.1, 123123.2, 100.0];
+ si2 = [42.24, -1.61];
+ si3 = [-3.14, 3.14];
+
+ sdi1('abc') = si1;
+ sdi1('ABC') = si2;
+ sdi2('aBc') = si3;
+
+ [r, p3] = p.opStringFloatSD(sdi1, sdi2);
+
+ assert(p3.Count == 1);
+ a = p3('aBc'); % Need to use temp
+ assert(length(a) == 2);
+ assert(a(1) == single(-3.14));
+ assert(a(2) == single(3.14));
+ assert(r.Count == 3);
+ a = r('abc'); % Need to use temp
+ assert(length(a) == 3);
+ assert(a(1) == single(-1.1));
+ assert(a(2) == single(123123.2));
+ assert(a(3) == single(100.0));
+ a = r('ABC'); % Need to use temp
+ assert(length(a) == 2);
+ assert(a(1) == single(42.24));
+ assert(a(2) == single(-1.61));
+ a = r('aBc'); % Need to use temp
+ assert(length(a) == 2);
+ assert(a(1) == single(-3.14));
+ assert(a(2) == single(3.14));
+
+ sdi1 = Test.StringDoubleSD.new();
+ sdi2 = Test.StringDoubleSD.new();
+
+ si1 = [ 1.1E10, 1.2E10, 1.3E10 ];
+ si2 = [ 1.4E10, 1.5E10 ];
+ si3 = [ 1.6E10, 1.7E10 ];
+
+ sdi1('Hello!!') = si1;
+ sdi1('Goodbye') = si2;
+ sdi2('') = si3;
+
+ [r, p3] = p.opStringDoubleSD(sdi1, sdi2);
+
+ assert(p3.Count == 1);
+ a = p3(''); % Need to use temp
+ assert(length(a) == 2);
+ assert(a(1) == 1.6E10);
+ assert(a(2) == 1.7E10);
+ assert(r.Count== 3);
+ a = r('Hello!!'); % Need to use temp
+ assert(length(a) == 3);
+ assert(a(1) == 1.1E10);
+ assert(a(2) == 1.2E10);
+ assert(a(3) == 1.3E10);
+ a = r('Goodbye'); % Need to use temp
+ assert(length(a) == 2);
+ assert(a(1) == 1.4E10);
+ assert(a(2) == 1.5E10);
+ a = r(''); % Need to use temp
+ assert(length(a) == 2);
+ assert(a(1) == 1.6E10);
+ assert(a(2) == 1.7E10);
+
+ sdi1 = Test.StringStringSD.new();
+ sdi2 = Test.StringStringSD.new();
+
+ si1 = { 'abc', 'de', 'fghi' };
+ si2 = { 'xyz', 'or' };
+ si3 = { 'and', 'xor' };
+
+ sdi1('abc') = si1;
+ sdi1('def') = si2;
+ sdi2('ghi') = si3;
+
+ [r, p3] = p.opStringStringSD(sdi1, sdi2);
+
+ assert(p3.Count == 1);
+ a = p3('ghi'); % Need to use temp
+ assert(length(a) == 2);
+ assert(strcmp(a(1), 'and'));
+ assert(strcmp(a(2), 'xor'));
+ assert(r.Count== 3);
+ a = r('abc'); % Need to use temp
+ assert(length(a) == 3);
+ assert(strcmp(a(1), 'abc'));
+ assert(strcmp(a(2), 'de'));
+ assert(strcmp(a(3), 'fghi'));
+ a = r('def'); % Need to use temp
+ assert(length(a) == 2);
+ assert(strcmp(a(1), 'xyz'));
+ assert(strcmp(a(2), 'or'));
+ a = r('ghi'); % Need to use temp
+ assert(length(a) == 2);
+ assert(strcmp(a(1), 'and'));
+ assert(strcmp(a(2), 'xor'));
+
+ sdi1 = Test.MyEnumMyEnumSD.new();
+ sdi2 = Test.MyEnumMyEnumSD.new();
+
+ si1 = { Test.MyEnum.enum1, Test.MyEnum.enum1, Test.MyEnum.enum2 };
+ si2 = { Test.MyEnum.enum1, Test.MyEnum.enum2 };
+ si3 = { Test.MyEnum.enum3, Test.MyEnum.enum3 };
+
+ sdi1(int32(Test.MyEnum.enum3)) = si1;
+ sdi1(int32(Test.MyEnum.enum2)) = si2;
+ sdi2(int32(Test.MyEnum.enum1)) = si3;
+
+ [r, p3] = p.opMyEnumMyEnumSD(sdi1, sdi2);
+
+ assert(p3.Count == 1);
+ a = p3(int32(Test.MyEnum.enum1)); % Need to use temp
+ assert(length(a) == 2);
+ assert(a{1} == Test.MyEnum.enum3);
+ assert(a{2} == Test.MyEnum.enum3);
+ assert(r.Count== 3);
+ a = r(int32(Test.MyEnum.enum3)); % Need to use temp
+ assert(length(a) == 3);
+ assert(a{1} == Test.MyEnum.enum1);
+ assert(a{2} == Test.MyEnum.enum1);
+ assert(a{3} == Test.MyEnum.enum2);
+ a = r(int32(Test.MyEnum.enum2)); % Need to use temp
+ assert(length(a) == 2);
+ assert(a{1} == Test.MyEnum.enum1);
+ assert(a{2} == Test.MyEnum.enum2);
+ a = r(int32(Test.MyEnum.enum1)); % Need to use temp
+ assert(length(a) == 2);
+ assert(a{1} == Test.MyEnum.enum3);
+ assert(a{2} == Test.MyEnum.enum3);
+
+ lengths = [0, 1, 2, 126, 127, 128, 129, 253, 254, 255, 256, 257, 1000];
+
+ for l = lengths
+ s = zeros(1, l);
+ if l > 0
+ s(1:l) = (1:l);
+ end
+ r = p.opIntS(s);
+ assert(length(r) == l);
+ for j = 1:l
+ assert(r(j) == -j);
+ end
+ end
+
+ ctx = Ice.Context.new();
+ ctx('one') = 'ONE';
+ ctx('two') = 'TWO';
+ ctx('three') = 'THREE';
+
+ assert(p.ice_getContext().Count == 0);
+ r = p.opContext();
+ assert(~isequal(r, ctx));
+
+ r = p.opContext(ctx);
+ assert(p.ice_getContext().Count == 0);
+ assert(isequal(r, ctx));
+
+ p2 = Test.MyClassPrx.checkedCast(p.ice_context(ctx));
+ assert(isequal(p2.ice_getContext(), ctx));
+ r = p2.opContext();
+ assert(isequal(r, ctx));
+ r = p2.opContext(ctx);
+ assert(isequal(r, ctx));
+
+ %
+ % Test implicit context propagation
+ %
+%{
+ impls = {'Shared', 'PerThread'};
+ for i = 1:2
+ initData = app.createInitializationData();
+ initData.properties_ = communicator.getProperties().clone();
+ initData.properties_.setProperty('Ice.ImplicitContext', impls{i});
+
+ ic = app.initialize(initData);
+
+ ctx = Ice.Context.new();
+ ctx('one') = 'ONE';
+ ctx('two') = 'TWO';
+ ctx('three') = 'THREE';
+
+ p3 = Test.MyClassPrx.uncheckedCast(ic.stringToProxy(['test:', app.getTestEndpoint(0)]));
+
+ ic.getImplicitContext().setContext(ctx);
+ assert(isequal(ic.getImplicitContext().getContext(), ctx));
+ assert(isequal(p3.opContext(), ctx));
+
+ assert(!ic.getImplicitContext().containsKey('zero'));
+ r = ic.getImplicitContext().put('zero', 'ZERO');
+ assert(strcmp(r, ''));
+ assert(ic.getImplicitContext().containsKey('zero'));
+ assert(strcmp(ic.getImplicitContext().get('zero'), 'ZERO'));
+
+ ctx = ic.getImplicitContext().getContext();
+ assert(isequal(p3.opContext(), ctx));
+
+ prxContext = Ice.Context.new();
+ prxContext('one') = 'UN';
+ prxContext('four') = 'QUATRE';
+
+ combined = Ice.Context.new(ctx);
+ keys = prxContext.keys();
+ for j = 1:prxContext.Count
+ combined(keys{j}) = prxContext(keys{j});
+ end
+ assert(strcmp(combined('one'), 'UN'));
+
+ p3 = p3.ice_context(prxContext);
+
+ ic.getImplicitContext().setContext([]);
+ assert(isequal(p3.opContext(), prxContext));
+
+ ic.getImplicitContext().setContext(ctx);
+ assert(isequal(p3.opContext(), combined));
+
+ assert(strcmp(ic.getImplicitContext().remove('one'), 'ONE'));
+
+ ic.destroy();
+ end
+%}
+
+ d = 1278312346.0 / 13.0;
+ ds = zeros(1, 5);
+ for i = 1:5
+ ds(i) = d;
+ end
+ p.opDoubleMarshaling(d, ds);
+
+ p.opIdempotent();
+
+ p.opNonmutating();
+
+ assert(p.opByte1(hex2dec('FF')) == hex2dec('FF'));
+ assert(p.opShort1(hex2dec('7FFF')) == hex2dec('7FFF'));
+ assert(p.opInt1(hex2dec('7FFFFFFF')) == hex2dec('7FFFFFFF'));
+ %assert(p.opLong1(0x7FFFFFFFFFFFFFFF) == 0x7FFFFFFFFFFFFFFF);
+ assert(p.opFloat1(1.0) == single(1.0));
+ assert(p.opDouble1(1.0) == 1.0);
+ assert(strcmp(p.opString1('opString1'), 'opString1'));
+ assert(length(p.opStringS1({})) == 0);
+ assert(p.opByteBoolD1([]).Count == 0);
+ assert(length(p.opStringS2([])) == 0);
+ assert(p.opByteBoolD2([]).Count == 0);
+
+ d = Test.MyDerivedClassPrx.uncheckedCast(p);
+ s = Test.MyStruct1();
+ s.tesT = 'Test.MyStruct1.s';
+ s.myClass = [];
+ s.myStruct1 = 'Test.MyStruct1.myStruct1';
+ s = d.opMyStruct1(s);
+ assert(strcmp(s.tesT, 'Test.MyStruct1.s'));
+ assert(isempty(s.myClass));
+ assert(strcmp(s.myStruct1, 'Test.MyStruct1.myStruct1'));
+
+ %{
+ c = new MyClass1();
+ c.tesT = 'Test.MyClass1.testT';
+ c.myClass = null;
+ c.myClass1 = 'Test.MyClass1.myClass1';
+ c = d.opMyClass1(c);
+ assert(c.tesT.equals('Test.MyClass1.testT'));
+ assert(c.myClass == null);
+ assert(c.myClass1.equals('Test.MyClass1.myClass1'));
+ %}
+ end
+ end
+end
diff --git a/matlab/test/Ice/operations/TwowaysAMI.m b/matlab/test/Ice/operations/TwowaysAMI.m
new file mode 100644
index 00000000000..9a84165b699
--- /dev/null
+++ b/matlab/test/Ice/operations/TwowaysAMI.m
@@ -0,0 +1,1266 @@
+%{
+**********************************************************************
+
+Copyright (c) 2003-2017 ZeroC, Inc. All rights reserved.
+
+This copy of Ice is licensed to you under the terms described in the
+ICE_LICENSE file included in this distribution.
+
+**********************************************************************
+%}
+
+classdef TwowaysAMI
+ methods(Static)
+ function twowaysAMI(app, p)
+ communicator = app.communicator();
+
+ call(p, 'ice_ping');
+
+ b = call(p, 'ice_isA', Test.MyClassPrx.ice_staticId());
+ assert(b);
+
+ id = call(p, 'ice_id');
+ assert(strcmp(id, Test.MyDerivedClassPrx.ice_staticId()));
+
+ ids = call(p, 'ice_ids');
+ assert(length(ids) == 3);
+
+ call(p, 'opVoid');
+
+ [r, p3] = call(p, 'opByte', hex2dec('ff'), hex2dec('0f'));
+ assert(p3 == hex2dec('f0'));
+ assert(r == hex2dec('ff'));
+
+ [r, p3] = call(p, 'opBool', true, false);
+ assert(p3);
+ assert(~r);
+
+ [r, p4, p5, p6] = call(p, 'opShortIntLong', 10, 11, 12);
+ assert(p4 == 10);
+ assert(p5 == 11);
+ assert(p6 == 12);
+ assert(r == 12);
+
+ [r, p3, p4] = call(p, 'opFloatDouble', 3.14, 1.1E10);
+ assert(p3 == single(3.14));
+ assert(p4 == 1.1E10);
+ assert(r == 1.1E10);
+
+ [r, p3] = call(p, 'opString', 'hello', 'world');
+ assert(strcmp(p3, 'world hello'));
+ assert(strcmp(r, 'hello world'));
+
+ [r, p2] = call(p, 'opMyEnum', Test.MyEnum.enum2);
+ assert(p2 == Test.MyEnum.enum2);
+ assert(r == Test.MyEnum.enum3);
+
+ [r, p2, p3] = call(p, 'opMyClass', p);
+ assert(isequal(p2.ice_getIdentity(), Ice.stringToIdentity('test')));
+ assert(isequal(p3.ice_getIdentity(), Ice.stringToIdentity('noSuchIdentity')));
+ assert(isequal(r.ice_getIdentity(), Ice.stringToIdentity('test')));
+
+ si1 = Test.Structure();
+ si1.p = p;
+ si1.e = Test.MyEnum.enum3;
+ si1.s = Test.AnotherStruct();
+ si1.s.s = 'abc';
+ si2 = Test.Structure();
+ si2.p = [];
+ si2.e = Test.MyEnum.enum2;
+ si2.s = Test.AnotherStruct();
+ si2.s.s = 'def';
+
+ [r, p3] = call(p, 'opStruct', si1, si2);
+ assert(isempty(r.p));
+ assert(r.e == Test.MyEnum.enum2);
+ assert(strcmp(r.s.s, 'def'));
+ assert(p3.p == p);
+ assert(p3.e == Test.MyEnum.enum3);
+ assert(strcmp(p3.s.s, 'a new string'));
+ p3.p.opVoid();
+
+ bsi1 = ...
+ [ ...
+ hex2dec('01'), ...
+ hex2dec('11'), ...
+ hex2dec('12'), ...
+ hex2dec('22') ...
+ ];
+ bsi2 = ...
+ [
+ hex2dec('f1'), ...
+ hex2dec('f2'), ...
+ hex2dec('f3'), ...
+ hex2dec('f4') ...
+ ];
+
+ [r, p3] = call(p, 'opByteS', bsi1, bsi2);
+ assert(length(p3) == 4);
+ assert(p3(1) == hex2dec('22'));
+ assert(p3(2) == hex2dec('12'));
+ assert(p3(3) == hex2dec('11'));
+ assert(p3(4) == hex2dec('01'));
+ assert(length(r) == 8);
+ assert(r(1) == hex2dec('01'));
+ assert(r(2) == hex2dec('11'));
+ assert(r(3) == hex2dec('12'));
+ assert(r(4) == hex2dec('22'));
+ assert(r(5) == hex2dec('f1'));
+ assert(r(6) == hex2dec('f2'));
+ assert(r(7) == hex2dec('f3'));
+ assert(r(8) == hex2dec('f4'));
+
+ bsi1 = [true, true, false];
+ bsi2 = [false];
+
+ [r, p3] = call(p, 'opBoolS', bsi1, bsi2);
+ assert(length(p3) == 4);
+ assert(p3(1));
+ assert(p3(2));
+ assert(~p3(3));
+ assert(~p3(4));
+ assert(length(r) == 3);
+ assert(~r(1));
+ assert(r(2));
+ assert(r(3));
+
+ ssi = [1, 2, 3];
+ isi = [5, 6, 7, 8];
+ lsi = [10, 30, 20];
+
+ [r, p4, p5, p6] = call(p, 'opShortIntLongS', ssi, isi, lsi);
+ assert(length(p4) == 3);
+ assert(p4(1) == 1);
+ assert(p4(2) == 2);
+ assert(p4(3) == 3);
+ assert(length(p5) == 4);
+ assert(p5(1) == 8);
+ assert(p5(2) == 7);
+ assert(p5(3) == 6);
+ assert(p5(4) == 5);
+ assert(length(p6) == 6);
+ assert(p6(1) == 10);
+ assert(p6(2) == 30);
+ assert(p6(3) == 20);
+ assert(p6(4) == 10);
+ assert(p6(5) == 30);
+ assert(p6(6) == 20);
+ assert(length(r) == 3);
+ assert(r(1) == 10);
+ assert(r(2) == 30);
+ assert(r(3) == 20);
+
+ fsi = [3.14, 1.11];
+ dsi = [1.1E10, 1.2E10, 1.3E10];
+
+ [r, p3, p4] = call(p, 'opFloatDoubleS', fsi, dsi);
+ assert(length(p3) == 2);
+ assert(p3(1) == single(3.14));
+ assert(p3(2) == single(1.11));
+ assert(length(p4) == 3);
+ assert(p4(1) == 1.3E10);
+ assert(p4(2) == 1.2E10);
+ assert(p4(3) == 1.1E10);
+ assert(length(r) == 5);
+ assert(r(1) == 1.1E10);
+ assert(r(2) == 1.2E10);
+ assert(r(3) == 1.3E10);
+ assert(r(4) == single(3.14));
+ assert(r(5) == single(1.11));
+
+ ssi1 = {'abc', 'de', 'fghi'};
+ ssi2 = {'xyz'};
+
+ [r, p3] = call(p, 'opStringS', ssi1, ssi2);
+ assert(length(p3) == 4);
+ assert(strcmp(p3{1}, 'abc'));
+ assert(strcmp(p3{2}, 'de'));
+ assert(strcmp(p3{3}, 'fghi'));
+ assert(strcmp(p3{4}, 'xyz'));
+ assert(length(r) == 3);
+ assert(strcmp(r{1}, 'fghi'));
+ assert(strcmp(r{2}, 'de'));
+ assert(strcmp(r{3}, 'abc'));
+
+ bsi1 = ...
+ { ...
+ [hex2dec('01'), hex2dec('11'), hex2dec('12')], ...
+ [hex2dec('ff')] ...
+ };
+ bsi2 = ...
+ { ...
+ [hex2dec('0e')], ...
+ [hex2dec('f2'), hex2dec('f1')] ...
+ };
+
+ [r, p3] = call(p, 'opByteSS', bsi1, bsi2);
+ assert(length(p3) == 2);
+ assert(length(p3{1}) == 1);
+ assert(p3{1}(1) == hex2dec('ff'));
+ assert(length(p3{2}) == 3);
+ assert(p3{2}(1) == hex2dec('01'));
+ assert(p3{2}(2) == hex2dec('11'));
+ assert(p3{2}(3) == hex2dec('12'));
+ assert(length(r) == 4);
+ assert(length(r{1}) == 3);
+ assert(r{1}(1) == hex2dec('01'));
+ assert(r{1}(2) == hex2dec('11'));
+ assert(r{1}(3) == hex2dec('12'));
+ assert(length(r{2}) == 1);
+ assert(r{2}(1) == hex2dec('ff'));
+ assert(length(r{3}) == 1);
+ assert(r{3}(1) == hex2dec('0e'));
+ assert(length(r{4}) == 2);
+ assert(r{4}(1) == hex2dec('f2'));
+ assert(r{4}(2) == hex2dec('f1'));
+
+ bsi1 = ...
+ { ...
+ [true], ...
+ [false], ...
+ [true, true] ...
+ };
+
+ bsi2 = ...
+ { ...
+ [false, false, true] ...
+ };
+
+ [r, p3] = call(p, 'opBoolSS', bsi1, bsi2);
+ assert(length(p3) == 4);
+ assert(length(p3{1}) == 1);
+ assert(p3{1}(1));
+ assert(length(p3{2}) == 1);
+ assert(~p3{2}(1));
+ assert(length(p3{3}) == 2);
+ assert(p3{3}(1));
+ assert(p3{3}(2));
+ assert(length(p3{4}) == 3);
+ assert(~p3{4}(1));
+ assert(~p3{4}(2));
+ assert(p3{4}(3));
+ assert(length(r) == 3);
+ assert(length(r{1}) == 2);
+ assert(r{1}(1));
+ assert(r{1}(2));
+ assert(length(r{2}) == 1);
+ assert(~r{2}(1));
+ assert(length(r{3}) == 1);
+ assert(r{3}(1));
+
+ ssi = ...
+ { ...
+ [1, 2, 5], ...
+ [13], ...
+ [] ...
+ };
+ isi = ...
+ { ...
+ [24, 98], ...
+ [42] ...
+ };
+ lsi = ...
+ { ...
+ [496, 1729], ...
+ };
+
+ [r, p4, p5, p6] = call(p, 'opShortIntLongSS', ssi, isi, lsi);
+ assert(length(r) == 1);
+ assert(length(r{1}) == 2);
+ assert(r{1}(1) == 496);
+ assert(r{1}(2) == 1729);
+ assert(length(p4) == 3);
+ assert(length(p4{1}) == 3);
+ assert(p4{1}(1) == 1);
+ assert(p4{1}(2) == 2);
+ assert(p4{1}(3) == 5);
+ assert(length(p4{2}) == 1);
+ assert(p4{2}(1) == 13);
+ assert(length(p4{3}) == 0);
+ assert(length(p5) == 2);
+ assert(length(p5{1}) == 1);
+ assert(p5{1}(1) == 42);
+ assert(length(p5{2}) == 2);
+ assert(p5{2}(1) == 24);
+ assert(p5{2}(2) == 98);
+ assert(length(p6) == 2);
+ assert(length(p6{1}) == 2);
+ assert(p6{1}(1) == 496);
+ assert(p6{1}(2) == 1729);
+ assert(length(p6{2}) == 2);
+ assert(p6{2}(1) == 496);
+ assert(p6{2}(2) == 1729);
+
+ fsi = ...
+ { ...
+ [3.14], ...
+ [1.11], ...
+ [], ...
+ };
+ dsi = ...
+ { ...
+ [1.1E10, 1.2E10, 1.3E10] ...
+ };
+
+ [r, p3, p4] = call(p, 'opFloatDoubleSS', fsi, dsi);
+ assert(length(p3) == 3);
+ assert(length(p3{1}) == 1);
+ assert(p3{1}(1) == single(3.14));
+ assert(length(p3{2}) == 1);
+ assert(p3{2}(1) == single(1.11));
+ assert(length(p3{3}) == 0);
+ assert(length(p4) == 1);
+ assert(length(p4{1}) == 3);
+ assert(p4{1}(1) == 1.1E10);
+ assert(p4{1}(2) == 1.2E10);
+ assert(p4{1}(3) == 1.3E10);
+ assert(length(r) == 2);
+ assert(length(r{1}) == 3);
+ assert(r{1}(1) == 1.1E10);
+ assert(r{1}(2) == 1.2E10);
+ assert(r{1}(3) == 1.3E10);
+ assert(length(r{2}) == 3);
+ assert(r{2}(1) == 1.1E10);
+ assert(r{2}(2) == 1.2E10);
+ assert(r{2}(3) == 1.3E10);
+
+ ssi1 = ...
+ { ...
+ {'abc'}, ...
+ {'de', 'fghi'} ...
+ };
+ ssi2 = ...
+ { ...
+ {}, ...
+ {}, ...
+ {'xyz'} ...
+ };
+
+ [r, p3] = call(p, 'opStringSS', ssi1, ssi2);
+ assert(length(p3) == 5);
+ assert(length(p3{1}) == 1);
+ assert(strcmp(p3{1}(1), 'abc'));
+ assert(length(p3{2}) == 2);
+ assert(strcmp(p3{2}(1), 'de'));
+ assert(strcmp(p3{2}(2), 'fghi'));
+ assert(length(p3{3}) == 0);
+ assert(length(p3{4}) == 0);
+ assert(length(p3{5}) == 1);
+ assert(strcmp(p3{5}(1), 'xyz'));
+ assert(length(r) == 3);
+ assert(length(r{1}) == 1);
+ assert(strcmp(r{1}(1), 'xyz'));
+ assert(length(r{2}) == 0);
+ assert(length(r{3}) == 0);
+
+ sssi1 = ...
+ { ...
+ { ...
+ { ...
+ 'abc', 'de' ...
+ }, ...
+ { ...
+ 'xyz' ...
+ } ...
+ }, ...
+ { ...
+ { ...
+ 'hello' ...
+ } ...
+ } ...
+ };
+
+ sssi2 = ...
+ { ...
+ { ...
+ { ...
+ '', '' ...
+ }, ...
+ { ...
+ 'abcd' ...
+ } ...
+ }, ...
+ { ...
+ { ...
+ '' ...
+ } ...
+ }, ...
+ { ...
+ } ...
+ };
+
+ [r, p3] = call(p, 'opStringSSS', sssi1, sssi2);
+ assert(length(p3) == 5);
+ assert(length(p3{1}) == 2);
+ assert(length(p3{1}{1}) == 2);
+ assert(length(p3{1}{2}) == 1);
+ assert(length(p3{2}) == 1);
+ assert(length(p3{2}{1}) == 1);
+ assert(length(p3{3}) == 2);
+ assert(length(p3{3}{1}) == 2);
+ assert(length(p3{3}{2}) == 1);
+ assert(length(p3{4}) == 1);
+ assert(length(p3{4}{1}) == 1);
+ assert(length(p3{5}) == 0);
+ assert(strcmp(p3{1}{1}(1), 'abc'));
+ assert(strcmp(p3{1}{1}(2), 'de'));
+ assert(strcmp(p3{1}{2}(1), 'xyz'));
+ assert(strcmp(p3{2}{1}(1), 'hello'));
+ assert(strcmp(p3{3}{1}(1), ''));
+ assert(strcmp(p3{3}{1}(2), ''));
+ assert(strcmp(p3{3}{2}(1), 'abcd'));
+ assert(strcmp(p3{4}{1}(1), ''));
+
+ assert(length(r) == 3);
+ assert(length(r{1}) == 0);
+ assert(length(r{2}) == 1);
+ assert(length(r{2}{1}) == 1);
+ assert(length(r{3}) == 2);
+ assert(length(r{3}{1}) == 2);
+ assert(length(r{3}{2}) == 1);
+ assert(strcmp(r{2}{1}(1), ''));
+ assert(strcmp(r{3}{1}(1), ''));
+ assert(strcmp(r{3}{1}(2), ''));
+ assert(strcmp(r{3}{2}(1), 'abcd'));
+
+ di1 = Test.ByteBoolD.new();
+ di1(10) = true;
+ di1(100) = false;
+ di2 = Test.ByteBoolD.new();
+ di2(10) = true;
+ di2(11) = false;
+ di2(101) = true;
+
+ [r, p3] = call(p, 'opByteBoolD', di1, di2);
+
+ assert(isequal(p3, di1));
+ assert(r.Count == 4);
+ assert(r(10));
+ assert(~r(11));
+ assert(~r(100));
+ assert(r(101));
+
+ di1 = Test.ShortIntD.new();
+ di1(110) = -1;
+ di1(1100) = 123123;
+ di2 = Test.ShortIntD.new();
+ di2(110) = -1;
+ di2(111) = -100;
+ di2(1101) = 0;
+
+ [r, p3] = call(p, 'opShortIntD', di1, di2);
+
+ assert(isequal(p3, di1));
+ assert(r.Count == 4);
+ assert(r(110) == -1);
+ assert(r(111) == -100);
+ assert(r(1100) == 123123);
+ assert(r(1101) == 0);
+
+ di1 = Test.LongFloatD.new();
+ di1(999999110) = -1.1;
+ di1(999999111) = 123123.2;
+ di2 = Test.LongFloatD.new();
+ di2(999999110) = -1.1;
+ di2(999999120) = -100.4;
+ di2(999999130) = 0.5;
+
+ [r, p3] = call(p, 'opLongFloatD', di1, di2);
+
+ assert(isequal(p3, di1));
+ assert(r.Count == 4);
+ assert(r(999999110) == single(-1.1));
+ assert(r(999999120) == single(-100.4));
+ assert(r(999999111) == single(123123.2));
+ assert(r(999999130) == single(0.5));
+
+ di1 = Test.StringStringD.new();
+ di1('foo') = 'abc -1.1';
+ di1('bar') = 'abc 123123.2';
+ di2 = Test.StringStringD.new();
+ di2('foo') = 'abc -1.1';
+ di2('FOO') = 'abc -100.4';
+ di2('BAR') = 'abc 0.5';
+
+ [r, p3] = call(p, 'opStringStringD', di1, di2);
+
+ assert(isequal(p3, di1));
+ assert(r.Count == 4);
+ assert(strcmp(r('foo'), 'abc -1.1'));
+ assert(strcmp(r('FOO'), 'abc -100.4'));
+ assert(strcmp(r('bar'), 'abc 123123.2'));
+ assert(strcmp(r('BAR'), 'abc 0.5'));
+
+ di1 = Test.StringMyEnumD.new();
+ di1('abc') = Test.MyEnum.enum1;
+ di1('') = Test.MyEnum.enum2;
+ di2 = Test.StringMyEnumD.new();
+ di2('abc') = Test.MyEnum.enum1;
+ di2('qwerty') = Test.MyEnum.enum3;
+ di2('Hello!!') = Test.MyEnum.enum2;
+
+ [r, p3] = call(p, 'opStringMyEnumD', di1, di2);
+
+ assert(isequal(p3, di1));
+ assert(r.Count == 4);
+ assert(r('abc') == Test.MyEnum.enum1);
+ assert(r('qwerty') == Test.MyEnum.enum3);
+ assert(r('') == Test.MyEnum.enum2);
+ assert(r('Hello!!') == Test.MyEnum.enum2);
+
+ di1 = Test.MyEnumStringD.new();
+ di1(int32(Test.MyEnum.enum1)) = 'abc';
+ di2 = Test.MyEnumStringD.new();
+ di2(int32(Test.MyEnum.enum2)) = 'Hello!!';
+ di2(int32(Test.MyEnum.enum3)) = 'qwerty';
+
+ [r, p3] = call(p, 'opMyEnumStringD', di1, di2);
+
+ assert(isequal(p3, di1));
+ assert(r.Count == 3);
+ assert(strcmp(r(int32(Test.MyEnum.enum1)), 'abc'));
+ assert(strcmp(r(int32(Test.MyEnum.enum2)), 'Hello!!'));
+ assert(strcmp(r(int32(Test.MyEnum.enum3)), 'qwerty'));
+
+ s11 = Test.MyStruct(1, 1);
+ s12 = Test.MyStruct(1, 2);
+ di1 = Test.MyStructMyEnumD.new();
+ di1(1).key = s11;
+ di1(1).value = Test.MyEnum.enum1;
+ di1(2).key = s12;
+ di1(2).value = Test.MyEnum.enum2;
+
+ s22 = Test.MyStruct(2, 2);
+ s23 = Test.MyStruct(2, 3);
+ di2 = Test.MyStructMyEnumD.new();
+ di2(1).key = s11;
+ di2(1).value = Test.MyEnum.enum1;
+ di2(2).key = s22;
+ di2(2).value = Test.MyEnum.enum3;
+ di2(3).key = s23;
+ di2(3).value = Test.MyEnum.enum2;
+
+ [r, p3] = call(p, 'opMyStructMyEnumD', di1, di2);
+
+ assert(isequal(p3, di1));
+ assert(length(r) == 4);
+ for i = 1:length(r)
+ if isequal(r(i).key, s11)
+ assert(r(i).value == Test.MyEnum.enum1);
+ elseif isequal(r(i).key, s12)
+ assert(r(i).value == Test.MyEnum.enum2);
+ elseif isequal(r(i).key, s22)
+ assert(r(i).value == Test.MyEnum.enum3);
+ elseif isequal(r(i).key, s23)
+ assert(r(i).value == Test.MyEnum.enum2);
+ else
+ assert(false);
+ end
+ end
+
+ di1 = Test.ByteBoolD.new();
+ di1(10) = true;
+ di1(100) = false;
+ di2 = Test.ByteBoolD.new();
+ di2(10) = true;
+ di2(11) = false;
+ di2(101) = true;
+ di3 = Test.ByteBoolD.new();
+ di3(100) = false;
+ di3(101) = false;
+
+ dsi1 = {di1, di2};
+ dsi2 = {di3};
+
+ [r, p3] = call(p, 'opByteBoolDS', dsi1, dsi2);
+
+ assert(length(r) == 2);
+ assert(r{1}.Count == 3);
+ assert(r{1}(10));
+ assert(~r{1}(11));
+ assert(r{1}(101));
+ assert(r{2}.Count == 2);
+ assert(r{2}(10));
+ assert(~r{2}(100));
+
+ assert(length(p3) == 3);
+ assert(p3{1}.Count == 2);
+ assert(~p3{1}(100));
+ assert(~p3{1}(101));
+ assert(p3{2}.Count == 2);
+ assert(p3{2}(10));
+ assert(~p3{2}(100));
+ assert(p3{3}.Count == 3);
+ assert(p3{3}(10));
+ assert(~p3{3}(11));
+ assert(p3{3}(101));
+
+ di1 = Test.ShortIntD.new();
+ di1(110) = -1;
+ di1(1100) = 123123;
+ di2 = Test.ShortIntD.new();
+ di2(110) = -1;
+ di2(111) = -100;
+ di2(1101) = 0;
+ di3 = Test.ShortIntD.new();
+ di3(100) = -1001;
+
+ dsi1 = {di1, di2};
+ dsi2 = {di3};
+
+ [r, p3] = call(p, 'opShortIntDS', dsi1, dsi2);
+
+ assert(length(r) == 2);
+ assert(r{1}.Count == 3);
+ assert(r{1}(110) == -1);
+ assert(r{1}(111) == -100);
+ assert(r{1}(1101) == 0);
+ assert(r{2}.Count == 2);
+ assert(r{2}(110) == -1);
+ assert(r{2}(1100) == 123123);
+
+ assert(length(p3) == 3);
+ assert(p3{1}.Count == 1);
+ assert(p3{1}(100) == -1001);
+ assert(p3{2}.Count == 2);
+ assert(p3{2}(110) == -1);
+ assert(p3{2}(1100) == 123123);
+ assert(p3{3}.Count == 3);
+ assert(p3{3}(110) == -1);
+ assert(p3{3}(111) == -100);
+ assert(p3{3}(1101) == 0);
+
+ di1 = Test.LongFloatD.new();
+ di1(999999110) = -1.1;
+ di1(999999111) = 123123.2;
+ di2 = Test.LongFloatD.new();
+ di2(999999110) = -1.1;
+ di2(999999120) = -100.4;
+ di2(999999130) = 0.5;
+ di3 = Test.LongFloatD.new();
+ di3(999999140) = 3.14;
+
+ dsi1 = {di1, di2};
+ dsi2 = {di3};
+
+ [r, p3] = call(p, 'opLongFloatDS', dsi1, dsi2);
+
+ assert(length(r) == 2);
+ assert(r{1}.Count == 3);
+ assert(r{1}(999999110) == single(-1.1));
+ assert(r{1}(999999120) == single(-100.4));
+ assert(r{1}(999999130) == single(0.5));
+ assert(r{2}.Count == 2);
+ assert(r{2}(999999110) == single(-1.1));
+ assert(r{2}(999999111) == single(123123.2));
+
+ assert(length(p3) == 3);
+ assert(p3{1}.Count == 1);
+ assert(p3{1}(999999140) == single(3.14));
+ assert(p3{2}.Count == 2);
+ assert(p3{2}(999999110) == single(-1.1));
+ assert(p3{2}(999999111) == single(123123.2));
+ assert(p3{3}.Count == 3);
+ assert(p3{3}(999999110) == single(-1.1));
+ assert(p3{3}(999999120) == single(-100.4));
+ assert(p3{3}(999999130) == single(0.5));
+
+ di1 = Test.StringStringD.new();
+ di1('foo') = 'abc -1.1';
+ di1('bar') = 'abc 123123.2';
+ di2 = Test.StringStringD.new();
+ di2('foo') = 'abc -1.1';
+ di2('FOO') = 'abc -100.4';
+ di2('BAR') = 'abc 0.5';
+ di3 = Test.StringStringD.new();
+ di3('f00') = 'ABC -3.14';
+
+ dsi1 = {di1, di2};
+ dsi2 = {di3};
+
+ [r, p3] = call(p, 'opStringStringDS', dsi1, dsi2);
+
+ assert(length(r) == 2);
+ assert(r{1}.Count == 3);
+ assert(strcmp(r{1}('foo'), 'abc -1.1'));
+ assert(strcmp(r{1}('FOO'), 'abc -100.4'));
+ assert(strcmp(r{1}('BAR'), 'abc 0.5'));
+ assert(r{2}.Count == 2);
+ assert(strcmp(r{2}('foo'), 'abc -1.1'));
+ assert(strcmp(r{2}('bar'), 'abc 123123.2'));
+
+ assert(length(p3) == 3);
+ assert(p3{1}.Count == 1);
+ assert(strcmp(p3{1}('f00'), 'ABC -3.14'));
+ assert(p3{2}.Count == 2);
+ assert(strcmp(p3{2}('foo'), 'abc -1.1'));
+ assert(strcmp(p3{2}('bar'), 'abc 123123.2'));
+ assert(p3{3}.Count == 3);
+ assert(strcmp(p3{3}('foo'), 'abc -1.1'));
+ assert(strcmp(p3{3}('FOO'), 'abc -100.4'));
+ assert(strcmp(p3{3}('BAR'), 'abc 0.5'));
+
+ di1 = Test.StringMyEnumD.new();
+ di1('abc') = Test.MyEnum.enum1;
+ di1('') = Test.MyEnum.enum2;
+ di2 = Test.StringMyEnumD.new();
+ di2('abc') = Test.MyEnum.enum1;
+ di2('qwerty') = Test.MyEnum.enum3;
+ di2('Hello!!') = Test.MyEnum.enum2;
+ di3 = Test.StringMyEnumD.new();
+ di3('Goodbye') = Test.MyEnum.enum1;
+
+ dsi1 = {di1, di2};
+ dsi2 = {di3};
+
+ [r, p3] = call(p, 'opStringMyEnumDS', dsi1, dsi2);
+
+ assert(length(r) == 2);
+ assert(r{1}.Count == 3);
+ assert(r{1}('abc') == Test.MyEnum.enum1);
+ assert(r{1}('qwerty') == Test.MyEnum.enum3);
+ assert(r{1}('Hello!!') == Test.MyEnum.enum2);
+ assert(r{2}.Count == 2);
+ assert(r{2}('abc') == Test.MyEnum.enum1);
+ assert(r{2}('') == Test.MyEnum.enum2);
+
+ assert(length(p3) == 3);
+ assert(p3{1}.Count == 1);
+ assert(p3{1}('Goodbye') == Test.MyEnum.enum1);
+ assert(p3{2}.Count == 2);
+ assert(p3{2}('abc') == Test.MyEnum.enum1);
+ assert(p3{2}('') == Test.MyEnum.enum2);
+ assert(p3{3}.Count == 3);
+ assert(p3{3}('abc') == Test.MyEnum.enum1);
+ assert(p3{3}('qwerty') == Test.MyEnum.enum3);
+ assert(p3{3}('Hello!!') == Test.MyEnum.enum2);
+
+ di1 = Test.MyEnumStringD.new();
+ di1(int32(Test.MyEnum.enum1)) = 'abc';
+ di2 = Test.MyEnumStringD.new();
+ di2(int32(Test.MyEnum.enum2)) = 'Hello!!';
+ di2(int32(Test.MyEnum.enum3)) = 'qwerty';
+ di3 = Test.MyEnumStringD.new();
+ di3(int32(Test.MyEnum.enum1)) = 'Goodbye';
+
+ dsi1 = {di1, di2};
+ dsi2 = {di3};
+
+ [r, p3] = call(p, 'opMyEnumStringDS', dsi1, dsi2);
+
+ assert(length(r) == 2);
+ assert(r{1}.Count == 2);
+ assert(strcmp(r{1}(int32(Test.MyEnum.enum2)), 'Hello!!'));
+ assert(strcmp(r{1}(int32(Test.MyEnum.enum3)), 'qwerty'));
+ assert(r{2}.Count == 1);
+ assert(strcmp(r{2}(int32(Test.MyEnum.enum1)), 'abc'));
+
+ assert(length(p3) == 3);
+ assert(p3{1}.Count == 1);
+ assert(strcmp(p3{1}(int32(Test.MyEnum.enum1)), 'Goodbye'));
+ assert(p3{2}.Count == 1);
+ assert(strcmp(p3{2}(int32(Test.MyEnum.enum1)), 'abc'));
+ assert(p3{3}.Count == 2);
+ assert(strcmp(p3{3}(int32(Test.MyEnum.enum2)), 'Hello!!'));
+ assert(strcmp(p3{3}(int32(Test.MyEnum.enum3)), 'qwerty'));
+
+ s11 = Test.MyStruct(1, 1);
+ s12 = Test.MyStruct(1, 2);
+ di1 = Test.MyStructMyEnumD.new();
+ di1(1).key = s11;
+ di1(1).value = Test.MyEnum.enum1;
+ di1(2).key = s12;
+ di1(2).value = Test.MyEnum.enum2;
+
+ s22 = Test.MyStruct(2, 2);
+ s23 = Test.MyStruct(2, 3);
+ di2 = Test.MyStructMyEnumD.new();
+ di2(1).key = s11;
+ di2(1).value = Test.MyEnum.enum1;
+ di2(2).key = s22;
+ di2(2).value = Test.MyEnum.enum3;
+ di2(3).key = s23;
+ di2(3).value = Test.MyEnum.enum2;
+
+ di3 = Test.MyStructMyEnumD.new();
+ di3(1).key = s23;
+ di3(1).value = Test.MyEnum.enum2;
+
+ dsi1 = {di1, di2};
+ dsi2 = {di3};
+
+ [r, p3] = call(p, 'opMyStructMyEnumDS', dsi1, dsi2);
+
+ function checkStructDict(d)
+ for i = 1:length(d)
+ if isequal(d(i).key, s11)
+ assert(d(i).value == Test.MyEnum.enum1);
+ elseif isequal(d(i).key, s12)
+ assert(d(i).value == Test.MyEnum.enum2);
+ elseif isequal(d(i).key, s22)
+ assert(d(i).value == Test.MyEnum.enum3);
+ elseif isequal(d(i).key, s23)
+ assert(d(i).value == Test.MyEnum.enum2);
+ else
+ assert(false);
+ end
+ end
+ end
+ assert(length(r) == 2);
+ assert(length(r{1}) == 3);
+ checkStructDict(r{1});
+ checkStructDict(r{2});
+
+ assert(length(p3) == 3);
+ assert(length(p3{1}) == 1);
+ checkStructDict(p3{1});
+ assert(length(p3{2}) == 2);
+ checkStructDict(p3{2});
+ assert(length(p3{3}) == 3);
+ checkStructDict(p3{3});
+
+ sdi1 = Test.ByteByteSD.new();
+ sdi2 = Test.ByteByteSD.new();
+
+ si1 = [hex2dec('01'), hex2dec('11')];
+ si2 = [hex2dec('12')];
+ si3 = [hex2dec('f2'), hex2dec('f3')];
+
+ sdi1(hex2dec('01')) = si1;
+ sdi1(hex2dec('22')) = si2;
+ sdi2(hex2dec('f1')) = si3;
+
+ [r, p3] = call(p, 'opByteByteSD', sdi1, sdi2);
+
+ assert(p3.Count == 1);
+ a = p3(hex2dec('f1')); % Need to use a temp
+ assert(length(a) == 2);
+ assert(a(1) == hex2dec('f2'));
+ assert(a(2) == hex2dec('f3'));
+ assert(r.Count == 3);
+ a = r(hex2dec('01')); % Need to use a temp
+ assert(length(a) == 2);
+ assert(a(1) == hex2dec('01'));
+ assert(a(2) == hex2dec('11'));
+ a = r(hex2dec('22')); % Need to use a temp
+ assert(length(a) == 1);
+ assert(a(1) == hex2dec('12'));
+ a = r(hex2dec('f1')); % Need to use a temp
+ assert(length(a) == 2);
+ assert(a(1) == hex2dec('f2'));
+ assert(a(2) == hex2dec('f3'));
+
+ sdi1 = Test.BoolBoolSD.new();
+ sdi2 = Test.BoolBoolSD.new();
+
+ si1 = [true, false];
+ si2 = [false, true, true];
+
+ sdi1(false) = si1;
+ sdi1(true) = si2;
+ sdi2(false) = si1;
+
+ [r, p3] = call(p, 'opBoolBoolSD', sdi1, sdi2);
+
+ assert(p3.Count == 1);
+ a = p3(false); % Need to use temp
+ assert(length(a) == 2);
+ assert(a(1));
+ assert(~a(2));
+ assert(r.Count == 2);
+ a = r(false); % Need to use temp
+ assert(length(a) == 2);
+ assert(a(1));
+ assert(~a(2));
+ a = r(true); % Need to use temp
+ assert(length(a) == 3);
+ assert(~a(1));
+ assert(a(2));
+ assert(a(3));
+
+ sdi1 = Test.ShortShortSD.new();
+ sdi2 = Test.ShortShortSD.new();
+
+ si1 = [1, 2, 3];
+ si2 = [4, 5];
+ si3 = [6, 7];
+
+ sdi1(1) = si1;
+ sdi1(2) = si2;
+ sdi2(4) = si3;
+
+ [r, p3] = call(p, 'opShortShortSD', sdi1, sdi2);
+
+ assert(p3.Count == 1);
+ a = p3(4); % Need to use temp
+ assert(length(a) == 2);
+ assert(a(1) == 6);
+ assert(a(2) == 7);
+ assert(r.Count == 3);
+ a = r(1); % Need to use temp
+ assert(length(a) == 3);
+ assert(a(1) == 1);
+ assert(a(2) == 2);
+ assert(a(3) == 3);
+ a = r(2); % Need to use temp
+ assert(length(a) == 2);
+ assert(a(1) == 4);
+ assert(a(2) == 5);
+ a = r(4); % Need to use temp
+ assert(length(a) == 2);
+ assert(a(1) == 6);
+ assert(a(2) == 7);
+
+ sdi1 = Test.IntIntSD.new();
+ sdi2 = Test.IntIntSD.new();
+
+ si1 = [100, 200, 300];
+ si2 = [400, 500];
+ si3 = [600, 700];
+
+ sdi1(100) = si1;
+ sdi1(200) = si2;
+ sdi2(400) = si3;
+
+ [r, p3] = call(p, 'opIntIntSD', sdi1, sdi2);
+
+ assert(p3.Count == 1);
+ a = p3(400); % Need to use temp
+ assert(length(a) == 2);
+ assert(a(1) == 600);
+ assert(a(2) == 700);
+ assert(r.Count == 3);
+ a = r(100); % Need to use temp
+ assert(length(a) == 3);
+ assert(a(1) == 100);
+ assert(a(2) == 200);
+ assert(a(3) == 300);
+ a = r(200); % Need to use temp
+ assert(length(a) == 2);
+ assert(a(1) == 400);
+ assert(a(2) == 500);
+ a = r(400); % Need to use temp
+ assert(length(a) == 2);
+ assert(a(1) == 600);
+ assert(a(2) == 700);
+
+ sdi1 = Test.LongLongSD.new();
+ sdi2 = Test.LongLongSD.new();
+
+ si1 = [999999110, 999999111, 999999110];
+ si2 = [999999120, 999999130];
+ si3 = [999999110, 999999120];
+
+ sdi1(999999990) = si1;
+ sdi1(999999991) = si2;
+ sdi2(999999992) = si3;
+
+ [r, p3] = call(p, 'opLongLongSD', sdi1, sdi2);
+
+ assert(p3.Count == 1);
+ a = p3(999999992); % Need to use temp
+ assert(length(a) == 2);
+ assert(a(1) == 999999110);
+ assert(a(2) == 999999120);
+ assert(r.Count == 3);
+ a = r(999999990); % Need to use temp
+ assert(length(a) == 3);
+ assert(a(1) == 999999110);
+ assert(a(2) == 999999111);
+ assert(a(3) == 999999110);
+ a = r(999999991); % Need to use temp
+ assert(length(a) == 2);
+ assert(a(1) == 999999120);
+ assert(a(2) == 999999130);
+ a = r(999999992); % Need to use temp
+ assert(length(a) == 2);
+ assert(a(1) == 999999110);
+ assert(a(2) == 999999120);
+
+ sdi1 = Test.StringFloatSD.new();
+ sdi2 = Test.StringFloatSD.new();
+
+ si1 = [-1.1, 123123.2, 100.0];
+ si2 = [42.24, -1.61];
+ si3 = [-3.14, 3.14];
+
+ sdi1('abc') = si1;
+ sdi1('ABC') = si2;
+ sdi2('aBc') = si3;
+
+ [r, p3] = call(p, 'opStringFloatSD', sdi1, sdi2);
+
+ assert(p3.Count == 1);
+ a = p3('aBc'); % Need to use temp
+ assert(length(a) == 2);
+ assert(a(1) == single(-3.14));
+ assert(a(2) == single(3.14));
+ assert(r.Count == 3);
+ a = r('abc'); % Need to use temp
+ assert(length(a) == 3);
+ assert(a(1) == single(-1.1));
+ assert(a(2) == single(123123.2));
+ assert(a(3) == single(100.0));
+ a = r('ABC'); % Need to use temp
+ assert(length(a) == 2);
+ assert(a(1) == single(42.24));
+ assert(a(2) == single(-1.61));
+ a = r('aBc'); % Need to use temp
+ assert(length(a) == 2);
+ assert(a(1) == single(-3.14));
+ assert(a(2) == single(3.14));
+
+ sdi1 = Test.StringDoubleSD.new();
+ sdi2 = Test.StringDoubleSD.new();
+
+ si1 = [ 1.1E10, 1.2E10, 1.3E10 ];
+ si2 = [ 1.4E10, 1.5E10 ];
+ si3 = [ 1.6E10, 1.7E10 ];
+
+ sdi1('Hello!!') = si1;
+ sdi1('Goodbye') = si2;
+ sdi2('') = si3;
+
+ [r, p3] = call(p, 'opStringDoubleSD', sdi1, sdi2);
+
+ assert(p3.Count == 1);
+ a = p3(''); % Need to use temp
+ assert(length(a) == 2);
+ assert(a(1) == 1.6E10);
+ assert(a(2) == 1.7E10);
+ assert(r.Count== 3);
+ a = r('Hello!!'); % Need to use temp
+ assert(length(a) == 3);
+ assert(a(1) == 1.1E10);
+ assert(a(2) == 1.2E10);
+ assert(a(3) == 1.3E10);
+ a = r('Goodbye'); % Need to use temp
+ assert(length(a) == 2);
+ assert(a(1) == 1.4E10);
+ assert(a(2) == 1.5E10);
+ a = r(''); % Need to use temp
+ assert(length(a) == 2);
+ assert(a(1) == 1.6E10);
+ assert(a(2) == 1.7E10);
+
+ sdi1 = Test.StringStringSD.new();
+ sdi2 = Test.StringStringSD.new();
+
+ si1 = { 'abc', 'de', 'fghi' };
+ si2 = { 'xyz', 'or' };
+ si3 = { 'and', 'xor' };
+
+ sdi1('abc') = si1;
+ sdi1('def') = si2;
+ sdi2('ghi') = si3;
+
+ [r, p3] = call(p, 'opStringStringSD', sdi1, sdi2);
+
+ assert(p3.Count == 1);
+ a = p3('ghi'); % Need to use temp
+ assert(length(a) == 2);
+ assert(strcmp(a(1), 'and'));
+ assert(strcmp(a(2), 'xor'));
+ assert(r.Count== 3);
+ a = r('abc'); % Need to use temp
+ assert(length(a) == 3);
+ assert(strcmp(a(1), 'abc'));
+ assert(strcmp(a(2), 'de'));
+ assert(strcmp(a(3), 'fghi'));
+ a = r('def'); % Need to use temp
+ assert(length(a) == 2);
+ assert(strcmp(a(1), 'xyz'));
+ assert(strcmp(a(2), 'or'));
+ a = r('ghi'); % Need to use temp
+ assert(length(a) == 2);
+ assert(strcmp(a(1), 'and'));
+ assert(strcmp(a(2), 'xor'));
+
+ sdi1 = Test.MyEnumMyEnumSD.new();
+ sdi2 = Test.MyEnumMyEnumSD.new();
+
+ si1 = { Test.MyEnum.enum1, Test.MyEnum.enum1, Test.MyEnum.enum2 };
+ si2 = { Test.MyEnum.enum1, Test.MyEnum.enum2 };
+ si3 = { Test.MyEnum.enum3, Test.MyEnum.enum3 };
+
+ sdi1(int32(Test.MyEnum.enum3)) = si1;
+ sdi1(int32(Test.MyEnum.enum2)) = si2;
+ sdi2(int32(Test.MyEnum.enum1)) = si3;
+
+ [r, p3] = call(p, 'opMyEnumMyEnumSD', sdi1, sdi2);
+
+ assert(p3.Count == 1);
+ a = p3(int32(Test.MyEnum.enum1)); % Need to use temp
+ assert(length(a) == 2);
+ assert(a{1} == Test.MyEnum.enum3);
+ assert(a{2} == Test.MyEnum.enum3);
+ assert(r.Count== 3);
+ a = r(int32(Test.MyEnum.enum3)); % Need to use temp
+ assert(length(a) == 3);
+ assert(a{1} == Test.MyEnum.enum1);
+ assert(a{2} == Test.MyEnum.enum1);
+ assert(a{3} == Test.MyEnum.enum2);
+ a = r(int32(Test.MyEnum.enum2)); % Need to use temp
+ assert(length(a) == 2);
+ assert(a{1} == Test.MyEnum.enum1);
+ assert(a{2} == Test.MyEnum.enum2);
+ a = r(int32(Test.MyEnum.enum1)); % Need to use temp
+ assert(length(a) == 2);
+ assert(a{1} == Test.MyEnum.enum3);
+ assert(a{2} == Test.MyEnum.enum3);
+
+ lengths = [0, 1, 2, 126, 127, 128, 129, 253, 254, 255, 256, 257, 1000];
+
+ for l = lengths
+ s = zeros(1, l);
+ if l > 0
+ s(1:l) = (1:l);
+ end
+ r = call(p, 'opIntS', s);
+ assert(length(r) == l);
+ for j = 1:l
+ assert(r(j) == -j);
+ end
+ end
+
+ ctx = Ice.Context.new();
+ ctx('one') = 'ONE';
+ ctx('two') = 'TWO';
+ ctx('three') = 'THREE';
+
+ assert(p.ice_getContext().Count == 0);
+ r = call(p, 'opContext');
+ assert(~isequal(r, ctx));
+
+ r = call(p, 'opContext', ctx);
+ assert(p.ice_getContext().Count == 0);
+ assert(isequal(r, ctx));
+
+ p2 = Test.MyClassPrx.checkedCast(p.ice_context(ctx));
+ assert(isequal(p2.ice_getContext(), ctx));
+ r = p2.opContext();
+ assert(isequal(r, ctx));
+ r = p2.opContext(ctx);
+ assert(isequal(r, ctx));
+
+ %
+ % Test implicit context propagation
+ %
+%{
+ impls = {'Shared', 'PerThread'};
+ for i = 1:2
+ initData = app.createInitializationData();
+ initData.properties_ = communicator.getProperties().clone();
+ initData.properties_.setProperty('Ice.ImplicitContext', impls{i});
+
+ ic = app.initialize(initData);
+
+ ctx = Ice.Context.new();
+ ctx('one') = 'ONE';
+ ctx('two') = 'TWO';
+ ctx('three') = 'THREE';
+
+ p3 = Test.MyClassPrx.uncheckedCast(ic.stringToProxy(['test:', app.getTestEndpoint(0)]));
+
+ ic.getImplicitContext().setContext(ctx);
+ assert(isequal(ic.getImplicitContext().getContext(), ctx));
+ assert(isequal(p3.opContext(), ctx));
+
+ assert(!ic.getImplicitContext().containsKey('zero'));
+ r = ic.getImplicitContext().put('zero', 'ZERO');
+ assert(strcmp(r, ''));
+ assert(ic.getImplicitContext().containsKey('zero'));
+ assert(strcmp(ic.getImplicitContext().get('zero'), 'ZERO'));
+
+ ctx = ic.getImplicitContext().getContext();
+ assert(isequal(p3.opContext(), ctx));
+
+ prxContext = Ice.Context.new();
+ prxContext('one') = 'UN';
+ prxContext('four') = 'QUATRE';
+
+ combined = Ice.Context.new(ctx);
+ keys = prxContext.keys();
+ for j = 1:prxContext.Count
+ combined(keys{j}) = prxContext(keys{j});
+ end
+ assert(strcmp(combined('one'), 'UN'));
+
+ p3 = p3.ice_context(prxContext);
+
+ ic.getImplicitContext().setContext([]);
+ assert(isequal(p3.opContext(), prxContext));
+
+ ic.getImplicitContext().setContext(ctx);
+ assert(isequal(p3.opContext(), combined));
+
+ assert(strcmp(ic.getImplicitContext().remove('one'), 'ONE'));
+
+ ic.destroy();
+ end
+%}
+
+ d = 1278312346.0 / 13.0;
+ ds = zeros(1, 5);
+ for i = 1:5
+ ds(i) = d;
+ end
+ call(p, 'opDoubleMarshaling', d, ds);
+
+ call(p, 'opIdempotent');
+
+ call(p, 'opNonmutating');
+
+ assert(call(p, 'opByte1', hex2dec('FF')) == hex2dec('FF'));
+ assert(call(p, 'opShort1', hex2dec('7FFF')) == hex2dec('7FFF'));
+ assert(call(p, 'opInt1', hex2dec('7FFFFFFF')) == hex2dec('7FFFFFFF'));
+ %assert(call(p, 'opLong1', 0x7FFFFFFFFFFFFFFF) == 0x7FFFFFFFFFFFFFFF);
+ assert(call(p, 'opFloat1', 1.0) == single(1.0));
+ assert(call(p, 'opDouble1', 1.0) == 1.0);
+ assert(strcmp(call(p, 'opString1', 'opString1'), 'opString1'));
+ assert(length(call(p, 'opStringS1', {})) == 0);
+ empty = call(p, 'opByteBoolD1', []);
+ assert(empty.Count == 0);
+ assert(length(call(p, 'opStringS2', [])) == 0);
+ empty = call(p, 'opByteBoolD2', []);
+ assert(empty.Count == 0);
+
+ d = Test.MyDerivedClassPrx.uncheckedCast(p);
+ s = Test.MyStruct1();
+ s.tesT = 'Test.MyStruct1.s';
+ s.myClass = [];
+ s.myStruct1 = 'Test.MyStruct1.myStruct1';
+ s = call(d, 'opMyStruct1', s);
+ assert(strcmp(s.tesT, 'Test.MyStruct1.s'));
+ assert(isempty(s.myClass));
+ assert(strcmp(s.myStruct1, 'Test.MyStruct1.myStruct1'));
+
+ %{
+ c = new MyClass1();
+ c.tesT = 'Test.MyClass1.testT';
+ c.myClass = null;
+ c.myClass1 = 'Test.MyClass1.myClass1';
+ c = d.opMyClass1(c);
+ assert(c.tesT.equals('Test.MyClass1.testT'));
+ assert(c.myClass == null);
+ assert(c.myClass1.equals('Test.MyClass1.myClass1'));
+ %}
+ end
+ end
+end
+
+function varargout = call(p, op, varargin)
+ try
+ name = [op, 'Async'];
+ future = p.(name)(varargin{:});
+ assert(strcmp(future.Operation, op));
+ assert(~future.Read);
+ assert(future.wait());
+ assert(strcmp(future.State, 'finished'));
+ [varargout{1:nargout}] = future.fetchOutputs();
+ assert(future.Read);
+ catch ex
+ disp(getReport(ex, 'extended'));
+ assert(false);
+ end
+end
diff --git a/matlab/test/Ice/operations/generated/.gitignore b/matlab/test/Ice/operations/generated/.gitignore
new file mode 100644
index 00000000000..39af5887579
--- /dev/null
+++ b/matlab/test/Ice/operations/generated/.gitignore
@@ -0,0 +1 @@
+# Dummy file, so that git retains this otherwise empty directory.
diff --git a/slice/Ice/Connection.ice b/slice/Ice/Connection.ice
index fc48f8d159f..1a4b67da136 100644
--- a/slice/Ice/Connection.ice
+++ b/slice/Ice/Connection.ice
@@ -181,7 +181,7 @@ local enum ConnectionClose
* The user-level interface to a connection.
*
**/
-["php:internal"]
+["php:internal", "matlab:internal"]
local interface Connection
{
/**