/* Copyright (C) 2026 Carl Hetherington This file is part of libttf. libttf 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; either version 2 of the License, or (at your option) any later version. libttf 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 libttf. If not, see . */ #include #include #include #include namespace ttf { class ParseError : public std::runtime_error { public: ParseError() : std::runtime_error("Parse error") {} }; /** Class which offers data read from a memory buffer */ class Source { public: explicit Source(std::vector const& data); Source(uint8_t const* data, int size); Source(Source& other, uint32_t offset); uint16_t get_uint16(); uint32_t get_uint32(); std::string get_string(uint32_t offset, uint16_t length); std::wstring get_wstring(uint32_t offset, uint16_t length); std::vector get_block(uint32_t offset, uint32_t length); uint32_t offset() const { return _offset; } uint8_t const* data() { return _data; } int size() const { return _size; } private: uint8_t const* _data; int _size; uint32_t _offset; }; /** Class which accepts data to be written into a memory buffer */ class Sink { public: explicit Sink(std::vector& data, uint32_t offset = 0); Sink(Sink&) = delete; Sink& operator=(Sink&) = delete; Sink(Sink&& other) = delete; Sink& operator=(Sink&& other) = delete; void put(uint16_t value); void put(uint32_t value); void put(uint32_t value, uint32_t offset); void put(std::string const& data); void put(std::wstring const& data); void put(std::vector const& data); std::vector& data() { return _data; } uint32_t initial_offset() const { return _initial_offset; } uint32_t offset() const { return _offset; } uint32_t offset_from_initial() const { return _offset - _initial_offset; } void set_offset(uint32_t offset) { _offset = offset; } void pad(); uint32_t checksum(uint32_t start) const; private: std::vector& _data; uint32_t _initial_offset; uint32_t _offset; }; /** Sink which starts at a given offset from another Sink's offset, * and on destruction sets its parent offset to be the same as its * own. */ class SubSink : public Sink { public: explicit SubSink(Sink& parent, uint32_t offset = 0); SubSink(SubSink const&) = delete; SubSink& operator=(SubSink const&) = delete; SubSink(SubSink&& other) = delete; SubSink& operator=(SubSink&& other) = delete; ~SubSink(); private: Sink& _parent; }; uint32_t checksum(std::vector const& data); uint32_t checksum(uint8_t const* data, uint32_t size); }