blob: de0ba093df98ad8270036d4c803f597cf067ef75 [file] [log] [blame] [edit]
// Copyright 2020 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.
#ifndef ZIRCON_SYSTEM_ULIB_ZBITL_TEST_MEMORY_TESTS_H_
#define ZIRCON_SYSTEM_ULIB_ZBITL_TEST_MEMORY_TESTS_H_
#include <lib/zbitl/memory.h>
#include "tests.h"
template <typename T>
struct FblSpanTestTraits {
using storage_type = fbl::Span<T>;
using payload_type = storage_type;
static constexpr bool kDefaultConstructedViewHasStorageError = false;
static constexpr bool kExpectExtensibility = false;
static constexpr bool kExpectOneshotReads = true;
static constexpr bool kExpectUnbufferedReads = true;
static constexpr bool kExpectUnbufferedWrites = !std::is_const_v<T>;
struct Context {
storage_type TakeStorage() const {
return {reinterpret_cast<T*>(buff_.get()), size_ / sizeof(T)};
}
std::unique_ptr<std::byte[]> buff_;
size_t size_ = 0;
};
static void Create(size_t size, Context* context) {
const size_t n = (size + sizeof(T) - 1) / sizeof(T);
std::unique_ptr<std::byte[]> buff{new std::byte[n]};
*context = {std::move(buff), n};
}
static void Create(fbl::unique_fd fd, size_t size, Context* context) {
ASSERT_TRUE(fd);
ASSERT_NO_FATAL_FAILURE(Create(size, context));
EXPECT_EQ(static_cast<ssize_t>(context->size_),
read(fd.get(), context->buff_.get(), context->size_));
}
static void Read(const storage_type& storage, payload_type payload, size_t size,
Bytes* contents) {
contents->resize(size);
auto bytes = fbl::as_bytes(payload);
ASSERT_LE(size, bytes.size());
memcpy(contents->data(), bytes.data(), size);
}
static void Write(storage_type& storage, uint32_t offset, const Bytes& data) {
ASSERT_LT(offset, storage.size());
ASSERT_LE(offset, storage.size() - data.size());
memcpy(storage.data() + offset, data.data(), data.size());
}
static void ToPayload(const storage_type& storage, uint32_t offset, payload_type& payload) {
ASSERT_LT(offset, storage.size());
payload = storage.subspan(offset);
}
};
template <typename T>
struct FblArrayTestTraits {
using storage_type = fbl::Array<T>;
using payload_type = fbl::Span<T>;
using creation_traits = FblArrayTestTraits;
using SpanTraits = FblSpanTestTraits<T>;
static constexpr bool kDefaultConstructedViewHasStorageError = false;
static constexpr bool kExpectExtensibility = true;
static constexpr bool kExpectOneshotReads = true;
static constexpr bool kExpectUnbufferedReads = true;
static constexpr bool kExpectUnbufferedWrites = !std::is_const_v<T>;
struct Context {
storage_type TakeStorage() { return std::move(storage_); }
storage_type storage_;
};
static void Create(size_t size, Context* context) {
const size_t n = (size + sizeof(T) - 1) / sizeof(T);
storage_type storage{new T[n], n};
*context = {std::move(storage)};
}
static void Create(fbl::unique_fd fd, size_t size, Context* context) {
ASSERT_TRUE(fd);
ASSERT_NO_FATAL_FAILURE(Create(size, context));
EXPECT_EQ(static_cast<ssize_t>(size), read(fd.get(), context->storage_.data(), size));
}
static void Read(const storage_type& storage, payload_type payload, size_t size,
Bytes* contents) {
fbl::Span<T> span{storage.data(), storage.size()};
ASSERT_NO_FATAL_FAILURE(SpanTraits::Read(span, payload, size, contents));
}
static void Write(storage_type& storage, uint32_t offset, const Bytes& data) {
fbl::Span<T> span{storage.data(), storage.size()};
ASSERT_NO_FATAL_FAILURE(SpanTraits::Write(span, offset, data));
}
static void ToPayload(const storage_type& storage, uint32_t offset, payload_type& payload) {
ASSERT_LT(offset, storage.size());
payload = payload_type{storage.data() + offset, storage.size() - offset};
}
};
using FblByteArrayTestTraits = FblArrayTestTraits<std::byte>;
#endif // ZIRCON_SYSTEM_ULIB_ZBITL_TEST_MEMORY_TESTS_H_