Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 29 additions & 11 deletions ProxyStubGenerator/StubGenerator.py
Original file line number Diff line number Diff line change
Expand Up @@ -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("}")

Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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))
Expand Down
95 changes: 95 additions & 0 deletions tests/FunctionalTests/common/implementations/TestOptionalsImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,101 @@ namespace TestImplementation {
return Core::ERROR_NONE;
}

Core::hresult ProcessOptionalVector(
const Core::OptionalType<std::vector<uint8_t>>& input,
Core::OptionalType<std::vector<uint8_t>>& output) override
{
if (input.IsSet() == true) {
std::vector<uint8_t> data;
data.resize(input.Value().size());
std::transform(input.Value().begin(), input.Value().end(), data.begin(), [](uint8_t x) {
return static_cast<uint8_t>(x * 2);
});
output = std::move(data);
}
else {
output = Core::OptionalType<std::vector<uint8_t>>();
}
return Core::ERROR_NONE;
}

Core::hresult ProcessOptionalInlineVector(
Core::OptionalType<std::vector<uint8_t>>& data,
const bool unset) override
{
if (data.IsSet() == true) {
if (unset == true) {
data = Core::OptionalType<std::vector<uint8_t>>();
}
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<Compound>& input,
Core::OptionalType<Compound>& 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<uint8_t>(x * 2);
});

if (input.Value().optionalData.IsSet() == true) {
std::vector<uint8_t> 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<uint8_t>(x * 2);
});

cp.optionalData = std::move(data);
}

output = std::move(cp);
}
else {
output = Core::OptionalType<Compound>();
}
return Core::ERROR_NONE;
}

Core::hresult ProcessOptionalVectorInOptionalInlineStruct(
Core::OptionalType<Compound>& data,
const bool unset) override
{
if (data.IsSet() == true) {

if ((data.Value().optionalMagic.IsSet() == true) && (unset == true)) {
data.Value().optionalMagic = Core::OptionalType<string>();
}

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<std::vector<uint8_t>>();
}
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<uint32_t>& a,
const Core::OptionalType<uint32_t>& b,
Expand Down
31 changes: 31 additions & 0 deletions tests/FunctionalTests/common/interfaces/ITestOptionals.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,13 @@ namespace FunctionalTest {
struct EXTERNAL ITestOptionals : virtual public Core::IUnknown {
enum { ID = ID_TEST_OPTIONALS };

struct Compound {
string magic;
Core::OptionalType<string> optionalMagic;
std::vector<uint8_t> data /* @restrict:8 */;
Core::OptionalType<std::vector<uint8_t>> optionalData /* @restrict:8 */;
};

// ===== Optional input parameters =====

// @brief Add two numbers. When b is not set it defaults to 0.
Expand Down Expand Up @@ -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<std::vector<uint8_t>>& input /* @restrict:8 */,
Core::OptionalType<std::vector<uint8_t>>& 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<std::vector<uint8_t>>& data /* @inout @restrict:8 */,
const bool unset) = 0;

// @brief Process vector in a struct
virtual Core::hresult ProcessOptionalVectorInOptionalStruct(
const Core::OptionalType<Compound>& input,
Core::OptionalType<Compound>& output /* @out */) = 0;

// @brief Process a vector in a struct to the same struct
// @param unset Change a set optional to unset
virtual Core::hresult ProcessOptionalVectorInOptionalInlineStruct(
Core::OptionalType<Compound>& data /* @inout*/,
const bool unset) = 0;

// ===== Edge cases =====

// @brief Compute a result from up to three optional unsigned integers.
Expand Down
Loading
Loading