mirror of https://github.com/OpenTTD/OpenTTD
Codechange: Move NewGRF ByteReader to own file.
parent
84f785b06b
commit
fe9dfa2b08
|
@ -17,6 +17,7 @@ add_subdirectory(linkgraph)
|
|||
add_subdirectory(misc)
|
||||
add_subdirectory(music)
|
||||
add_subdirectory(network)
|
||||
add_subdirectory(newgrf)
|
||||
add_subdirectory(os)
|
||||
add_subdirectory(pathfinder)
|
||||
add_subdirectory(saveload)
|
||||
|
|
|
@ -54,6 +54,7 @@
|
|||
#include "vehicle_base.h"
|
||||
#include "road.h"
|
||||
#include "newgrf_roadstop.h"
|
||||
#include "newgrf/newgrf_bytereader.h"
|
||||
|
||||
#include "table/strings.h"
|
||||
#include "table/build_industry.h"
|
||||
|
@ -213,102 +214,6 @@ static inline bool IsValidNewGRFImageIndex(uint8_t image_index)
|
|||
return image_index == 0xFD || IsValidImageIndex<T>(image_index);
|
||||
}
|
||||
|
||||
class OTTDByteReaderSignal { };
|
||||
|
||||
/** Class to read from a NewGRF file */
|
||||
class ByteReader {
|
||||
protected:
|
||||
uint8_t *data;
|
||||
uint8_t *end;
|
||||
|
||||
public:
|
||||
ByteReader(uint8_t *data, uint8_t *end) : data(data), end(end) { }
|
||||
|
||||
inline uint8_t *ReadBytes(size_t size)
|
||||
{
|
||||
if (data + size >= end) {
|
||||
/* Put data at the end, as would happen if every byte had been individually read. */
|
||||
data = end;
|
||||
throw OTTDByteReaderSignal();
|
||||
}
|
||||
|
||||
uint8_t *ret = data;
|
||||
data += size;
|
||||
return ret;
|
||||
}
|
||||
|
||||
inline uint8_t ReadByte()
|
||||
{
|
||||
if (data < end) return *(data)++;
|
||||
throw OTTDByteReaderSignal();
|
||||
}
|
||||
|
||||
uint16_t ReadWord()
|
||||
{
|
||||
uint16_t val = ReadByte();
|
||||
return val | (ReadByte() << 8);
|
||||
}
|
||||
|
||||
uint16_t ReadExtendedByte()
|
||||
{
|
||||
uint16_t val = ReadByte();
|
||||
return val == 0xFF ? ReadWord() : val;
|
||||
}
|
||||
|
||||
uint32_t ReadDWord()
|
||||
{
|
||||
uint32_t val = ReadWord();
|
||||
return val | (ReadWord() << 16);
|
||||
}
|
||||
|
||||
uint32_t PeekDWord()
|
||||
{
|
||||
AutoRestoreBackup backup(this->data, this->data);
|
||||
return this->ReadDWord();
|
||||
}
|
||||
|
||||
uint32_t ReadVarSize(uint8_t size)
|
||||
{
|
||||
switch (size) {
|
||||
case 1: return ReadByte();
|
||||
case 2: return ReadWord();
|
||||
case 4: return ReadDWord();
|
||||
default:
|
||||
NOT_REACHED();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
std::string_view ReadString()
|
||||
{
|
||||
char *string = reinterpret_cast<char *>(data);
|
||||
size_t string_length = ttd_strnlen(string, Remaining());
|
||||
|
||||
/* Skip past the terminating NUL byte if it is present, but not more than remaining. */
|
||||
Skip(std::min(string_length + 1, Remaining()));
|
||||
|
||||
return std::string_view(string, string_length);
|
||||
}
|
||||
|
||||
inline size_t Remaining() const
|
||||
{
|
||||
return end - data;
|
||||
}
|
||||
|
||||
inline bool HasData(size_t count = 1) const
|
||||
{
|
||||
return data + count <= end;
|
||||
}
|
||||
|
||||
inline void Skip(size_t len)
|
||||
{
|
||||
data += len;
|
||||
/* It is valid to move the buffer to exactly the end of the data,
|
||||
* as there may not be any more data read. */
|
||||
if (data > end) throw OTTDByteReaderSignal();
|
||||
}
|
||||
};
|
||||
|
||||
typedef void (*SpecialSpriteHandler)(ByteReader &buf);
|
||||
|
||||
/** The maximum amount of stations a single GRF is allowed to add */
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
add_files(
|
||||
newgrf_bytereader.cpp
|
||||
newgrf_bytereader.h
|
||||
)
|
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* This file is part of OpenTTD.
|
||||
* 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.
|
||||
* 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.
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
/** @file newgrf_bytereader.cpp NewGRF byte buffer reader implementation. */
|
||||
|
||||
#include "../stdafx.h"
|
||||
#include "../core/backup_type.hpp"
|
||||
#include "../string_func.h"
|
||||
#include "newgrf_bytereader.h"
|
||||
|
||||
#include "../safeguards.h"
|
||||
|
||||
/**
|
||||
* Read a single DWord (32 bits).
|
||||
* @note The buffer is NOT advanced.
|
||||
* @returns Value read from buffer.
|
||||
*/
|
||||
uint32_t ByteReader::PeekDWord()
|
||||
{
|
||||
AutoRestoreBackup backup(this->data, this->data);
|
||||
return this->ReadDWord();
|
||||
}
|
||||
|
||||
/**
|
||||
* Read a value of the given number of bytes.
|
||||
* @returns Value read from buffer.
|
||||
*/
|
||||
uint32_t ByteReader::ReadVarSize(uint8_t size)
|
||||
{
|
||||
switch (size) {
|
||||
case 1: return this->ReadByte();
|
||||
case 2: return this->ReadWord();
|
||||
case 4: return this->ReadDWord();
|
||||
default:
|
||||
NOT_REACHED();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Read a string.
|
||||
* @returns Sting read from the buffer.
|
||||
*/
|
||||
std::string_view ByteReader::ReadString()
|
||||
{
|
||||
const char *string = reinterpret_cast<const char *>(this->data);
|
||||
size_t string_length = ttd_strnlen(string, this->Remaining());
|
||||
|
||||
/* Skip past the terminating NUL byte if it is present, but not more than remaining. */
|
||||
this->Skip(std::min(string_length + 1, this->Remaining()));
|
||||
|
||||
return std::string_view(string, string_length);
|
||||
}
|
|
@ -0,0 +1,100 @@
|
|||
/*
|
||||
* This file is part of OpenTTD.
|
||||
* 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.
|
||||
* 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.
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
/** @file newgrf_bytereader.h NewGRF buffer reader definition. */
|
||||
|
||||
#ifndef NEWGRF_BYTEREADER_H
|
||||
#define NEWGRF_BYTEREADER_H
|
||||
|
||||
class OTTDByteReaderSignal { };
|
||||
|
||||
/** Class to read from a NewGRF file */
|
||||
class ByteReader {
|
||||
public:
|
||||
ByteReader(const uint8_t *data, const uint8_t *end) : data(data), end(end) { }
|
||||
|
||||
const uint8_t *ReadBytes(size_t size)
|
||||
{
|
||||
if (this->data + size >= this->end) {
|
||||
/* Put data at the end, as would happen if every byte had been individually read. */
|
||||
this->data = this->end;
|
||||
throw OTTDByteReaderSignal();
|
||||
}
|
||||
|
||||
const uint8_t *ret = this->data;
|
||||
this->data += size;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read a single byte (8 bits).
|
||||
* @return Value read from buffer.
|
||||
*/
|
||||
uint8_t ReadByte()
|
||||
{
|
||||
if (this->data < this->end) return *this->data++;
|
||||
throw OTTDByteReaderSignal();
|
||||
}
|
||||
|
||||
/**
|
||||
* Read a single Word (16 bits).
|
||||
* @return Value read from buffer.
|
||||
*/
|
||||
uint16_t ReadWord()
|
||||
{
|
||||
uint16_t val = this->ReadByte();
|
||||
return val | (this->ReadByte() << 8);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read a single Extended Byte (8 or 16 bits).
|
||||
* @return Value read from buffer.
|
||||
*/
|
||||
uint16_t ReadExtendedByte()
|
||||
{
|
||||
uint16_t val = this->ReadByte();
|
||||
return val == 0xFF ? this->ReadWord() : val;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read a single DWord (32 bits).
|
||||
* @return Value read from buffer.
|
||||
*/
|
||||
uint32_t ReadDWord()
|
||||
{
|
||||
uint32_t val = this->ReadWord();
|
||||
return val | (this->ReadWord() << 16);
|
||||
}
|
||||
|
||||
uint32_t PeekDWord();
|
||||
uint32_t ReadVarSize(uint8_t size);
|
||||
std::string_view ReadString();
|
||||
|
||||
size_t Remaining() const
|
||||
{
|
||||
return this->end - this->data;
|
||||
}
|
||||
|
||||
bool HasData(size_t count = 1) const
|
||||
{
|
||||
return this->data + count <= this->end;
|
||||
}
|
||||
|
||||
void Skip(size_t len)
|
||||
{
|
||||
this->data += len;
|
||||
/* It is valid to move the buffer to exactly the end of the data,
|
||||
* as there may not be any more data read. */
|
||||
if (this->data > this->end) throw OTTDByteReaderSignal();
|
||||
}
|
||||
|
||||
private:
|
||||
const uint8_t *data; ///< Current position within data.
|
||||
const uint8_t *end; ///< Last position of data.
|
||||
};
|
||||
|
||||
#endif /* NEWGRF_BYTEREADER_H */
|
Loading…
Reference in New Issue