blob: 07f3043fabfc558ef084e1198f688c9a6a5a3dc4 [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.
#include <lib/fidl/cpp/natural_coding_traits.h>
#include <lib/fidl/cpp/wire/incoming_message.h>
#include <lib/fidl/cpp/wire/wire_coding_traits.h>
namespace fidl::internal {
fidl::Status NaturalDecode(::fidl::WireFormatMetadata metadata, size_t inline_size,
NaturalTopLevelDecodeFn decode_fn, ::fidl::EncodedMessage& message,
void* value) {
if (fidl::Status status = EnsureSupportedWireFormat(metadata); !status.ok()) {
std::move(message).CloseHandles();
return status;
}
size_t message_byte_actual = message.bytes().size();
uint32_t message_handle_actual = message.num_handles();
::fidl::internal::NaturalDecoder decoder(std::move(message), metadata.wire_format_version());
size_t offset;
if (unlikely(!decoder.Alloc(inline_size, &offset))) {
return ::fidl::Error::DecodeError(decoder.status(), decoder.error());
}
decode_fn(&decoder, value, offset);
if (unlikely(decoder.status() != ZX_OK)) {
return ::fidl::Error::DecodeError(decoder.status(), decoder.error());
}
if (unlikely(decoder.CurrentLength() != message_byte_actual)) {
return ::fidl::Error::DecodeError(ZX_ERR_INTERNAL, kCodingErrorNotAllBytesConsumed);
}
if (unlikely(decoder.CurrentHandleCount() != message_handle_actual)) {
return ::fidl::Error::DecodeError(ZX_ERR_INTERNAL, kCodingErrorNotAllHandlesConsumed);
}
return ::fidl::Status::Ok();
}
} // namespace fidl::internal