blob: 8ad4452b385ed89a0b90ff3a2ba071d8bf650b74 [file] [log] [blame]
// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <fidl/test/compatibility/cpp/fidl.h>
#include <lib/async-loop/cpp/loop.h>
#include <lib/async-loop/default.h>
#include <lib/fidl/cpp/binding_set.h>
#include <lib/fidl/cpp/interface_request.h>
#include <lib/sys/cpp/component_context.h>
#include <lib/syslog/cpp/macros.h>
#include <lib/zx/channel.h>
#include <zircon/types.h>
#include <cstdlib>
#include <string>
#include "fidl/test/imported/cpp/fidl.h"
#include "src/tests/fidl/compatibility/hlcpp_client_app.h"
namespace fidl {
namespace test {
namespace compatibility {
class EchoServerApp : public Echo {
public:
explicit EchoServerApp(async::Loop* loop)
: loop_(loop), context_(sys::ComponentContext::CreateAndServeOutgoingDirectory()) {
context_->outgoing()->AddPublicService(bindings_.GetHandler(this));
}
~EchoServerApp() {}
void EchoMinimal(std::string forward_to_server, EchoMinimalCallback callback) override {
if (!forward_to_server.empty()) {
EchoClientApp app;
bool failed = false;
app.echo().set_error_handler([this, &forward_to_server, &failed](zx_status_t status) {
failed = true;
loop_->Quit();
FX_LOGS(ERROR) << "error communicating with " << forward_to_server << ": " << status;
});
app.Start(forward_to_server);
bool called_back = false;
app.echo()->EchoMinimal("", [this, &called_back, &callback]() {
called_back = true;
callback();
loop_->Quit();
});
while (!called_back && !failed) {
loop_->Run();
}
loop_->ResetQuit();
} else {
callback();
}
}
void EchoMinimalWithError(std::string forward_to_server, RespondWith result_variant,
EchoMinimalWithErrorCallback callback) override {
if (!forward_to_server.empty()) {
EchoClientApp app;
bool failed = false;
app.echo().set_error_handler([this, &forward_to_server, &failed](zx_status_t status) {
failed = true;
loop_->Quit();
FX_LOGS(ERROR) << "error communicating with " << forward_to_server << ": " << status;
});
app.Start(forward_to_server);
bool called_back = false;
app.echo()->EchoMinimalWithError(
"", result_variant,
[this, &called_back, &callback](Echo_EchoMinimalWithError_Result result) {
called_back = true;
callback(std::move(result));
loop_->Quit();
});
while (!called_back && !failed) {
loop_->Run();
}
loop_->ResetQuit();
} else {
Echo_EchoMinimalWithError_Result result;
if (result_variant == RespondWith::ERR) {
result.set_err(0u);
} else {
result.set_response(Echo_EchoMinimalWithError_Response());
}
callback(std::move(result));
}
}
void EchoMinimalNoRetVal(std::string forward_to_server) override {
if (!forward_to_server.empty()) {
std::unique_ptr<EchoClientApp> app(new EchoClientApp);
app->echo().set_error_handler([this, forward_to_server](zx_status_t status) {
loop_->Quit();
FX_LOGS(ERROR) << "error communicating with " << forward_to_server << ": " << status;
});
app->Start(forward_to_server);
app->echo().events().EchoMinimalEvent = [this]() { this->HandleEchoMinimalEvent(); };
app->echo()->EchoMinimalNoRetVal("");
client_apps_.push_back(std::move(app));
} else {
for (const auto& binding : bindings_.bindings()) {
binding->events().EchoMinimalEvent();
}
}
}
void EchoStruct(Struct value, std::string forward_to_server,
EchoStructCallback callback) override {
if (!forward_to_server.empty()) {
EchoClientApp app;
bool failed = false;
app.echo().set_error_handler([this, &forward_to_server, &failed](zx_status_t status) {
failed = true;
loop_->Quit();
FX_LOGS(ERROR) << "error communicating with " << forward_to_server << ": " << status;
});
app.Start(forward_to_server);
bool called_back = false;
app.echo()->EchoStruct(std::move(value), "", [this, &called_back, &callback](Struct resp) {
called_back = true;
callback(std::move(resp));
loop_->Quit();
});
while (!called_back && !failed) {
loop_->Run();
}
loop_->ResetQuit();
} else {
callback(std::move(value));
}
}
void EchoStructWithError(Struct value, default_enum err, std::string forward_to_server,
RespondWith result_variant,
EchoStructWithErrorCallback callback) override {
if (!forward_to_server.empty()) {
EchoClientApp app;
bool failed = false;
app.echo().set_error_handler([this, &forward_to_server, &failed](zx_status_t status) {
failed = true;
loop_->Quit();
FX_LOGS(ERROR) << "error communicating with " << forward_to_server << ": " << status;
});
app.Start(forward_to_server);
bool called_back = false;
app.echo()->EchoStructWithError(
std::move(value), std::move(err), "", result_variant,
[this, &called_back, &callback](Echo_EchoStructWithError_Result result) {
called_back = true;
callback(std::move(result));
loop_->Quit();
});
while (!called_back && !failed) {
loop_->Run();
}
loop_->ResetQuit();
} else {
Echo_EchoStructWithError_Result result;
if (result_variant == RespondWith::ERR) {
result.set_err(err);
} else {
result.set_response(Echo_EchoStructWithError_Response(std::move(value)));
}
callback(std::move(result));
}
}
void EchoStructNoRetVal(Struct value, std::string forward_to_server) override {
if (!forward_to_server.empty()) {
std::unique_ptr<EchoClientApp> app(new EchoClientApp);
app->echo().set_error_handler([this, forward_to_server](zx_status_t status) {
loop_->Quit();
FX_LOGS(ERROR) << "error communicating with " << forward_to_server << ": " << status;
});
app->Start(forward_to_server);
app->echo().events().EchoEvent = [this](Struct resp) {
this->HandleEchoEvent(std::move(resp));
};
app->echo()->EchoStructNoRetVal(std::move(value), "");
client_apps_.push_back(std::move(app));
} else {
for (const auto& binding : bindings_.bindings()) {
Struct to_send;
value.Clone(&to_send);
binding->events().EchoEvent(std::move(to_send));
}
}
}
void EchoArrays(ArraysStruct value, std::string forward_to_server,
EchoArraysCallback callback) override {
if (!forward_to_server.empty()) {
EchoClientApp app;
bool failed = false;
app.echo().set_error_handler([this, &forward_to_server, &failed](zx_status_t status) {
failed = true;
loop_->Quit();
FX_LOGS(ERROR) << "error communicating with " << forward_to_server << ": " << status;
});
app.Start(forward_to_server);
bool called_back = false;
app.echo()->EchoArrays(std::move(value), "",
[this, &called_back, &callback](ArraysStruct resp) {
called_back = true;
callback(std::move(resp));
loop_->Quit();
});
while (!called_back && !failed) {
loop_->Run();
}
loop_->ResetQuit();
} else {
callback(std::move(value));
}
}
void EchoArraysWithError(ArraysStruct value, default_enum err, std::string forward_to_server,
RespondWith result_variant,
EchoArraysWithErrorCallback callback) override {
if (!forward_to_server.empty()) {
EchoClientApp app;
bool failed = false;
app.echo().set_error_handler([this, &forward_to_server, &failed](zx_status_t status) {
failed = true;
loop_->Quit();
FX_LOGS(ERROR) << "error communicating with " << forward_to_server << ": " << status;
});
app.Start(forward_to_server);
bool called_back = false;
app.echo()->EchoArraysWithError(
std::move(value), std::move(err), "", result_variant,
[this, &called_back, &callback](Echo_EchoArraysWithError_Result result) {
called_back = true;
callback(std::move(result));
loop_->Quit();
});
while (!called_back && !failed) {
loop_->Run();
}
loop_->ResetQuit();
} else {
Echo_EchoArraysWithError_Result result;
if (result_variant == RespondWith::ERR) {
result.set_err(err);
} else {
result.set_response(Echo_EchoArraysWithError_Response(std::move(value)));
}
callback(std::move(result));
}
}
void EchoVectors(VectorsStruct value, std::string forward_to_server,
EchoVectorsCallback callback) override {
if (!forward_to_server.empty()) {
EchoClientApp app;
bool failed = false;
app.echo().set_error_handler([this, &forward_to_server, &failed](zx_status_t status) {
failed = true;
loop_->Quit();
FX_LOGS(ERROR) << "error communicating with " << forward_to_server << ": " << status;
});
app.Start(forward_to_server);
bool called_back = false;
app.echo()->EchoVectors(std::move(value), "",
[this, &called_back, &callback](VectorsStruct resp) {
called_back = true;
callback(std::move(resp));
loop_->Quit();
});
while (!called_back && !failed) {
loop_->Run();
}
loop_->ResetQuit();
} else {
callback(std::move(value));
}
}
void EchoVectorsWithError(VectorsStruct value, default_enum err, std::string forward_to_server,
RespondWith result_variant,
EchoVectorsWithErrorCallback callback) override {
if (!forward_to_server.empty()) {
EchoClientApp app;
bool failed = false;
app.echo().set_error_handler([this, &forward_to_server, &failed](zx_status_t status) {
failed = true;
loop_->Quit();
FX_LOGS(ERROR) << "error communicating with " << forward_to_server << ": " << status;
});
app.Start(forward_to_server);
bool called_back = false;
app.echo()->EchoVectorsWithError(
std::move(value), std::move(err), "", result_variant,
[this, &called_back, &callback](Echo_EchoVectorsWithError_Result result) {
called_back = true;
callback(std::move(result));
loop_->Quit();
});
while (!called_back && !failed) {
loop_->Run();
}
loop_->ResetQuit();
} else {
Echo_EchoVectorsWithError_Result result;
if (result_variant == RespondWith::ERR) {
result.set_err(err);
} else {
result.set_response(Echo_EchoVectorsWithError_Response(std::move(value)));
}
callback(std::move(result));
}
}
void EchoTable(AllTypesTable value, std::string forward_to_server,
EchoTableCallback callback) override {
if (!forward_to_server.empty()) {
EchoClientApp app;
bool failed = false;
app.echo().set_error_handler([this, &forward_to_server, &failed](zx_status_t status) {
failed = true;
loop_->Quit();
FX_LOGS(ERROR) << "error communicating with " << forward_to_server << ": " << status;
});
app.Start(forward_to_server);
bool called_back = false;
app.echo()->EchoTable(std::move(value), "",
[this, &called_back, &callback](AllTypesTable resp) {
called_back = true;
callback(std::move(resp));
loop_->Quit();
});
while (!called_back && !failed) {
loop_->Run();
}
loop_->ResetQuit();
} else {
callback(std::move(value));
}
}
void EchoTableWithError(AllTypesTable value, default_enum err, std::string forward_to_server,
RespondWith result_variant,
EchoTableWithErrorCallback callback) override {
if (!forward_to_server.empty()) {
EchoClientApp app;
bool failed = false;
app.echo().set_error_handler([this, &forward_to_server, &failed](zx_status_t status) {
failed = true;
loop_->Quit();
FX_LOGS(ERROR) << "error communicating with " << forward_to_server << ": " << status;
});
app.Start(forward_to_server);
bool called_back = false;
app.echo()->EchoTableWithError(
std::move(value), std::move(err), "", result_variant,
[this, &called_back, &callback](Echo_EchoTableWithError_Result result) {
called_back = true;
callback(std::move(result));
loop_->Quit();
});
while (!called_back && !failed) {
loop_->Run();
}
loop_->ResetQuit();
} else {
Echo_EchoTableWithError_Result result;
if (result_variant == RespondWith::ERR) {
result.set_err(err);
} else {
result.set_response(Echo_EchoTableWithError_Response(std::move(value)));
}
callback(std::move(result));
}
}
void EchoXunions(std::vector<AllTypesXunion> value, std::string forward_to_server,
EchoXunionsCallback callback) override {
if (!forward_to_server.empty()) {
EchoClientApp app;
bool failed = false;
app.echo().set_error_handler([this, &forward_to_server, &failed](zx_status_t status) {
failed = true;
loop_->Quit();
FX_LOGS(ERROR) << "error communicating with " << forward_to_server << ": " << status;
});
app.Start(forward_to_server);
bool called_back = false;
app.echo()->EchoXunions(std::move(value), "",
[this, &called_back, &callback](std::vector<AllTypesXunion> resp) {
called_back = true;
callback(std::move(resp));
loop_->Quit();
});
while (!called_back && !failed) {
loop_->Run();
}
loop_->ResetQuit();
} else {
callback(std::move(value));
}
}
void EchoXunionsWithError(std::vector<AllTypesXunion> value, default_enum err,
std::string forward_to_server, RespondWith result_variant,
EchoXunionsWithErrorCallback callback) override {
if (!forward_to_server.empty()) {
EchoClientApp app;
bool failed = false;
app.echo().set_error_handler([this, &forward_to_server, &failed](zx_status_t status) {
failed = true;
loop_->Quit();
FX_LOGS(ERROR) << "error communicating with " << forward_to_server << ": " << status;
});
app.Start(forward_to_server);
bool called_back = false;
app.echo()->EchoXunionsWithError(
std::move(value), std::move(err), "", result_variant,
[this, &called_back, &callback](Echo_EchoXunionsWithError_Result result) {
called_back = true;
callback(std::move(result));
loop_->Quit();
});
while (!called_back && !failed) {
loop_->Run();
}
loop_->ResetQuit();
} else {
Echo_EchoXunionsWithError_Result result;
if (result_variant == RespondWith::ERR) {
result.set_err(err);
} else {
result.set_response(Echo_EchoXunionsWithError_Response(std::move(value)));
}
callback(std::move(result));
}
}
void EchoNamedStruct(imported::SimpleStruct value, std::string forward_to_server,
EchoNamedStructCallback callback) override {
if (!forward_to_server.empty()) {
EchoClientApp app;
bool failed = false;
app.echo().set_error_handler([this, &forward_to_server, &failed](zx_status_t status) {
failed = true;
loop_->Quit();
FX_LOGS(ERROR) << "error communicating with " << forward_to_server << ": " << status;
});
app.Start(forward_to_server);
bool called_back = false;
app.echo()->EchoNamedStruct(std::move(value), "",
[this, &called_back, &callback](imported::SimpleStruct resp) {
called_back = true;
callback(std::move(resp));
loop_->Quit();
});
while (!called_back && !failed) {
loop_->Run();
}
loop_->ResetQuit();
} else {
callback(std::move(value));
}
}
void EchoNamedStructWithError(imported::SimpleStruct value, uint32_t err,
std::string forward_to_server,
imported::WantResponse result_variant,
EchoNamedStructWithErrorCallback callback) override {
if (!forward_to_server.empty()) {
EchoClientApp app;
bool failed = false;
app.echo().set_error_handler([this, &forward_to_server, &failed](zx_status_t status) {
failed = true;
loop_->Quit();
FX_LOGS(ERROR) << "error communicating with " << forward_to_server << ": " << status;
});
app.Start(forward_to_server);
bool called_back = false;
app.echo()->EchoNamedStructWithError(
std::move(value), std::move(err), "", result_variant,
[this, &called_back, &callback](Echo_EchoNamedStructWithError_Result result) {
called_back = true;
callback(std::move(result));
loop_->Quit();
});
while (!called_back && !failed) {
loop_->Run();
}
loop_->ResetQuit();
} else {
Echo_EchoNamedStructWithError_Result result;
if (result_variant == imported::WantResponse::ERR) {
result.set_err(err);
} else {
result.set_response(imported::ResponseStruct{std::move(value)});
}
callback(std::move(result));
}
}
void EchoNamedStructNoRetVal(imported::SimpleStruct value,
std::string forward_to_server) override {
if (!forward_to_server.empty()) {
std::unique_ptr<EchoClientApp> app(new EchoClientApp);
app->echo().set_error_handler([this, forward_to_server](zx_status_t status) {
loop_->Quit();
FX_LOGS(ERROR) << "error communicating with " << forward_to_server << ": " << status;
});
app->Start(forward_to_server);
app->echo().events().OnEchoNamedEvent = [this](imported::SimpleStruct resp) {
this->HandleOnEchoNamedEvent(std::move(resp));
};
app->echo()->EchoNamedStructNoRetVal(std::move(value), "");
client_apps_.push_back(std::move(app));
} else {
for (const auto& binding : bindings_.bindings()) {
imported::SimpleStruct to_send;
value.Clone(&to_send);
binding->events().OnEchoNamedEvent(std::move(to_send));
}
}
}
void EchoTablePayload(RequestTable payload, EchoTablePayloadCallback callback) override {
if (payload.has_forward_to_server()) {
EchoClientApp app;
const std::string& forward_to_server = payload.forward_to_server();
bool failed = false;
app.echo().set_error_handler([this, &forward_to_server, &failed](zx_status_t status) {
failed = true;
loop_->Quit();
FX_LOGS(ERROR) << "error communicating with " << forward_to_server << ": " << status;
});
app.Start(forward_to_server);
bool called_back = false;
payload.clear_forward_to_server();
app.echo()->EchoTablePayload(std::move(payload),
[this, &called_back, &callback](ResponseTable resp) {
called_back = true;
callback(std::move(resp));
loop_->Quit();
});
while (!called_back && !failed) {
loop_->Run();
}
loop_->ResetQuit();
} else {
ResponseTable resp;
resp.set_value(payload.value());
callback(std::move(resp));
}
}
void EchoTablePayloadNoRetVal(RequestTable payload) override {
if (payload.has_forward_to_server()) {
std::unique_ptr<EchoClientApp> app(new EchoClientApp);
const std::string& forward_to_server = payload.forward_to_server();
app->echo().set_error_handler([this, forward_to_server](zx_status_t status) {
loop_->Quit();
FX_LOGS(ERROR) << "error communicating with " << forward_to_server << ": " << status;
});
app->Start(forward_to_server);
app->echo().events().OnEchoTablePayloadEvent = [this](ResponseTable resp) {
this->HandleOnTablePayloadEvent(std::move(resp));
};
payload.clear_forward_to_server();
app->echo()->EchoTablePayloadNoRetVal(std::move(payload));
client_apps_.push_back(std::move(app));
} else {
for (const auto& binding : bindings_.bindings()) {
ResponseTable resp;
resp.set_value(payload.value());
binding->events().OnEchoTablePayloadEvent(std::move(resp));
}
}
}
void EchoTablePayloadWithError(EchoEchoTablePayloadWithErrorRequest payload,
EchoTablePayloadWithErrorCallback callback) override {
if (payload.has_forward_to_server()) {
EchoClientApp app;
const std::string& forward_to_server = payload.forward_to_server();
bool failed = false;
app.echo().set_error_handler([this, &forward_to_server, &failed](zx_status_t status) {
failed = true;
loop_->Quit();
FX_LOGS(ERROR) << "error communicating with " << forward_to_server << ": " << status;
});
app.Start(forward_to_server);
bool called_back = false;
payload.clear_forward_to_server();
app.echo()->EchoTablePayloadWithError(
std::move(payload),
[this, &called_back, &callback](Echo_EchoTablePayloadWithError_Result res) {
called_back = true;
callback(std::move(res));
loop_->Quit();
});
while (!called_back && !failed) {
loop_->Run();
}
loop_->ResetQuit();
} else {
Echo_EchoTablePayloadWithError_Result result;
if (payload.result_variant() == RespondWith::ERR) {
result.set_err(payload.result_err());
} else {
ResponseTable resp;
resp.set_value(payload.value());
result.set_response(std::move(resp));
}
callback(std::move(result));
}
}
void EchoTableRequestComposed(
::fidl::test::imported::ComposedEchoTableRequestComposedRequest payload,
EchoTableRequestComposedCallback callback) override {
if (payload.has_forward_to_server()) {
EchoClientApp app;
const std::string& forward_to_server = payload.forward_to_server();
bool failed = false;
app.echo().set_error_handler([this, &forward_to_server, &failed](zx_status_t status) {
failed = true;
loop_->Quit();
FX_LOGS(ERROR) << "error communicating with " << forward_to_server << ": " << status;
});
app.Start(forward_to_server);
bool called_back = false;
payload.clear_forward_to_server();
app.echo()->EchoTableRequestComposed(
std::move(payload), [this, &called_back, &callback](imported::SimpleStruct resp) {
called_back = true;
callback(std::move(resp));
loop_->Quit();
});
while (!called_back && !failed) {
loop_->Run();
}
loop_->ResetQuit();
} else {
imported::SimpleStruct resp = {.f1 = true, .f2 = payload.value()};
callback(std::move(resp));
}
}
void EchoUnionPayload(RequestUnion payload, EchoUnionPayloadCallback callback) override {
const std::string& forward_to_server = payload.is_signed_()
? payload.signed_().forward_to_server
: payload.unsigned_().forward_to_server;
if (!forward_to_server.empty()) {
EchoClientApp app;
bool failed = false;
app.echo().set_error_handler([this, &forward_to_server, &failed](zx_status_t status) {
failed = true;
loop_->Quit();
FX_LOGS(ERROR) << "error communicating with " << forward_to_server << ": " << status;
});
app.Start(forward_to_server);
bool called_back = false;
if (payload.is_signed_()) {
payload.signed_().forward_to_server = "";
} else {
payload.unsigned_().forward_to_server = "";
}
app.echo()->EchoUnionPayload(std::move(payload),
[this, &called_back, &callback](ResponseUnion resp) {
called_back = true;
callback(std::move(resp));
loop_->Quit();
});
while (!called_back && !failed) {
loop_->Run();
}
loop_->ResetQuit();
} else {
ResponseUnion resp;
if (payload.is_signed_()) {
resp.set_signed_(payload.signed_().value);
} else {
resp.set_unsigned_(payload.unsigned_().value);
}
callback(std::move(resp));
}
}
void EchoUnionPayloadWithError(EchoEchoUnionPayloadWithErrorRequest payload,
EchoUnionPayloadWithErrorCallback callback) override {
const std::string& forward_to_server = payload.is_signed_()
? payload.signed_().forward_to_server
: payload.unsigned_().forward_to_server;
if (!forward_to_server.empty()) {
EchoClientApp app;
bool failed = false;
app.echo().set_error_handler([this, &forward_to_server, &failed](zx_status_t status) {
failed = true;
loop_->Quit();
FX_LOGS(ERROR) << "error communicating with " << forward_to_server << ": " << status;
});
app.Start(forward_to_server);
bool called_back = false;
if (payload.is_signed_()) {
payload.signed_().forward_to_server = "";
} else {
payload.unsigned_().forward_to_server = "";
}
app.echo()->EchoUnionPayloadWithError(
std::move(payload),
[this, &called_back, &callback](Echo_EchoUnionPayloadWithError_Result res) {
called_back = true;
callback(std::move(res));
loop_->Quit();
});
while (!called_back && !failed) {
loop_->Run();
}
loop_->ResetQuit();
} else {
const RespondWith result_variant = payload.is_signed_() ? payload.signed_().result_variant
: payload.unsigned_().result_variant;
Echo_EchoUnionPayloadWithError_Result result;
ResponseUnion resp;
if (result_variant == RespondWith::ERR) {
result.set_err(payload.is_signed_() ? payload.signed_().result_err
: payload.unsigned_().result_err);
} else {
if (payload.is_signed_()) {
resp.set_signed_(payload.signed_().value);
} else {
resp.set_unsigned_(payload.unsigned_().value);
}
result.set_response(std::move(resp));
}
callback(std::move(result));
}
}
void EchoUnionPayloadNoRetVal(RequestUnion payload) override {
const std::string& forward_to_server = payload.is_signed_()
? payload.signed_().forward_to_server
: payload.unsigned_().forward_to_server;
if (!forward_to_server.empty()) {
std::unique_ptr<EchoClientApp> app(new EchoClientApp);
app->echo().set_error_handler([this, forward_to_server](zx_status_t status) {
loop_->Quit();
FX_LOGS(ERROR) << "error communicating with " << forward_to_server << ": " << status;
});
app->Start(forward_to_server);
app->echo().events().OnEchoUnionPayloadEvent = [this](ResponseUnion resp) {
this->HandleOnUnionPayloadEvent(std::move(resp));
};
if (payload.is_signed_()) {
payload.signed_().forward_to_server = "";
} else {
payload.unsigned_().forward_to_server = "";
}
app->echo()->EchoUnionPayloadNoRetVal(std::move(payload));
client_apps_.push_back(std::move(app));
} else {
for (const auto& binding : bindings_.bindings()) {
ResponseUnion resp;
if (payload.is_signed_()) {
resp.set_signed_(payload.signed_().value);
} else {
resp.set_unsigned_(payload.unsigned_().value);
}
binding->events().OnEchoUnionPayloadEvent(std::move(resp));
}
}
}
void EchoUnionResponseWithErrorComposed(
int64_t value, bool want_absolute_value, std::string forward_to_server, uint32_t err,
imported::WantResponse result_variant,
EchoUnionResponseWithErrorComposedCallback callback) override {
if (!forward_to_server.empty()) {
EchoClientApp app;
bool failed = false;
app.echo().set_error_handler([this, &forward_to_server, &failed](zx_status_t status) {
failed = true;
loop_->Quit();
FX_LOGS(ERROR) << "error communicating with " << forward_to_server << ": " << status;
});
app.Start(forward_to_server);
bool called_back = false;
app.echo()->EchoUnionResponseWithErrorComposed(
value, want_absolute_value, "", err, result_variant,
[this, &called_back,
&callback](imported::Composed_EchoUnionResponseWithErrorComposed_Result resp) {
called_back = true;
callback(std::move(resp));
loop_->Quit();
});
while (!called_back && !failed) {
loop_->Run();
}
loop_->ResetQuit();
return;
}
imported::Composed_EchoUnionResponseWithErrorComposed_Result result;
if (result_variant == imported::WantResponse::ERR) {
result.set_err(err);
} else if (want_absolute_value) {
result.set_response(
::fidl::test::imported::Composed_EchoUnionResponseWithErrorComposed_Response::
WithUnsigned_(static_cast<uint64_t>(std::abs(value))));
} else {
result.set_response(
::fidl::test::imported::Composed_EchoUnionResponseWithErrorComposed_Response::WithSigned_(
std::move(value)));
}
callback(std::move(result));
}
private:
void HandleEchoEvent(Struct value) {
for (const auto& binding : bindings_.bindings()) {
Struct to_send;
value.Clone(&to_send);
binding->events().EchoEvent(std::move(to_send));
}
}
void HandleEchoMinimalEvent() {
for (const auto& binding : bindings_.bindings()) {
binding->events().EchoMinimalEvent();
}
}
void HandleOnEchoNamedEvent(imported::SimpleStruct value) {
for (const auto& binding : bindings_.bindings()) {
imported::SimpleStruct to_send;
value.Clone(&to_send);
binding->events().OnEchoNamedEvent(std::move(to_send));
}
}
void HandleOnTablePayloadEvent(ResponseTable payload) {
for (const auto& binding : bindings_.bindings()) {
ResponseTable to_send;
payload.Clone(&to_send);
binding->events().OnEchoTablePayloadEvent(std::move(to_send));
}
}
void HandleOnUnionPayloadEvent(ResponseUnion payload) {
for (const auto& binding : bindings_.bindings()) {
ResponseUnion to_send;
payload.Clone(&to_send);
binding->events().OnEchoUnionPayloadEvent(std::move(to_send));
}
}
EchoPtr server_ptr;
EchoServerApp(const EchoServerApp&) = delete;
EchoServerApp& operator=(const EchoServerApp&) = delete;
async::Loop* loop_;
std::unique_ptr<sys::ComponentContext> context_;
fidl::BindingSet<Echo> bindings_;
std::vector<std::unique_ptr<EchoClientApp>> client_apps_;
};
} // namespace compatibility
} // namespace test
} // namespace fidl
int main(int argc, const char** argv) {
// The FIDL support lib requires async_get_default_dispatcher() to return
// non-null.
async::Loop loop(&kAsyncLoopConfigAttachToCurrentThread);
fidl::test::compatibility::EchoServerApp app(&loop);
loop.Run();
return EXIT_SUCCESS;
}