OpenTTD Source 20250529-master-g10c159a79f
newgrf_bytereader.h
Go to the documentation of this file.
1/*
2 * This file is part of OpenTTD.
3 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
4 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
5 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
6 */
7
10#ifndef NEWGRF_BYTEREADER_H
11#define NEWGRF_BYTEREADER_H
12
13#include "../core/string_consumer.hpp"
14
16
19 StringConsumer consumer;
20public:
21 ByteReader(const uint8_t *data, size_t len) : consumer(std::string_view{reinterpret_cast<const char *>(data), len}) { }
22
23 const uint8_t *ReadBytes(size_t size)
24 {
25 auto result = this->consumer.Read(size);
26 if (result.size() != size) throw OTTDByteReaderSignal();
27 return reinterpret_cast<const uint8_t *>(result.data());
28 }
29
34 uint8_t ReadByte()
35 {
36 auto result = this->consumer.TryReadUint8();
37 if (!result.has_value()) throw OTTDByteReaderSignal();
38 return *result;
39 }
40
45 uint16_t ReadWord()
46 {
47 auto result = this->consumer.TryReadUint16LE();
48 if (!result.has_value()) throw OTTDByteReaderSignal();
49 return *result;
50 }
51
57 {
58 uint16_t val = this->ReadByte();
59 return val == 0xFF ? this->ReadWord() : val;
60 }
61
66 uint32_t ReadDWord()
67 {
68 auto result = this->consumer.TryReadUint32LE();
69 if (!result.has_value()) throw OTTDByteReaderSignal();
70 return *result;
71 }
72
78 uint32_t PeekDWord()
79 {
80 auto result = this->consumer.PeekUint32LE();
81 if (!result.has_value()) throw OTTDByteReaderSignal();
82 return *result;
83 }
84
85 uint32_t ReadVarSize(uint8_t size);
86
91 std::string_view ReadString()
92 {
93 /* Terminating NUL may be missing at the end of sprite. */
94 return this->consumer.ReadUntilChar('\0', StringConsumer::SKIP_ONE_SEPARATOR);
95 }
96
97 size_t Remaining() const
98 {
99 return this->consumer.GetBytesLeft();
100 }
101
102 bool HasData(size_t count = 1) const
103 {
104 return count <= this->consumer.GetBytesLeft();
105 }
106
107 void Skip(size_t len)
108 {
109 auto result = this->consumer.Read(len);
110 if (result.size() != len) throw OTTDByteReaderSignal();
111 }
112
113};
114
115#endif /* NEWGRF_BYTEREADER_H */
Class to read from a NewGRF file.
uint32_t PeekDWord()
Read a single DWord (32 bits).
uint32_t ReadDWord()
Read a single DWord (32 bits).
uint16_t ReadWord()
Read a single Word (16 bits).
std::string_view ReadString()
Read a NUL-terminated string.
uint16_t ReadExtendedByte()
Read a single Extended Byte (8 or 16 bits).
uint32_t ReadVarSize(uint8_t size)
Read a value of the given number of bytes.
uint8_t ReadByte()
Read a single byte (8 bits).
Parse data from a string / buffer.
std::optional< uint32_t > TryReadUint32LE()
Try to read binary uint32, and then advance reader.
std::string_view ReadUntilChar(char c, SeparatorUsage sep)
Read data until the first occurrence of 8-bit char 'c', and advance reader.
@ SKIP_ONE_SEPARATOR
Read and discard one separator, do not include it in the result.
std::optional< uint32_t > PeekUint32LE() const
Peek binary uint32 using little endian.
std::optional< uint16_t > TryReadUint16LE()
Try to read binary uint16, and then advance reader.
size_type GetBytesLeft() const noexcept
Get number of bytes left to read.
std::optional< uint8_t > TryReadUint8()
Try to read binary uint8, and then advance reader.
std::string_view Read(size_type len)
Read the next 'len' bytes, and advance reader.