BSPParser
Simple and modern library for parsing the Valve BSP format
Loading...
Searching...
No Matches
offset-data-view.hpp
1#pragma once
2
3#include "check-bounds.hpp"
4#include <memory>
5#include <span>
6
7namespace BspParser::Internal {
8 class OffsetDataView {
9 public:
10 template <typename T> using ValueOffsetPair = std::pair<T, size_t>;
11
12 explicit OffsetDataView(std::span<const std::byte> data);
13
14 explicit OffsetDataView(const OffsetDataView& from, size_t newOffset);
15
16 ~OffsetDataView() = default;
17 OffsetDataView(const OffsetDataView&) = delete;
18 OffsetDataView& operator=(const OffsetDataView&) = delete;
19 OffsetDataView(const OffsetDataView&&) = delete;
20 OffsetDataView& operator=(const OffsetDataView&&) = delete;
21
22 [[nodiscard]] OffsetDataView withRelativeOffset(size_t newOffset) const;
23
24 template <typename T>
25 [[nodiscard]] const T& parseStruct(const size_t relativeOffset, const char* errorMessage) const {
26 const auto absoluteOffset = offset + relativeOffset;
27 checkBounds(absoluteOffset, sizeof(T), data.size_bytes(), errorMessage);
28
29 return *reinterpret_cast<const T*>(&data[absoluteOffset]);
30 }
31
32 template <typename T>
33 [[nodiscard]] std::span<const T> parseStructArray(
34 const size_t relativeOffset, const size_t count, const char* errorMessage
35 ) const {
36 if (count == 0) {
37 return std::span<const T>(static_cast<const T*>(nullptr), 0);
38 }
39
40 const auto absoluteOffset = offset + relativeOffset;
41 checkBounds(absoluteOffset, sizeof(T) * count, data.size_bytes(), errorMessage);
42
43 const T* first = reinterpret_cast<const T*>(&data[absoluteOffset]);
44 return std::span<const T>(first, count);
45 }
46
47 std::string parseString(size_t relativeOffset, const char* errorMessage) const;
48
49 private:
50 const std::span<const std::byte> data;
51 const size_t offset;
52 };
53}