1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-19 11:02:59 +02:00
llvm-mirror/include/llvm/Support/BinaryItemStream.h
Chandler Carruth ae65e281f3 Update the file headers across all of the LLVM projects in the monorepo
to reflect the new license.

We understand that people may be surprised that we're moving the header
entirely to discuss the new license. We checked this carefully with the
Foundation's lawyer and we believe this is the correct approach.

Essentially, all code in the project is now made available by the LLVM
project under our new license, so you will see that the license headers
include that license only. Some of our contributors have contributed
code under our old license, and accordingly, we have retained a copy of
our old license notice in the top-level files in each project and
repository.

llvm-svn: 351636
2019-01-19 08:50:56 +00:00

108 lines
3.6 KiB
C++

//===- BinaryItemStream.h ---------------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_SUPPORT_BINARYITEMSTREAM_H
#define LLVM_SUPPORT_BINARYITEMSTREAM_H
#include "llvm/ADT/ArrayRef.h"
#include "llvm/Support/BinaryStream.h"
#include "llvm/Support/BinaryStreamError.h"
#include "llvm/Support/Error.h"
#include <cstddef>
#include <cstdint>
namespace llvm {
template <typename T> struct BinaryItemTraits {
static size_t length(const T &Item) = delete;
static ArrayRef<uint8_t> bytes(const T &Item) = delete;
};
/// BinaryItemStream represents a sequence of objects stored in some kind of
/// external container but for which it is useful to view as a stream of
/// contiguous bytes. An example of this might be if you have a collection of
/// records and you serialize each one into a buffer, and store these serialized
/// records in a container. The pointers themselves are not laid out
/// contiguously in memory, but we may wish to read from or write to these
/// records as if they were.
template <typename T, typename Traits = BinaryItemTraits<T>>
class BinaryItemStream : public BinaryStream {
public:
explicit BinaryItemStream(llvm::support::endianness Endian)
: Endian(Endian) {}
llvm::support::endianness getEndian() const override { return Endian; }
Error readBytes(uint32_t Offset, uint32_t Size,
ArrayRef<uint8_t> &Buffer) override {
auto ExpectedIndex = translateOffsetIndex(Offset);
if (!ExpectedIndex)
return ExpectedIndex.takeError();
const auto &Item = Items[*ExpectedIndex];
if (auto EC = checkOffsetForRead(Offset, Size))
return EC;
if (Size > Traits::length(Item))
return make_error<BinaryStreamError>(stream_error_code::stream_too_short);
Buffer = Traits::bytes(Item).take_front(Size);
return Error::success();
}
Error readLongestContiguousChunk(uint32_t Offset,
ArrayRef<uint8_t> &Buffer) override {
auto ExpectedIndex = translateOffsetIndex(Offset);
if (!ExpectedIndex)
return ExpectedIndex.takeError();
Buffer = Traits::bytes(Items[*ExpectedIndex]);
return Error::success();
}
void setItems(ArrayRef<T> ItemArray) {
Items = ItemArray;
computeItemOffsets();
}
uint32_t getLength() override {
return ItemEndOffsets.empty() ? 0 : ItemEndOffsets.back();
}
private:
void computeItemOffsets() {
ItemEndOffsets.clear();
ItemEndOffsets.reserve(Items.size());
uint32_t CurrentOffset = 0;
for (const auto &Item : Items) {
uint32_t Len = Traits::length(Item);
assert(Len > 0 && "no empty items");
CurrentOffset += Len;
ItemEndOffsets.push_back(CurrentOffset);
}
}
Expected<uint32_t> translateOffsetIndex(uint32_t Offset) {
// Make sure the offset is somewhere in our items array.
if (Offset >= getLength())
return make_error<BinaryStreamError>(stream_error_code::stream_too_short);
++Offset;
auto Iter =
std::lower_bound(ItemEndOffsets.begin(), ItemEndOffsets.end(), Offset);
size_t Idx = std::distance(ItemEndOffsets.begin(), Iter);
assert(Idx < Items.size() && "binary search for offset failed");
return Idx;
}
llvm::support::endianness Endian;
ArrayRef<T> Items;
// Sorted vector of offsets to accelerate lookup.
std::vector<uint32_t> ItemEndOffsets;
};
} // end namespace llvm
#endif // LLVM_SUPPORT_BINARYITEMSTREAM_H