blob: d5ab4cfb53271abd29278f23590470cba4dc9e02 [file] [log] [blame]
{{/*
// Copyright 2022 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.
*/}}
{{- define "driver/Method:UnownedResult:MessagingHeader" }}
{{- EnsureNamespace "" }}
{{ if .WireResultUnwrapType -}}
template<>
struct {{ .WireResultUnwrap }} {
using Type = {{ .WireResultUnwrapType }};
};
{{- end }}
{{/* TODO(fxbug.dev/105375): This type should probably actually just be called
* WireResult since it owns and fdf::Arena and uses DecodedValue to own the
* handles in the decoded message. */}}
template<>
class [[nodiscard]] {{ .WireUnownedResult }} final : public {{ .BaseWireResult }} {
public:
{{- if .Transport.HasSyncClient }}
{{- $args := (printf "%s client_end" .Protocol.UnownedClientEnd) }}
{{- $args = (List $args "const ::fdf::Arena& arena") }}
{{- $args = (List $args (printf "%s* request" .WireTransactionalRequest)) }}
explicit {{ .WireUnownedResult.Self }}({{ RenderParams $args }});
{{- end }}
{{- if .HasResponsePayload }}
explicit {{ .WireUnownedResult.Self }}({{ .WireResponse }}* response)
: {{ .BaseWireResult }}(fidl::Status::Ok()), decoded_(response) {
ExtractValueFromDecoded(decoded_.pointer());
}
explicit {{ .WireUnownedResult.Self }}(
::fit::result<::fidl::Error, ::fidl::DecodedValue<{{ .WireResponse }}>>&& decoded,
::fidl::internal::MessageStorageViewBase* storage_view
) : {{ .BaseWireResult }}(::fidl::internal::StatusFromResult(decoded)),
arena_(::fidl::internal::TakeDriverArenaFromStorage(storage_view)) {
if (decoded.is_ok()) {
decoded_ = std::move(decoded.value());
ExtractValueFromDecoded(decoded_.pointer());
}
}
{{- else }}
explicit {{ .WireUnownedResult.Self }}(
::fit::result<::fidl::Error>&& decoded,
::fidl::internal::MessageStorageViewBase* storage_view
) : {{ .BaseWireResult }}(::fidl::internal::StatusFromResult(decoded)) {}
{{- end }}
explicit {{ .WireUnownedResult.Self }}(const ::fidl::Status& result) : {{ .BaseWireResult }}(result) {}
{{ .WireUnownedResult.Self }}({{ .WireUnownedResult.Self }}&&) = default;
{{ .WireUnownedResult.Self }}(const {{ .WireUnownedResult.Self }}&) = delete;
{{ .WireUnownedResult.Self }}& operator=({{ .WireUnownedResult.Self }}&&) = default;
{{ .WireUnownedResult.Self }}* operator=(const {{ .WireUnownedResult.Self }}&) = delete;
~{{ .WireUnownedResult.Self }}() = default;
{{- if .HasResponse }}
fdf::Arena& arena() {
ZX_ASSERT(ok());
return arena_;
}
private:
::fdf::Arena arena_{nullptr};
{{- if .HasResponsePayload }}
::fidl::DecodedValue<{{ .WireResponse }}> decoded_;
{{- end }}
{{- end }}
};
{{- end }}
{{- define "driver/Method:UnownedResult:MessagingSource" }}
{{- if .Transport.HasSyncClient }}
{{- IfdefFuchsia -}}
{{- EnsureNamespace "" }}
{{- $args := (printf "%s client_end" .Protocol.UnownedClientEnd) }}
{{- $args = (List $args "const ::fdf::Arena& arena") }}
{{- $args = (List $args (printf "%s* request" .WireTransactionalRequest)) }}
{{ .WireUnownedResult }}::{{ .WireUnownedResult.Self }}({{ RenderParams $args }}) {
{{/* TODO(fxbug.dev/86367): Factor out common buffer allocation logic once we have other instances
of this pattern. */ -}}
constexpr uint32_t buffer_size =
::fidl::MaxSizeInChannel<{{ .WireTransactionalRequest }}, ::fidl::MessageDirection::kSending>();
uint8_t* buffer = static_cast<uint8_t*>(arena.Allocate(buffer_size));
::fidl::internal::UnownedEncodedMessage<{{ .WireTransactionalRequest }}, fidl::internal::DriverTransport> request_message(
buffer, buffer_size, request);
auto& outgoing = request_message.GetOutgoingMessage();
{{- if .HasResponse }}
{{ .IncomingMessageStorageForResponse }} response_storage;
::fidl::CallOptions call_options = {
.outgoing_transport_context =
::fidl::internal::OutgoingTransportContext::Create<fidl::internal::DriverTransport>(
arena.get()),
};
::fit::result decoded = ::fidl::internal::InplaceDecodeTransactionalResponse<{{ .Marker }}>(
outgoing.Call(client_end.handle(), response_storage.view(), std::move(call_options))
);
SetStatus(::fidl::internal::StatusFromResult(decoded));
{{- if .HasResponsePayload }}
if (ok()) {
decoded_ = std::move(decoded.value());
ExtractValueFromDecoded(decoded_.pointer());
}
{{- end }}
arena_ = std::move(response_storage.arena);
{{- else }}
::fidl::WriteOptions write_options = {
.outgoing_transport_context =
::fidl::internal::OutgoingTransportContext::Create<fidl::internal::DriverTransport>(
arena.get()),
};
outgoing.Write(client_end.handle(), std::move(write_options));
SetStatus(outgoing);
{{- end }}
}
{{- EndifFuchsia -}}
{{- end }}
{{- end }}