blob: a55c3600cb333be24b59e6f38524e21c8497634b [file] [log] [blame]
{{/*
// Copyright 2021 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 "Method:UnownedResult:MessagingHeader" }}
{{- EnsureNamespace "" }}
template<>
class {{ .WireUnownedResult }} final : public ::fidl::Result {
public:
{{- $args := (printf "::fidl::UnownedClientEnd<%s> client_end" .Protocol) }}
{{- $args = (List $args "::fidl::internal::AnyBufferAllocator& allocator") }}
{{- $args = (List $args (printf "%s* request" .WireRequest)) }}
explicit {{ .WireUnownedResult.Self }}({{ RenderParams $args }});
{{- if .HasResponse }}
explicit {{ .WireUnownedResult.Self }}({{ .WireResponse }}* response)
: bytes_(reinterpret_cast<uint8_t*>(response)) {}
{{- end }}
explicit {{ .WireUnownedResult.Self }}(const ::fidl::Result& result) : ::fidl::Result(result) {}
{{- if .HasResponse }}
explicit {{ .WireUnownedResult.Self }}(::fidl::DecodedMessage<{{ .WireResponse }}>&& decoded)
: ::fidl::Result(decoded) {
if (decoded.ok()) {
bytes_ = reinterpret_cast<uint8_t*>(decoded.PrimaryObject());
} else {
bytes_ = nullptr;
}
decoded.ReleasePrimaryObject();
}
{{- end }}
{{ .WireUnownedResult.Self }}({{ .WireUnownedResult.Self }}&&) = delete;
{{ .WireUnownedResult.Self }}(const {{ .WireUnownedResult.Self }}&) = delete;
{{ .WireUnownedResult.Self }}* operator=({{ .WireUnownedResult.Self }}&&) = delete;
{{ .WireUnownedResult.Self }}* operator=(const {{ .WireUnownedResult.Self }}&) = delete;
{{- if and .HasResponse .Response.IsResource }}
~{{ .WireUnownedResult.Self }}() {
if (ok()) {
Unwrap()->_CloseHandles();
}
}
{{- else }}
~{{ .WireUnownedResult.Self }}() = default;
{{- end }}
{{- if .HasResponse }}
{{ .WireResponse }}* Unwrap() {
ZX_DEBUG_ASSERT(ok());
return reinterpret_cast<{{ .WireResponse }}*>(bytes_);
}
const {{ .WireResponse }}* Unwrap() const {
ZX_DEBUG_ASSERT(ok());
return reinterpret_cast<const {{ .WireResponse }}*>(bytes_);
}
{{ .WireResponse }}& value() { return *Unwrap(); }
const {{ .WireResponse }}& value() const { return *Unwrap(); }
{{ .WireResponse }}* operator->() { return &value(); }
const {{ .WireResponse }}* operator->() const { return &value(); }
{{ .WireResponse }}& operator*() { return value(); }
const {{ .WireResponse }}& operator*() const { return value(); }
private:
uint8_t* bytes_;
{{- end }}
};
{{- end }}
{{- define "Method:UnownedResult:MessagingSource" }}
{{- IfdefFuchsia -}}
{{- EnsureNamespace "" }}
{{- $args := (printf "::fidl::UnownedClientEnd<%s> client_end" .Protocol) }}
{{- $args = (List $args "::fidl::internal::AnyBufferAllocator& allocator") }}
{{- $args = (List $args (printf "%s* request" .WireRequest)) }}
{{ .WireUnownedResult }}::{{ .WireUnownedResult.Self }}({{ RenderParams $args }}) {
{{/* TODO(fxbug.dev/86367): Factor out common buffer allocation logic once we have other instances
of this pattern. */ -}}
{{/* Allocate one buffer for both request/response (if applicable). */ -}}
constexpr uint32_t buffer_size = ::fidl::SyncClientMethodBufferSizeInChannel<{{ .Marker }}>();
uint8_t* buffer = allocator.Allocate(buffer_size);
if (!buffer) {
::fidl::Result::operator=(
::fidl::Result::EncodeError(
ZX_ERR_BUFFER_TOO_SMALL,
::fidl::internal::kCallerAllocatedBufferTooSmall));
return;
}
{{- if .HasResponse -}}
{{/* TODO(fxbug.dev/85843): We should be able optimize this to just the max of
the send/receive size, once Zircon channel calls guarantee that the
send/receive buffers can overlap.
For now, the invariant of SyncClientMethodBufferSizeInChannel is that it returns
the sum of the request/response size, so we can index into it and get the
address of the response buffer. */ -}}
constexpr uint32_t request_byte_capacity = ::fidl::MaxSizeInChannel<
::fidl::WireRequest<{{ .Marker }}>, ::fidl::MessageDirection::kSending>();
uint8_t* request_bytes = buffer;
static_assert(buffer_size > request_byte_capacity);
uint32_t response_byte_capacity = buffer_size - request_byte_capacity;
uint8_t* response_bytes = &buffer[request_byte_capacity];
{{- else }}
uint32_t request_byte_capacity = buffer_size;
uint8_t* request_bytes = buffer;
{{- end }}
::fidl::UnownedEncodedMessage<{{ .WireRequest }}> request_message(
request_bytes, request_byte_capacity, request);
auto& outgoing = request_message.GetOutgoingMessage();
{{- if .HasResponse }}
outgoing.Call<{{ .WireResponse }}>(client_end.channel(), response_bytes, response_byte_capacity);
bytes_ = response_bytes;
{{- else }}
outgoing.Write(client_end.channel());
{{- end }}
::fidl::Result::operator=(outgoing);
}
{{- EndifFuchsia -}}
{{- end }}