diff --git a/ProxyStubGenerator/StubGenerator.py b/ProxyStubGenerator/StubGenerator.py index 7eaf8394..2cb9bdff 100755 --- a/ProxyStubGenerator/StubGenerator.py +++ b/ProxyStubGenerator/StubGenerator.py @@ -1630,24 +1630,22 @@ def _EmitAssignment(p): elif p.is_dynamic_array: obj_name = p.name - if not p.suppress_type: - if p.optional: - obj_name = Normalize(obj_name + "Object__") - emit.Line("%s %s{};" % (p.optional.type_name, obj_name)) - else: - emit.Line("%s %s{};" % (p.type_name, obj_name)) + if p.optional: + obj_name = Normalize(p.name + "Object__") + emit.Line("%s %s{};" % (p.optional.type_name, obj_name)) + elif not p.suppress_type: + emit.Line("%s %s{};" % (p.type_name, obj_name)) length = EmitParam(interface, p.length, Normalize("%sSize" % obj_name)) ReadParameter(length) CheckRange(p, ("%s" % length.as_rvalue)) - emit.Line("%s.reserve(%s);" % (p.as_rvalue, length.as_rvalue)) - + emit.Line("%s.reserve(%s);" % (obj_name, length.as_rvalue)) index = chr(ord('i') + p.name.count('Item')) element = EmitParam(interface, p.element, Normalize(obj_name + "Item"), parent=p) emit.Line("for (%s %s = 0; %s < %s; %s++) {" % (p.length.type_name, index, index, length.as_rvalue, index)) emit.IndentInc() ReadParameter(element) - emit.Line("%s.push_back(std::move(%s));" % (p.as_rvalue, element.as_rvalue)) + emit.Line("%s.push_back(std::move(%s));" % (obj_name, element.as_rvalue)) emit.IndentDec() emit.Line("}") @@ -2320,18 +2318,33 @@ def ReadParameter(p, no_array=False, suppress_type=True): elif p.is_dynamic_array: length = EmitLength(interface, p.length, Normalize(p.name + "Size")) element = EmitParam(interface, p.element, Normalize(p.name + "Item"), parent=p) + + obj_name = p.as_rvalue + + if p.optional: + obj_name = Normalize(p.name + "Object__") + emit.Line("%s %s{};" % (p.optional.type_name, obj_name)) + emit.Line("%s{};" % (length.temporary_no_cv)) ReadParameter(length) - emit.Line("%s.reserve(%s);" % (p.as_rvalue, length.as_rvalue)) + + if not p.optional: + emit.Line("%s.clear();" % (p.as_rvalue)) + + emit.Line("%s.reserve(%s);" % (obj_name, length.as_rvalue)) + index = chr(ord('i') + p.name.count('Item')) emit.Line("for (%s %s = 0; %s < %s; %s++) {" % (p.length.type_name, index, index, length.as_rvalue, index)) emit.IndentInc() emit.Line("%s{};" % (element.temporary_no_cv)) ReadParameter(element) - emit.Line("%s.push_back(std::move(%s));" % (p.as_rvalue, element.as_rvalue)) + emit.Line("%s.push_back(std::move(%s));" % (obj_name, element.as_rvalue)) emit.IndentDec() emit.Line("}") + if p.optional: + emit.Line("%s = std::move(%s);" % (p.name, obj_name)) + elif p.is_buffer: CheckFrame(p) CheckSize(p) @@ -2385,6 +2398,11 @@ def _EmitAssignment(p): if p.optional and (not p.is_array or no_array): emit.IndentDec() emit.Line("}") + emit.Line("else {") + emit.IndentInc() + emit.Line("%s = %s();" % (p.name, p.type_name)) + emit.IndentDec() + emit.Line("}") if EMIT_TRACES: emit.Line('fprintf(stderr, "*** [%s proxy] ENTER: %s()\\n");' % (interface_name, method.name)) diff --git a/tests/FunctionalTests/common/implementations/TestOptionalsImpl.cpp b/tests/FunctionalTests/common/implementations/TestOptionalsImpl.cpp index 42fe0b5f..5bfe2165 100644 --- a/tests/FunctionalTests/common/implementations/TestOptionalsImpl.cpp +++ b/tests/FunctionalTests/common/implementations/TestOptionalsImpl.cpp @@ -120,6 +120,101 @@ namespace TestImplementation { return Core::ERROR_NONE; } + Core::hresult ProcessOptionalVector( + const Core::OptionalType>& input, + Core::OptionalType>& output) override + { + if (input.IsSet() == true) { + std::vector data; + data.resize(input.Value().size()); + std::transform(input.Value().begin(), input.Value().end(), data.begin(), [](uint8_t x) { + return static_cast(x * 2); + }); + output = std::move(data); + } + else { + output = Core::OptionalType>(); + } + return Core::ERROR_NONE; + } + + Core::hresult ProcessOptionalInlineVector( + Core::OptionalType>& data, + const bool unset) override + { + if (data.IsSet() == true) { + if (unset == true) { + data = Core::OptionalType>(); + } + else { + std::for_each(data.Value().begin(), data.Value().end(), [](uint8_t& num) { + num *= 2; + }); + } + } + return Core::ERROR_NONE; + } + + Core::hresult ProcessOptionalVectorInOptionalStruct( + const Core::OptionalType& input, + Core::OptionalType& output) override + { + if (input.IsSet() == true) { + Compound cp; + cp.magic = input.Value().magic; + cp.optionalMagic = input.Value().optionalMagic; + cp.data.resize(input.Value().data.size()); + + std::transform(input.Value().data.begin(), input.Value().data.end(), cp.data.begin(), [](uint8_t x) { + return static_cast(x * 2); + }); + + if (input.Value().optionalData.IsSet() == true) { + std::vector data; + data.resize(input.Value().optionalData.Value().size()); + std::transform(input.Value().optionalData.Value().begin(), input.Value().optionalData.Value().end(), data.begin(), [](uint8_t x) { + return static_cast(x * 2); + }); + + cp.optionalData = std::move(data); + } + + output = std::move(cp); + } + else { + output = Core::OptionalType(); + } + return Core::ERROR_NONE; + } + + virtual Core::hresult ProcessOptionalVectorInOptionalInlineStruct( + Core::OptionalType& data, + const bool unset) override + { + if (data.IsSet() == true) { + + if ((data.Value().optionalMagic.IsSet() == true) and (unset == true)) { + data.Value().optionalMagic = Core::OptionalType(); + } + + std::for_each(data.Value().data.begin(), data.Value().data.end(), [](uint8_t& num) { + num *= 2; + }); + + if (data.Value().optionalData.IsSet() == true) { + if (unset == true) { + data.Value().optionalData = Core::OptionalType>(); + } + else { + std::for_each(data.Value().optionalData.Value().begin(), data.Value().optionalData.Value().end(), [](uint8_t& num) { + num *= 2; + }); + } + } + } + return Core::ERROR_NONE; + } + Core::hresult AllOptional( const Core::OptionalType& a, const Core::OptionalType& b, diff --git a/tests/FunctionalTests/common/interfaces/ITestOptionals.h b/tests/FunctionalTests/common/interfaces/ITestOptionals.h index f88862ec..8a76bcab 100644 --- a/tests/FunctionalTests/common/interfaces/ITestOptionals.h +++ b/tests/FunctionalTests/common/interfaces/ITestOptionals.h @@ -31,6 +31,13 @@ namespace FunctionalTest { struct EXTERNAL ITestOptionals : virtual public Core::IUnknown { enum { ID = ID_TEST_OPTIONALS }; + struct Compound { + string magic; + Core::OptionalType optionalMagic; + std::vector data /* @restrict:8 */; + Core::OptionalType> optionalData /* @restrict:8 */; + }; + // ===== Optional input parameters ===== // @brief Add two numbers. When b is not set it defaults to 0. @@ -130,6 +137,30 @@ namespace FunctionalTest { const uint16_t maxOutputSize, uint16_t& written /* @out */) = 0; + // ===== Optional vectors ===== + + // @brief Process an input vector into an output vector. + virtual Core::hresult ProcessOptionalVector( + const Core::OptionalType>& input /* @restrict:8 */, + Core::OptionalType>& output /* @out @restrict:8 */) = 0; + + // @brief Process an input vector into same output vector. + // @param unset Change a set optional to unset + virtual Core::hresult ProcessOptionalInlineVector( + Core::OptionalType>& data /* @inout @restrict:8 */, + const bool unset) = 0; + + // @brief Process an vector in a struct + virtual Core::hresult ProcessOptionalVectorInOptionalStruct( + const Core::OptionalType& input, + Core::OptionalType& output /* @out */) = 0; + + // @brief Process an vector in a struct to the same struct + // @param unset Change a set optional to unset + virtual Core::hresult ProcessOptionalVectorInOptionalInlineStruct( + Core::OptionalType& data /* @inout*/, + const bool unset) = 0; + // ===== Edge cases ===== // @brief Compute a result from up to three optional unsigned integers. diff --git a/tests/FunctionalTests/common/interfaces/ProxyStubs_TestOptionals.cpp b/tests/FunctionalTests/common/interfaces/ProxyStubs_TestOptionals.cpp new file mode 100644 index 00000000..ff761d97 --- /dev/null +++ b/tests/FunctionalTests/common/interfaces/ProxyStubs_TestOptionals.cpp @@ -0,0 +1,1029 @@ +// +// generated automatically from "ITestOptionals.h" +// +// implements COM-RPC proxy stubs for: +// - class FunctionalTest::ITestOptionals +// + +#include "ITestOptionals.h" + +#include + +namespace Thunder { + +namespace ProxyStubs { + + PUSH_WARNING(DISABLE_WARNING_DEPRECATED_USE) + PUSH_WARNING(DISABLE_WARNING_TYPE_LIMITS) + + // ----------------------------------------------------------------- + // STUBS + // ----------------------------------------------------------------- + + // + // FunctionalTest::ITestOptionals interface stub definitions + // + // Methods: + // (0) virtual Core::hresult Add(const uint32_t, const Core::OptionalType&, uint32_t&) = 0 + // (1) virtual Core::hresult Multiply(const int32_t, const Core::OptionalType&, int32_t&) = 0 + // (2) virtual Core::hresult Concatenate(const string&, const Core::OptionalType&, string&) = 0 + // (3) virtual Core::hresult Divide(const uint32_t, const uint32_t, uint32_t&, Core::OptionalType&) = 0 + // (4) virtual Core::hresult ParseInt(const string&, int32_t&, Core::OptionalType&) = 0 + // (5) virtual Core::hresult Format(const string&, const Core::OptionalType&, const Core::OptionalType&, string&) = 0 + // (6) virtual Core::hresult Calculate(const int32_t, const Core::OptionalType&, const Core::OptionalType&, int32_t&) = 0 + // (7) virtual Core::hresult ProcessOptionalBuffer(const uint8_t*, const uint16_t, uint8_t*, const uint16_t, uint16_t&) = 0 + // (8) virtual Core::hresult ProcessOptionalVector(const Core::OptionalType>&, Core::OptionalType>&) = 0 + // (9) virtual Core::hresult ProcessOptionalInlineVector(Core::OptionalType>&, const bool) = 0 + // (10) virtual Core::hresult ProcessOptionalVectorInOptionalStruct(const Core::OptionalType&, Core::OptionalType&) = 0 + // (11) virtual Core::hresult ProcessOptionalVectorInOptionalInlineStruct(Core::OptionalType&, const bool) = 0 + // (12) virtual Core::hresult AllOptional(const Core::OptionalType&, const Core::OptionalType&, const Core::OptionalType&, uint32_t&) = 0 + // (13) virtual Core::hresult WithDefault(const string&, const Core::OptionalType&, string&) = 0 + // + + static ProxyStub::MethodHandler FunctionalTestTestOptionalsStubMethods[] = { + // (0) virtual Core::hresult Add(const uint32_t, const Core::OptionalType&, uint32_t&) = 0 + // + [](Core::ProxyType& /* channel */, Core::ProxyType& message) { + FunctionalTest::ITestOptionals* implementation = reinterpret_cast(message->Parameters().Implementation()); + ASSERT(implementation != nullptr); + + RPC::Data::Frame::Reader reader(message->Parameters().Reader()); + const uint32_t _a = reader.Number(); + Core::OptionalType _b{}; + if (reader.Boolean() == true) { + _b = reader.Number(); + } + + uint32_t _result{}; + + Core::hresult result = implementation->Add(_a, static_cast&>(_b), _result); + + RPC::Data::Frame::Writer writer(message->Response().Writer()); + writer.Number(result); + writer.Number(_result); + }, + + // (1) virtual Core::hresult Multiply(const int32_t, const Core::OptionalType&, int32_t&) = 0 + // + [](Core::ProxyType& /* channel */, Core::ProxyType& message) { + FunctionalTest::ITestOptionals* implementation = reinterpret_cast(message->Parameters().Implementation()); + ASSERT(implementation != nullptr); + + RPC::Data::Frame::Reader reader(message->Parameters().Reader()); + const int32_t _value = reader.Number(); + Core::OptionalType _multiplier{}; + if (reader.Boolean() == true) { + _multiplier = reader.Number(); + } + + int32_t _result{}; + + Core::hresult result = implementation->Multiply(_value, static_cast&>(_multiplier), _result); + + RPC::Data::Frame::Writer writer(message->Response().Writer()); + writer.Number(result); + writer.Number(_result); + }, + + // (2) virtual Core::hresult Concatenate(const string&, const Core::OptionalType&, string&) = 0 + // + [](Core::ProxyType& /* channel */, Core::ProxyType& message) { + FunctionalTest::ITestOptionals* implementation = reinterpret_cast(message->Parameters().Implementation()); + ASSERT(implementation != nullptr); + + RPC::Data::Frame::Reader reader(message->Parameters().Reader()); + const string _first = reader.Text(); + Core::OptionalType _second{}; + if (reader.Boolean() == true) { + _second = reader.Text(); + } + + string _result{}; + + Core::hresult result = implementation->Concatenate(static_cast(_first), static_cast&>(_second), _result); + + RPC::Data::Frame::Writer writer(message->Response().Writer()); + writer.Number(result); + writer.Text(_result); + }, + + // (3) virtual Core::hresult Divide(const uint32_t, const uint32_t, uint32_t&, Core::OptionalType&) = 0 + // + [](Core::ProxyType& /* channel */, Core::ProxyType& message) { + FunctionalTest::ITestOptionals* implementation = reinterpret_cast(message->Parameters().Implementation()); + ASSERT(implementation != nullptr); + + RPC::Data::Frame::Reader reader(message->Parameters().Reader()); + const uint32_t _dividend = reader.Number(); + const uint32_t _divisor = reader.Number(); + Core::OptionalType _remainder{}; + if (reader.Boolean() == true) { + _remainder = reader.Number(); + } + + uint32_t _quotient{}; + + Core::hresult result = implementation->Divide(_dividend, _divisor, _quotient, _remainder); + + RPC::Data::Frame::Writer writer(message->Response().Writer()); + writer.Number(result); + writer.Number(_quotient); + writer.Boolean(_remainder.IsSet()); + if (_remainder.IsSet() == true) { + writer.Number(_remainder.Value()); + } + }, + + // (4) virtual Core::hresult ParseInt(const string&, int32_t&, Core::OptionalType&) = 0 + // + [](Core::ProxyType& /* channel */, Core::ProxyType& message) { + FunctionalTest::ITestOptionals* implementation = reinterpret_cast(message->Parameters().Implementation()); + ASSERT(implementation != nullptr); + + RPC::Data::Frame::Reader reader(message->Parameters().Reader()); + const string _text = reader.Text(); + Core::OptionalType _success{}; + if (reader.Boolean() == true) { + _success = reader.Boolean(); + } + + int32_t _value{}; + + Core::hresult result = implementation->ParseInt(static_cast(_text), _value, _success); + + RPC::Data::Frame::Writer writer(message->Response().Writer()); + writer.Number(result); + writer.Number(_value); + writer.Boolean(_success.IsSet()); + if (_success.IsSet() == true) { + writer.Boolean(_success.Value()); + } + }, + + // (5) virtual Core::hresult Format(const string&, const Core::OptionalType&, const Core::OptionalType&, string&) = 0 + // + [](Core::ProxyType& /* channel */, Core::ProxyType& message) { + FunctionalTest::ITestOptionals* implementation = reinterpret_cast(message->Parameters().Implementation()); + ASSERT(implementation != nullptr); + + RPC::Data::Frame::Reader reader(message->Parameters().Reader()); + const string _text = reader.Text(); + Core::OptionalType _prefix{}; + if (reader.Boolean() == true) { + _prefix = reader.Text(); + } + Core::OptionalType _suffix{}; + if (reader.Boolean() == true) { + _suffix = reader.Text(); + } + + string _result{}; + + Core::hresult result = implementation->Format(static_cast(_text), static_cast&>(_prefix), static_cast&>(_suffix), _result); + + RPC::Data::Frame::Writer writer(message->Response().Writer()); + writer.Number(result); + writer.Text(_result); + }, + + // (6) virtual Core::hresult Calculate(const int32_t, const Core::OptionalType&, const Core::OptionalType&, int32_t&) = 0 + // + [](Core::ProxyType& /* channel */, Core::ProxyType& message) { + FunctionalTest::ITestOptionals* implementation = reinterpret_cast(message->Parameters().Implementation()); + ASSERT(implementation != nullptr); + + RPC::Data::Frame::Reader reader(message->Parameters().Reader()); + const int32_t _value = reader.Number(); + Core::OptionalType _min{}; + if (reader.Boolean() == true) { + _min = reader.Number(); + } + Core::OptionalType _max{}; + if (reader.Boolean() == true) { + _max = reader.Number(); + } + + int32_t _result{}; + + Core::hresult result = implementation->Calculate(_value, static_cast&>(_min), static_cast&>(_max), _result); + + RPC::Data::Frame::Writer writer(message->Response().Writer()); + writer.Number(result); + writer.Number(_result); + }, + + // (7) virtual Core::hresult ProcessOptionalBuffer(const uint8_t*, const uint16_t, uint8_t*, const uint16_t, uint16_t&) = 0 + // + [](Core::ProxyType& /* channel */, Core::ProxyType& message) { + FunctionalTest::ITestOptionals* implementation = reinterpret_cast(message->Parameters().Implementation()); + ASSERT(implementation != nullptr); + + RPC::Data::Frame::Reader reader(message->Parameters().Reader()); + const uint8_t* _input{}; + const uint16_t _inputSize = reader.LockBuffer(_input); + reader.UnlockBuffer(_inputSize); + const uint16_t _maxOutputSize = reader.Number(); + + uint16_t _written{}; + uint8_t* _output{}; + + if (_maxOutputSize != 0) { + _output = static_cast(ALLOCA(_maxOutputSize * sizeof(uint8_t))); + ASSERT(_output != nullptr); + } + + Core::hresult result = implementation->ProcessOptionalBuffer(_input, _inputSize, _output, _maxOutputSize, _written); + + RPC::Data::Frame::Writer writer(message->Response().Writer()); + writer.Number(result); + writer.Buffer(_written, _output); + }, + + // (8) virtual Core::hresult ProcessOptionalVector(const Core::OptionalType>&, Core::OptionalType>&) = 0 + // + [](Core::ProxyType& /* channel */, Core::ProxyType& message) { + FunctionalTest::ITestOptionals* implementation = reinterpret_cast(message->Parameters().Implementation()); + ASSERT(implementation != nullptr); + + RPC::Data::Frame::Reader reader(message->Parameters().Reader()); + Core::OptionalType> _input{}; + if (reader.Boolean() == true) { + std::vector _inputObject__{}; + uint8_t _inputObject__Size = reader.Number(); + ASSERT((_inputObject__Size >= 0) && (_inputObject__Size <= 8)); + _inputObject__.reserve(_inputObject__Size); + for (uint8_t i = 0; i < _inputObject__Size; i++) { + uint8_t _inputObject__Item = reader.Number(); + _inputObject__.push_back(std::move(_inputObject__Item)); + } + _input = std::move(_inputObject__); + } + + Core::OptionalType> _output{}; + + Core::hresult result = implementation->ProcessOptionalVector(static_cast>&>(_input), _output); + + RPC::Data::Frame::Writer writer(message->Response().Writer()); + writer.Number(result); + writer.Boolean(_output.IsSet()); + if (_output.IsSet() == true) { + writer.Number(_output.Value().size()); + for (uint8_t i = 0; i < _output.Value().size(); i++) { + writer.Number(_output.Value()[i]); + } + } + }, + + // (9) virtual Core::hresult ProcessOptionalInlineVector(Core::OptionalType>&, const bool) = 0 + // + [](Core::ProxyType& /* channel */, Core::ProxyType& message) { + FunctionalTest::ITestOptionals* implementation = reinterpret_cast(message->Parameters().Implementation()); + ASSERT(implementation != nullptr); + + RPC::Data::Frame::Reader reader(message->Parameters().Reader()); + Core::OptionalType> _data{}; + if (reader.Boolean() == true) { + std::vector _dataObject__{}; + uint8_t _dataObject__Size = reader.Number(); + ASSERT((_dataObject__Size >= 0) && (_dataObject__Size <= 8)); + _dataObject__.reserve(_dataObject__Size); + for (uint8_t i = 0; i < _dataObject__Size; i++) { + uint8_t _dataObject__Item = reader.Number(); + _dataObject__.push_back(std::move(_dataObject__Item)); + } + _data = std::move(_dataObject__); + } + const bool _unset = reader.Boolean(); + + Core::hresult result = implementation->ProcessOptionalInlineVector(_data, _unset); + + RPC::Data::Frame::Writer writer(message->Response().Writer()); + writer.Number(result); + writer.Boolean(_data.IsSet()); + if (_data.IsSet() == true) { + writer.Number(_data.Value().size()); + for (uint8_t i = 0; i < _data.Value().size(); i++) { + writer.Number(_data.Value()[i]); + } + } + }, + + // (10) virtual Core::hresult ProcessOptionalVectorInOptionalStruct(const Core::OptionalType&, Core::OptionalType&) = 0 + // + [](Core::ProxyType& /* channel */, Core::ProxyType& message) { + FunctionalTest::ITestOptionals* implementation = reinterpret_cast(message->Parameters().Implementation()); + ASSERT(implementation != nullptr); + + RPC::Data::Frame::Reader reader(message->Parameters().Reader()); + Core::OptionalType _input{}; + if (reader.Boolean() == true) { + FunctionalTest::ITestOptionals::Compound _inputObject__{}; + _inputObject__.magic = reader.Text(); + if (reader.Boolean() == true) { + _inputObject__.optionalMagic = reader.Text(); + } + uint8_t _inputObject___dataSize = reader.Number(); + ASSERT((_inputObject___dataSize >= 0) && (_inputObject___dataSize <= 8)); + _inputObject__.data.reserve(_inputObject___dataSize); + for (uint8_t i = 0; i < _inputObject___dataSize; i++) { + uint8_t _inputObject___dataItem = reader.Number(); + _inputObject__.data.push_back(std::move(_inputObject___dataItem)); + } + if (reader.Boolean() == true) { + std::vector _inputObject___optionalDataObject__{}; + uint8_t _inputObject___optionalDataObject__Size = reader.Number(); + ASSERT((_inputObject___optionalDataObject__Size >= 0) && (_inputObject___optionalDataObject__Size <= 8)); + _inputObject___optionalDataObject__.reserve(_inputObject___optionalDataObject__Size); + for (uint8_t i = 0; i < _inputObject___optionalDataObject__Size; i++) { + uint8_t _inputObject___optionalDataObject__Item = reader.Number(); + _inputObject___optionalDataObject__.push_back(std::move(_inputObject___optionalDataObject__Item)); + } + _inputObject__.optionalData = std::move(_inputObject___optionalDataObject__); + } + _input = std::move(_inputObject__); + } + + Core::OptionalType _output{}; + + Core::hresult result = implementation->ProcessOptionalVectorInOptionalStruct(static_cast&>(_input), _output); + + RPC::Data::Frame::Writer writer(message->Response().Writer()); + writer.Number(result); + writer.Boolean(_output.IsSet()); + if (_output.IsSet() == true) { + writer.Text(_output.Value().magic); + writer.Boolean(_output.Value().optionalMagic.IsSet()); + if (_output.Value().optionalMagic.IsSet() == true) { + writer.Text(_output.Value().optionalMagic.Value()); + } + writer.Number(_output.Value().data.size()); + for (uint8_t i = 0; i < _output.Value().data.size(); i++) { + writer.Number(_output.Value().data[i]); + } + writer.Boolean(_output.Value().optionalData.IsSet()); + if (_output.Value().optionalData.IsSet() == true) { + writer.Number(_output.Value().optionalData.Value().size()); + for (uint8_t i = 0; i < _output.Value().optionalData.Value().size(); i++) { + writer.Number(_output.Value().optionalData.Value()[i]); + } + } + } + }, + + // (11) virtual Core::hresult ProcessOptionalVectorInOptionalInlineStruct(Core::OptionalType&, const bool) = 0 + // + [](Core::ProxyType& /* channel */, Core::ProxyType& message) { + FunctionalTest::ITestOptionals* implementation = reinterpret_cast(message->Parameters().Implementation()); + ASSERT(implementation != nullptr); + + RPC::Data::Frame::Reader reader(message->Parameters().Reader()); + Core::OptionalType _data{}; + if (reader.Boolean() == true) { + FunctionalTest::ITestOptionals::Compound _dataObject__{}; + _dataObject__.magic = reader.Text(); + if (reader.Boolean() == true) { + _dataObject__.optionalMagic = reader.Text(); + } + uint8_t _dataObject___dataSize = reader.Number(); + ASSERT((_dataObject___dataSize >= 0) && (_dataObject___dataSize <= 8)); + _dataObject__.data.reserve(_dataObject___dataSize); + for (uint8_t i = 0; i < _dataObject___dataSize; i++) { + uint8_t _dataObject___dataItem = reader.Number(); + _dataObject__.data.push_back(std::move(_dataObject___dataItem)); + } + if (reader.Boolean() == true) { + std::vector _dataObject___optionalDataObject__{}; + uint8_t _dataObject___optionalDataObject__Size = reader.Number(); + ASSERT((_dataObject___optionalDataObject__Size >= 0) && (_dataObject___optionalDataObject__Size <= 8)); + _dataObject___optionalDataObject__.reserve(_dataObject___optionalDataObject__Size); + for (uint8_t i = 0; i < _dataObject___optionalDataObject__Size; i++) { + uint8_t _dataObject___optionalDataObject__Item = reader.Number(); + _dataObject___optionalDataObject__.push_back(std::move(_dataObject___optionalDataObject__Item)); + } + _dataObject__.optionalData = std::move(_dataObject___optionalDataObject__); + } + _data = std::move(_dataObject__); + } + const bool _unset = reader.Boolean(); + + Core::hresult result = implementation->ProcessOptionalVectorInOptionalInlineStruct(_data, _unset); + + RPC::Data::Frame::Writer writer(message->Response().Writer()); + writer.Number(result); + writer.Boolean(_data.IsSet()); + if (_data.IsSet() == true) { + writer.Text(_data.Value().magic); + writer.Boolean(_data.Value().optionalMagic.IsSet()); + if (_data.Value().optionalMagic.IsSet() == true) { + writer.Text(_data.Value().optionalMagic.Value()); + } + writer.Number(_data.Value().data.size()); + for (uint8_t i = 0; i < _data.Value().data.size(); i++) { + writer.Number(_data.Value().data[i]); + } + writer.Boolean(_data.Value().optionalData.IsSet()); + if (_data.Value().optionalData.IsSet() == true) { + writer.Number(_data.Value().optionalData.Value().size()); + for (uint8_t i = 0; i < _data.Value().optionalData.Value().size(); i++) { + writer.Number(_data.Value().optionalData.Value()[i]); + } + } + } + }, + + // (12) virtual Core::hresult AllOptional(const Core::OptionalType&, const Core::OptionalType&, const Core::OptionalType&, uint32_t&) = 0 + // + [](Core::ProxyType& /* channel */, Core::ProxyType& message) { + FunctionalTest::ITestOptionals* implementation = reinterpret_cast(message->Parameters().Implementation()); + ASSERT(implementation != nullptr); + + RPC::Data::Frame::Reader reader(message->Parameters().Reader()); + Core::OptionalType _a{}; + if (reader.Boolean() == true) { + _a = reader.Number(); + } + Core::OptionalType _b{}; + if (reader.Boolean() == true) { + _b = reader.Number(); + } + Core::OptionalType _c{}; + if (reader.Boolean() == true) { + _c = reader.Number(); + } + + uint32_t _result{}; + + Core::hresult result = implementation->AllOptional(static_cast&>(_a), static_cast&>(_b), static_cast&>(_c), _result); + + RPC::Data::Frame::Writer writer(message->Response().Writer()); + writer.Number(result); + writer.Number(_result); + }, + + // (13) virtual Core::hresult WithDefault(const string&, const Core::OptionalType&, string&) = 0 + // + [](Core::ProxyType& /* channel */, Core::ProxyType& message) { + FunctionalTest::ITestOptionals* implementation = reinterpret_cast(message->Parameters().Implementation()); + ASSERT(implementation != nullptr); + + RPC::Data::Frame::Reader reader(message->Parameters().Reader()); + const string _value = reader.Text(); + Core::OptionalType _uppercase{}; + if (reader.Boolean() == true) { + _uppercase = reader.Boolean(); + } + + string _result{}; + + Core::hresult result = implementation->WithDefault(static_cast(_value), static_cast&>(_uppercase), _result); + + RPC::Data::Frame::Writer writer(message->Response().Writer()); + writer.Number(result); + writer.Text(_result); + } + , nullptr + }; // FunctionalTestTestOptionalsStubMethods + + // ----------------------------------------------------------------- + // PROXIES + // ----------------------------------------------------------------- + + // + // FunctionalTest::ITestOptionals interface proxy definitions + // + // Methods: + // (0) virtual Core::hresult Add(const uint32_t, const Core::OptionalType&, uint32_t&) = 0 + // (1) virtual Core::hresult Multiply(const int32_t, const Core::OptionalType&, int32_t&) = 0 + // (2) virtual Core::hresult Concatenate(const string&, const Core::OptionalType&, string&) = 0 + // (3) virtual Core::hresult Divide(const uint32_t, const uint32_t, uint32_t&, Core::OptionalType&) = 0 + // (4) virtual Core::hresult ParseInt(const string&, int32_t&, Core::OptionalType&) = 0 + // (5) virtual Core::hresult Format(const string&, const Core::OptionalType&, const Core::OptionalType&, string&) = 0 + // (6) virtual Core::hresult Calculate(const int32_t, const Core::OptionalType&, const Core::OptionalType&, int32_t&) = 0 + // (7) virtual Core::hresult ProcessOptionalBuffer(const uint8_t*, const uint16_t, uint8_t*, const uint16_t, uint16_t&) = 0 + // (8) virtual Core::hresult ProcessOptionalVector(const Core::OptionalType>&, Core::OptionalType>&) = 0 + // (9) virtual Core::hresult ProcessOptionalInlineVector(Core::OptionalType>&, const bool) = 0 + // (10) virtual Core::hresult ProcessOptionalVectorInOptionalStruct(const Core::OptionalType&, Core::OptionalType&) = 0 + // (11) virtual Core::hresult ProcessOptionalVectorInOptionalInlineStruct(Core::OptionalType&, const bool) = 0 + // (12) virtual Core::hresult AllOptional(const Core::OptionalType&, const Core::OptionalType&, const Core::OptionalType&, uint32_t&) = 0 + // (13) virtual Core::hresult WithDefault(const string&, const Core::OptionalType&, string&) = 0 + // + + class FunctionalTestTestOptionalsProxy final : public ProxyStub::UnknownProxyType { + public: + FunctionalTestTestOptionalsProxy(const Core::ProxyType& channel, const Core::instance_id implementation, const bool otherSideInformed) + : BaseClass(channel, implementation, otherSideInformed) + { + } + + Core::hresult Add(const uint32_t _a, const Core::OptionalType& _b, uint32_t& _result) override + { + IPCMessage message(static_cast(*this).Message(0)); + + RPC::Data::Frame::Writer writer(message->Parameters().Writer()); + writer.Number(_a); + writer.Boolean(_b.IsSet()); + if (_b.IsSet() == true) { + writer.Number(_b.Value()); + } + + Core::hresult hresult = static_cast(*this).Invoke(message); + if (hresult == Core::ERROR_NONE) { + RPC::Data::Frame::Reader reader(message->Response().Reader()); + hresult = reader.Number(); + _result = reader.Number(); + } else { + ASSERT((hresult & COM_ERROR) != 0); + } + + return (hresult); + } + + Core::hresult Multiply(const int32_t _value, const Core::OptionalType& _multiplier, int32_t& _result) override + { + IPCMessage message(static_cast(*this).Message(1)); + + RPC::Data::Frame::Writer writer(message->Parameters().Writer()); + writer.Number(_value); + writer.Boolean(_multiplier.IsSet()); + if (_multiplier.IsSet() == true) { + writer.Number(_multiplier.Value()); + } + + Core::hresult hresult = static_cast(*this).Invoke(message); + if (hresult == Core::ERROR_NONE) { + RPC::Data::Frame::Reader reader(message->Response().Reader()); + hresult = reader.Number(); + _result = reader.Number(); + } else { + ASSERT((hresult & COM_ERROR) != 0); + } + + return (hresult); + } + + Core::hresult Concatenate(const string& _first, const Core::OptionalType& _second, string& _result) override + { + IPCMessage message(static_cast(*this).Message(2)); + + RPC::Data::Frame::Writer writer(message->Parameters().Writer()); + writer.Text(_first); + writer.Boolean(_second.IsSet()); + if (_second.IsSet() == true) { + writer.Text(_second.Value()); + } + + Core::hresult hresult = static_cast(*this).Invoke(message); + if (hresult == Core::ERROR_NONE) { + RPC::Data::Frame::Reader reader(message->Response().Reader()); + hresult = reader.Number(); + _result = reader.Text(); + } else { + ASSERT((hresult & COM_ERROR) != 0); + } + + return (hresult); + } + + Core::hresult Divide(const uint32_t _dividend, const uint32_t _divisor, uint32_t& _quotient, Core::OptionalType& _remainder) override + { + IPCMessage message(static_cast(*this).Message(3)); + + RPC::Data::Frame::Writer writer(message->Parameters().Writer()); + writer.Number(_dividend); + writer.Number(_divisor); + writer.Boolean(_remainder.IsSet()); + if (_remainder.IsSet() == true) { + writer.Number(_remainder.Value()); + } + + Core::hresult hresult = static_cast(*this).Invoke(message); + if (hresult == Core::ERROR_NONE) { + RPC::Data::Frame::Reader reader(message->Response().Reader()); + hresult = reader.Number(); + _quotient = reader.Number(); + if (reader.Boolean() == true) { + _remainder = reader.Number(); + } + else { + _remainder = Core::OptionalType(); + } + } else { + ASSERT((hresult & COM_ERROR) != 0); + } + + return (hresult); + } + + Core::hresult ParseInt(const string& _text, int32_t& _value, Core::OptionalType& _success) override + { + IPCMessage message(static_cast(*this).Message(4)); + + RPC::Data::Frame::Writer writer(message->Parameters().Writer()); + writer.Text(_text); + writer.Boolean(_success.IsSet()); + if (_success.IsSet() == true) { + writer.Boolean(_success.Value()); + } + + Core::hresult hresult = static_cast(*this).Invoke(message); + if (hresult == Core::ERROR_NONE) { + RPC::Data::Frame::Reader reader(message->Response().Reader()); + hresult = reader.Number(); + _value = reader.Number(); + if (reader.Boolean() == true) { + _success = reader.Boolean(); + } + else { + _success = Core::OptionalType(); + } + } else { + ASSERT((hresult & COM_ERROR) != 0); + } + + return (hresult); + } + + Core::hresult Format(const string& _text, const Core::OptionalType& _prefix, const Core::OptionalType& _suffix, string& _result) override + { + IPCMessage message(static_cast(*this).Message(5)); + + RPC::Data::Frame::Writer writer(message->Parameters().Writer()); + writer.Text(_text); + writer.Boolean(_prefix.IsSet()); + if (_prefix.IsSet() == true) { + writer.Text(_prefix.Value()); + } + writer.Boolean(_suffix.IsSet()); + if (_suffix.IsSet() == true) { + writer.Text(_suffix.Value()); + } + + Core::hresult hresult = static_cast(*this).Invoke(message); + if (hresult == Core::ERROR_NONE) { + RPC::Data::Frame::Reader reader(message->Response().Reader()); + hresult = reader.Number(); + _result = reader.Text(); + } else { + ASSERT((hresult & COM_ERROR) != 0); + } + + return (hresult); + } + + Core::hresult Calculate(const int32_t _value, const Core::OptionalType& _min, const Core::OptionalType& _max, int32_t& _result) override + { + IPCMessage message(static_cast(*this).Message(6)); + + RPC::Data::Frame::Writer writer(message->Parameters().Writer()); + writer.Number(_value); + writer.Boolean(_min.IsSet()); + if (_min.IsSet() == true) { + writer.Number(_min.Value()); + } + writer.Boolean(_max.IsSet()); + if (_max.IsSet() == true) { + writer.Number(_max.Value()); + } + + Core::hresult hresult = static_cast(*this).Invoke(message); + if (hresult == Core::ERROR_NONE) { + RPC::Data::Frame::Reader reader(message->Response().Reader()); + hresult = reader.Number(); + _result = reader.Number(); + } else { + ASSERT((hresult & COM_ERROR) != 0); + } + + return (hresult); + } + + Core::hresult ProcessOptionalBuffer(const uint8_t* _input, const uint16_t _inputSize, uint8_t* _output, const uint16_t _maxOutputSize, uint16_t& _written) override + { + IPCMessage message(static_cast(*this).Message(7)); + + RPC::Data::Frame::Writer writer(message->Parameters().Writer()); + writer.Buffer(_inputSize, _input); + writer.Number(_maxOutputSize); + + Core::hresult hresult = static_cast(*this).Invoke(message); + if (hresult == Core::ERROR_NONE) { + RPC::Data::Frame::Reader reader(message->Response().Reader()); + hresult = reader.Number(); + _written = reader.Buffer(_maxOutputSize, _output); + } else { + ASSERT((hresult & COM_ERROR) != 0); + } + + return (hresult); + } + + Core::hresult ProcessOptionalVector(const Core::OptionalType>& _input, Core::OptionalType>& _output) override + { + IPCMessage message(static_cast(*this).Message(8)); + + RPC::Data::Frame::Writer writer(message->Parameters().Writer()); + writer.Boolean(_input.IsSet()); + if (_input.IsSet() == true) { + writer.Number(_input.Value().size()); + for (uint8_t i = 0; i < _input.Value().size(); i++) { + writer.Number(_input.Value()[i]); + } + } + + Core::hresult hresult = static_cast(*this).Invoke(message); + if (hresult == Core::ERROR_NONE) { + RPC::Data::Frame::Reader reader(message->Response().Reader()); + hresult = reader.Number(); + if (reader.Boolean() == true) { + std::vector _outputObject__{}; + uint8_t _outputSize{}; + _outputSize = reader.Number(); + _outputObject__.reserve(_outputSize); + for (uint8_t i = 0; i < _outputSize; i++) { + uint8_t _outputItem{}; + _outputItem = reader.Number(); + _outputObject__.push_back(std::move(_outputItem)); + } + _output = std::move(_outputObject__); + } + else { + _output = Core::OptionalType>(); + } + } else { + ASSERT((hresult & COM_ERROR) != 0); + } + + return (hresult); + } + + Core::hresult ProcessOptionalInlineVector(Core::OptionalType>& _data, const bool _unset) override + { + IPCMessage message(static_cast(*this).Message(9)); + + RPC::Data::Frame::Writer writer(message->Parameters().Writer()); + writer.Boolean(_data.IsSet()); + if (_data.IsSet() == true) { + writer.Number(_data.Value().size()); + for (uint8_t i = 0; i < _data.Value().size(); i++) { + writer.Number(_data.Value()[i]); + } + } + writer.Boolean(_unset); + + Core::hresult hresult = static_cast(*this).Invoke(message); + if (hresult == Core::ERROR_NONE) { + RPC::Data::Frame::Reader reader(message->Response().Reader()); + hresult = reader.Number(); + if (reader.Boolean() == true) { + std::vector _dataObject__{}; + uint8_t _dataSize{}; + _dataSize = reader.Number(); + _dataObject__.reserve(_dataSize); + for (uint8_t i = 0; i < _dataSize; i++) { + uint8_t _dataItem{}; + _dataItem = reader.Number(); + _dataObject__.push_back(std::move(_dataItem)); + } + _data = std::move(_dataObject__); + } + else { + _data = Core::OptionalType>(); + } + } else { + ASSERT((hresult & COM_ERROR) != 0); + } + + return (hresult); + } + + Core::hresult ProcessOptionalVectorInOptionalStruct(const Core::OptionalType& _input, Core::OptionalType& _output) override + { + IPCMessage message(static_cast(*this).Message(10)); + + RPC::Data::Frame::Writer writer(message->Parameters().Writer()); + writer.Boolean(_input.IsSet()); + if (_input.IsSet() == true) { + writer.Text(_input.Value().magic); + writer.Boolean(_input.Value().optionalMagic.IsSet()); + if (_input.Value().optionalMagic.IsSet() == true) { + writer.Text(_input.Value().optionalMagic.Value()); + } + writer.Number(_input.Value().data.size()); + for (uint8_t i = 0; i < _input.Value().data.size(); i++) { + writer.Number(_input.Value().data[i]); + } + writer.Boolean(_input.Value().optionalData.IsSet()); + if (_input.Value().optionalData.IsSet() == true) { + writer.Number(_input.Value().optionalData.Value().size()); + for (uint8_t i = 0; i < _input.Value().optionalData.Value().size(); i++) { + writer.Number(_input.Value().optionalData.Value()[i]); + } + } + } + + Core::hresult hresult = static_cast(*this).Invoke(message); + if (hresult == Core::ERROR_NONE) { + RPC::Data::Frame::Reader reader(message->Response().Reader()); + hresult = reader.Number(); + if (reader.Boolean() == true) { + FunctionalTest::ITestOptionals::Compound _outputObject__{}; + _outputObject__.magic = reader.Text(); + if (reader.Boolean() == true) { + _outputObject__.optionalMagic = reader.Text(); + } + else { + _outputObject__.optionalMagic = Core::OptionalType(); + } + uint8_t _outputObject___dataSize{}; + _outputObject___dataSize = reader.Number(); + _outputObject__.data.clear(); + _outputObject__.data.reserve(_outputObject___dataSize); + for (uint8_t i = 0; i < _outputObject___dataSize; i++) { + uint8_t _outputObject___dataItem{}; + _outputObject___dataItem = reader.Number(); + _outputObject__.data.push_back(std::move(_outputObject___dataItem)); + } + if (reader.Boolean() == true) { + std::vector _outputObject___optionalDataObject__{}; + uint8_t _outputObject___optionalDataSize{}; + _outputObject___optionalDataSize = reader.Number(); + _outputObject___optionalDataObject__.reserve(_outputObject___optionalDataSize); + for (uint8_t i = 0; i < _outputObject___optionalDataSize; i++) { + uint8_t _outputObject___optionalDataItem{}; + _outputObject___optionalDataItem = reader.Number(); + _outputObject___optionalDataObject__.push_back(std::move(_outputObject___optionalDataItem)); + } + _outputObject__.optionalData = std::move(_outputObject___optionalDataObject__); + } + else { + _outputObject__.optionalData = Core::OptionalType>(); + } + _output = std::move(_outputObject__); + } + else { + _output = Core::OptionalType(); + } + } else { + ASSERT((hresult & COM_ERROR) != 0); + } + + return (hresult); + } + + Core::hresult ProcessOptionalVectorInOptionalInlineStruct(Core::OptionalType& _data, const bool _unset) override + { + IPCMessage message(static_cast(*this).Message(11)); + + RPC::Data::Frame::Writer writer(message->Parameters().Writer()); + writer.Boolean(_data.IsSet()); + if (_data.IsSet() == true) { + writer.Text(_data.Value().magic); + writer.Boolean(_data.Value().optionalMagic.IsSet()); + if (_data.Value().optionalMagic.IsSet() == true) { + writer.Text(_data.Value().optionalMagic.Value()); + } + writer.Number(_data.Value().data.size()); + for (uint8_t i = 0; i < _data.Value().data.size(); i++) { + writer.Number(_data.Value().data[i]); + } + writer.Boolean(_data.Value().optionalData.IsSet()); + if (_data.Value().optionalData.IsSet() == true) { + writer.Number(_data.Value().optionalData.Value().size()); + for (uint8_t i = 0; i < _data.Value().optionalData.Value().size(); i++) { + writer.Number(_data.Value().optionalData.Value()[i]); + } + } + } + writer.Boolean(_unset); + + Core::hresult hresult = static_cast(*this).Invoke(message); + if (hresult == Core::ERROR_NONE) { + RPC::Data::Frame::Reader reader(message->Response().Reader()); + hresult = reader.Number(); + if (reader.Boolean() == true) { + FunctionalTest::ITestOptionals::Compound _dataObject__{}; + _dataObject__.magic = reader.Text(); + if (reader.Boolean() == true) { + _dataObject__.optionalMagic = reader.Text(); + } + else { + _dataObject__.optionalMagic = Core::OptionalType(); + } + uint8_t _dataObject___dataSize{}; + _dataObject___dataSize = reader.Number(); + _dataObject__.data.clear(); + _dataObject__.data.reserve(_dataObject___dataSize); + for (uint8_t i = 0; i < _dataObject___dataSize; i++) { + uint8_t _dataObject___dataItem{}; + _dataObject___dataItem = reader.Number(); + _dataObject__.data.push_back(std::move(_dataObject___dataItem)); + } + if (reader.Boolean() == true) { + std::vector _dataObject___optionalDataObject__{}; + uint8_t _dataObject___optionalDataSize{}; + _dataObject___optionalDataSize = reader.Number(); + _dataObject___optionalDataObject__.reserve(_dataObject___optionalDataSize); + for (uint8_t i = 0; i < _dataObject___optionalDataSize; i++) { + uint8_t _dataObject___optionalDataItem{}; + _dataObject___optionalDataItem = reader.Number(); + _dataObject___optionalDataObject__.push_back(std::move(_dataObject___optionalDataItem)); + } + _dataObject__.optionalData = std::move(_dataObject___optionalDataObject__); + } + else { + _dataObject__.optionalData = Core::OptionalType>(); + } + _data = std::move(_dataObject__); + } + else { + _data = Core::OptionalType(); + } + } else { + ASSERT((hresult & COM_ERROR) != 0); + } + + return (hresult); + } + + Core::hresult AllOptional(const Core::OptionalType& _a, const Core::OptionalType& _b, const Core::OptionalType& _c, uint32_t& _result) override + { + IPCMessage message(static_cast(*this).Message(12)); + + RPC::Data::Frame::Writer writer(message->Parameters().Writer()); + writer.Boolean(_a.IsSet()); + if (_a.IsSet() == true) { + writer.Number(_a.Value()); + } + writer.Boolean(_b.IsSet()); + if (_b.IsSet() == true) { + writer.Number(_b.Value()); + } + writer.Boolean(_c.IsSet()); + if (_c.IsSet() == true) { + writer.Number(_c.Value()); + } + + Core::hresult hresult = static_cast(*this).Invoke(message); + if (hresult == Core::ERROR_NONE) { + RPC::Data::Frame::Reader reader(message->Response().Reader()); + hresult = reader.Number(); + _result = reader.Number(); + } else { + ASSERT((hresult & COM_ERROR) != 0); + } + + return (hresult); + } + + Core::hresult WithDefault(const string& _value, const Core::OptionalType& _uppercase, string& _result) override + { + IPCMessage message(static_cast(*this).Message(13)); + + RPC::Data::Frame::Writer writer(message->Parameters().Writer()); + writer.Text(_value); + writer.Boolean(_uppercase.IsSet()); + if (_uppercase.IsSet() == true) { + writer.Boolean(_uppercase.Value()); + } + + Core::hresult hresult = static_cast(*this).Invoke(message); + if (hresult == Core::ERROR_NONE) { + RPC::Data::Frame::Reader reader(message->Response().Reader()); + hresult = reader.Number(); + _result = reader.Text(); + } else { + ASSERT((hresult & COM_ERROR) != 0); + } + + return (hresult); + } + + }; // class FunctionalTestTestOptionalsProxy + + POP_WARNING() + POP_WARNING() + + // ----------------------------------------------------------------- + // REGISTRATION + // ----------------------------------------------------------------- + namespace { + + typedef ProxyStub::UnknownStubType FunctionalTestTestOptionalsStub; + + static class Instantiation { + public: + Instantiation() + { + RPC::Administrator::Instance().Announce(); + } + ~Instantiation() + { + RPC::Administrator::Instance().Recall(); + } + } ProxyStubRegistration; + + } // namespace + +} // namespace ProxyStubs + +} diff --git a/tests/FunctionalTests/comrpc/tests/TestOptionals.cpp b/tests/FunctionalTests/comrpc/tests/TestOptionals.cpp index 647069b1..642caa98 100644 --- a/tests/FunctionalTests/comrpc/tests/TestOptionals.cpp +++ b/tests/FunctionalTests/comrpc/tests/TestOptionals.cpp @@ -196,6 +196,194 @@ TEST_F(TestOptionals, ProcessOptionalBuffer_NoOutput) { EXPECT_EQ(written, 0u); } +// ===== Optional vector ===== + +TEST_F(TestOptionals, ProcessOptionalVector_Set) { + // Set optional vector round trip. + std::vector input{ 1,2,3,4 }; + Core::OptionalType> optOutput; + Core::OptionalType> optInput; + optInput = input; + ASSERT_EQ(_proxy->ProcessOptionalVector(optInput, optOutput), Core::ERROR_NONE); + EXPECT_EQ(optOutput.IsSet(), true); + EXPECT_EQ(optOutput.Value().size(), input.size()); + if (optOutput.Value().size() == input.size()) { + // process multiplies by 2 + for (uint8_t i = 0; i < input.size(); i++) { + EXPECT_EQ(optOutput.Value()[i], input[i]*2); + } + } +} + +TEST_F(TestOptionals, ProcessOptionalVector_Unset) { + // Unset optional vector round trip. + Core::OptionalType> optOutput; + Core::OptionalType> optInput; + ASSERT_EQ(_proxy->ProcessOptionalVector(optInput, optOutput), Core::ERROR_NONE); + EXPECT_EQ(optOutput.IsSet(), false); +} + +TEST_F(TestOptionals, ProcessOptionalInlineVector_Set) { + // Set optional vector round trip to the same vector parameter. + std::vector data{ 1,2,3,4 }; + Core::OptionalType> optData; + optData = data; // copy! + ASSERT_EQ(_proxy->ProcessOptionalInlineVector(optData, false), Core::ERROR_NONE); + EXPECT_EQ(optData.IsSet(), true); + EXPECT_EQ(optData.Value().size(), data.size()); + if (optData.Value().size() == data.size()) { + // process multiplies by 2 + for (uint8_t i = 0; i < data.size(); i++) { + EXPECT_EQ(optData.Value()[i], data[i]*2); + } + } +} + +TEST_F(TestOptionals, ProcessOptionalInlineVector_Unset) { + // Unset optional vector round trip to the same vector parameter. + Core::OptionalType> optData; + ASSERT_EQ(_proxy->ProcessOptionalInlineVector(optData, false), Core::ERROR_NONE); + EXPECT_EQ(optData.IsSet(), false); +} + +TEST_F(TestOptionals, ProcessOptionalInlineVector_SetToUnset) { + // Set optional vector change into unset in the same vector parameter. + std::vector data{ 1,2,3,4 }; + Core::OptionalType> optData; + optData = data; + ASSERT_EQ(_proxy->ProcessOptionalInlineVector(optData, true /* change setbit! */), Core::ERROR_NONE); + EXPECT_EQ(optData.IsSet(), false); +} + +TEST_F(TestOptionals, ProcessOptionalVectorInStruct_Set) { + // Set optional vector in a struct round trip. + ITestOptionals::Compound data; + data.magic = "hokus"; + data.optionalMagic = "pokus"; + data.data = { 1,2,3,4 }; + data.optionalData = { 11,12,13,14 }; + Core::OptionalType optOutput; + Core::OptionalType optInput; + optInput = data; // copy! + ASSERT_EQ(_proxy->ProcessOptionalVectorInOptionalStruct(optInput, optOutput), Core::ERROR_NONE); + EXPECT_EQ(optOutput.IsSet(), true); + EXPECT_EQ(optOutput.Value().magic, data.magic); + EXPECT_EQ(optOutput.Value().optionalMagic.IsSet(), true); + EXPECT_EQ(optOutput.Value().optionalMagic.Value(), data.optionalMagic.Value()); + EXPECT_EQ(optOutput.Value().data.size(), data.data.size()); + if (optOutput.Value().data.size() == data.data.size()) { + // process multiplies by 2 + for (uint8_t i = 0; i < data.data.size(); i++) { + EXPECT_EQ(optOutput.Value().data[i], data.data[i]*2); + } + } + EXPECT_EQ(optOutput.Value().optionalData.IsSet(), true); + EXPECT_EQ(optOutput.Value().optionalData.Value().size(), data.optionalData.Value().size()); + if (optOutput.Value().optionalData.Value().size() == data.optionalData.Value().size()) { + // process multiplies by 2 + for (uint8_t i = 0; i < data.optionalData.Value().size(); i++) { + EXPECT_EQ(optOutput.Value().optionalData.Value()[i], data.optionalData.Value()[i]*2); + } + } +} + +TEST_F(TestOptionals, ProcessOptionalVectorInStruct_Unset) { + // Unset optional vector in a struct round trip. + ITestOptionals::Compound data; + data.magic = "hokus"; + data.data = { 1,2,3,4 }; + Core::OptionalType optOutput; + Core::OptionalType optInput; + optInput = data; + ASSERT_EQ(_proxy->ProcessOptionalVectorInOptionalStruct(optInput, optOutput), Core::ERROR_NONE); + EXPECT_EQ(optOutput.IsSet(), true); + EXPECT_EQ(optOutput.Value().magic, data.magic); + EXPECT_EQ(optOutput.Value().optionalMagic.IsSet(), false); + EXPECT_EQ(optOutput.Value().data.size(), data.data.size()); + if (optOutput.Value().data.size() == data.data.size()) { + // process multiplies by 2 + for (uint8_t i = 0; i < data.data.size(); i++) { + EXPECT_EQ(optOutput.Value().data[i], data.data[i]*2); + } + } + EXPECT_EQ(optOutput.Value().optionalData.IsSet(), false); +} + +TEST_F(TestOptionals, ProcessOptionalInlineVectorInStruct_Set) { + // Set optional vector in a struct round trip to the same vector parameter. + ITestOptionals::Compound data; + data.magic = "hokus"; + data.optionalMagic = "pokus"; + data.data = { 1,2,3,4 }; + data.optionalData = { 11,12,13,14 }; + Core::OptionalType optData; + optData = data; // copy! + ASSERT_EQ(_proxy->ProcessOptionalVectorInOptionalInlineStruct(optData, false), Core::ERROR_NONE); + EXPECT_EQ(optData.IsSet(), true); + EXPECT_EQ(optData.Value().magic, data.magic); + EXPECT_EQ(optData.Value().optionalMagic.IsSet(), true); + EXPECT_EQ(optData.Value().optionalMagic.Value(), data.optionalMagic.Value()); + EXPECT_EQ(optData.Value().data.size(), data.data.size()); + if (optData.Value().data.size() == data.data.size()) { + // process multiplies by 2 + for (uint8_t i = 0; i < data.data.size(); i++) { + EXPECT_EQ(optData.Value().data[i], data.data[i]*2); + } + } + EXPECT_EQ(optData.Value().optionalData.IsSet(), true); + EXPECT_EQ(optData.Value().optionalData.Value().size(), data.optionalData.Value().size()); + if (optData.Value().optionalData.Value().size() == data.optionalData.Value().size()) { + // process multiplies by 2 + for (uint8_t i = 0; i < data.optionalData.Value().size(); i++) { + EXPECT_EQ(optData.Value().optionalData.Value()[i], data.optionalData.Value()[i]*2); + } + } +} + +TEST_F(TestOptionals, ProcessOptionalInlineVectorInStruct_Unset) { + // Unset optional vector in a struct round trip to the same vector sparameter. + ITestOptionals::Compound data; + data.magic = "hokus"; + data.data = { 1,2,3,4 }; + Core::OptionalType optData; + optData = data; // copy! + ASSERT_EQ(_proxy->ProcessOptionalVectorInOptionalInlineStruct(optData, false), Core::ERROR_NONE); + EXPECT_EQ(optData.IsSet(), true); + EXPECT_EQ(optData.Value().magic, data.magic); + EXPECT_EQ(optData.Value().optionalMagic.IsSet(), false); + EXPECT_EQ(optData.Value().data.size(), data.data.size()); + if (optData.Value().data.size() == data.data.size()) { + // process multiplies by 2 + for (uint8_t i = 0; i < data.data.size(); i++) { + EXPECT_EQ(optData.Value().data[i], data.data[i]*2); + } + } + EXPECT_EQ(optData.Value().optionalData.IsSet(), false); +} + +TEST_F(TestOptionals, ProcessOptionalInlineVectorInStruct_SetToUnset) { + // Set optional vector in a struct change to unset in the same vector parameter. + ITestOptionals::Compound data; + data.magic = "hokus"; + data.optionalMagic = "pokus"; + data.data = { 1,2,3,4 }; + data.optionalData = { 11,12,13,14 }; + Core::OptionalType optData; + optData = data; // copy! + ASSERT_EQ(_proxy->ProcessOptionalVectorInOptionalInlineStruct(optData, true /* change setbit! */), Core::ERROR_NONE); + EXPECT_EQ(optData.IsSet(), true); + EXPECT_EQ(optData.Value().magic, data.magic); + EXPECT_EQ(optData.Value().optionalMagic.IsSet(), false); + EXPECT_EQ(optData.Value().data.size(), data.data.size()); + if (optData.Value().data.size() == data.data.size()) { + // process multiplies by 2 + for (uint8_t i = 0; i < data.data.size(); i++) { + EXPECT_EQ(optData.Value().data[i], data.data[i]*2); + } + } + EXPECT_EQ(optData.Value().optionalData.IsSet(), false); +} + // ===== AllOptional ===== TEST_F(TestOptionals, AllOptional_AllUnset) {