blob: 9d9a88316bcd16a2c903f04923f87a9ecc8b8ba8 [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.
#include <lib/fidl/llcpp/message_storage.h>
#include <zircon/assert.h>
#include <zircon/compiler.h>
namespace fidl {
AnyMemoryResource MakeFidlAnyMemoryResource(fidl::BufferSpan buffer_span) {
class BufferSpanMemoryResource : public MemoryResource {
public:
explicit BufferSpanMemoryResource(fidl::BufferSpan buffer_span)
: data_(buffer_span.data), capacity_(buffer_span.capacity) {}
uint8_t* Allocate(uint32_t num_bytes) final {
uint32_t used_original = used_;
if (unlikely(add_overflow(used_, num_bytes, &used_))) {
// Allocation overflowed, revert to previous state.
used_ = used_original;
return nullptr;
}
if (used_ > capacity_) {
// Allocation failed, revert to previous state.
used_ = used_original;
return nullptr;
}
return &data_[used_original];
}
private:
uint8_t* data_;
uint32_t capacity_;
uint32_t used_ = 0;
};
return AnyMemoryResource(std::in_place_type_t<BufferSpanMemoryResource>{}, buffer_span);
}
namespace internal {
fitx::result<fidl::Error, fidl::BufferSpan> AnyBufferAllocator::TryAllocate(uint32_t num_bytes) {
uint8_t* buffer = Allocate(num_bytes);
if (buffer == nullptr) {
return fitx::error(fidl::Status::EncodeError(ZX_ERR_BUFFER_TOO_SMALL,
fidl::internal::kCallerAllocatedBufferTooSmall));
}
return fitx::ok(fidl::BufferSpan{buffer, num_bytes});
}
} // namespace internal
} // namespace fidl