blob: a3b2f51006f5b4ba432c7da79312ec8465a6ab09 [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 <lib/fidl/walker.h>
#include <cstdint>
#include <limits>
namespace fidl {
zx_status_t PrimaryObjectSize(const fidl_type_t* type, size_t* out_size, const char** out_error) {
auto set_error = [&out_error](const char* msg) {
if (out_error)
*out_error = msg;
};
if (type == nullptr) {
set_error("fidl type cannot be null");
return ZX_ERR_INVALID_ARGS;
}
switch (type->type_tag()) {
case kFidlTypeStruct:
*out_size = type->coded_struct().size;
return ZX_OK;
case kFidlTypeTable:
*out_size = sizeof(fidl_vector_t);
return ZX_OK;
default:
set_error("Message must be a struct or a table");
return ZX_ERR_INVALID_ARGS;
}
}
zx_status_t StartingOutOfLineOffset(const fidl_type_t* type, uint32_t buffer_size,
uint32_t* out_first_out_of_line, const char** out_error) {
auto set_error = [&out_error](const char* msg) {
if (out_error)
*out_error = msg;
};
size_t primary_size;
zx_status_t status;
if ((status = PrimaryObjectSize(type, &primary_size, out_error)) != ZX_OK) {
return status;
}
if (primary_size > buffer_size) {
set_error("Buffer is too small for first inline object");
return ZX_ERR_INVALID_ARGS;
}
uint64_t first_out_of_line = FidlAlign(static_cast<uint32_t>(primary_size));
if (first_out_of_line > std::numeric_limits<uint32_t>::max()) {
set_error("Out of line starting offset overflows");
return ZX_ERR_INVALID_ARGS;
}
*out_first_out_of_line = static_cast<uint32_t>(first_out_of_line);
return ZX_OK;
}
} // namespace fidl