| {{/* |
| // 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 }} |