File indexing completed on 2025-01-05 04:01:21
0001 /* 0002 * SPDX-FileCopyrightText: 2019-2023 Mattia Basaglia <dev@dragon.best> 0003 * 0004 * SPDX-License-Identifier: GPL-3.0-or-later 0005 */ 0006 0007 #include "binary_stream.hpp" 0008 0009 #include <array> 0010 #include <QtEndian> 0011 0012 glaxnimate::io::BinaryInputStream::BinaryInputStream(QIODevice* file): 0013 BinaryInputStream(file->readAll()) 0014 { 0015 } 0016 0017 glaxnimate::io::BinaryInputStream::BinaryInputStream(QByteArray data): 0018 data(std::move(data)), 0019 data_start(this->data.data()), 0020 data_end(data_start + this->data.size()) 0021 { 0022 } 0023 0024 void glaxnimate::io::BinaryInputStream::on_overflow() 0025 { 0026 error = true; 0027 } 0028 0029 bool glaxnimate::io::BinaryInputStream::eof() const 0030 { 0031 return data_start >= data_end; 0032 } 0033 0034 bool glaxnimate::io::BinaryInputStream::has_error() const 0035 { 0036 return error; 0037 } 0038 0039 QByteArray glaxnimate::io::BinaryInputStream::read(qint64 max_size) 0040 { 0041 if ( data_start + max_size < data_end ) 0042 { 0043 data_start += max_size; 0044 return QByteArray(data_start - max_size, max_size); 0045 } 0046 0047 on_overflow(); 0048 return {}; 0049 } 0050 0051 quint8 glaxnimate::io::BinaryInputStream::next() 0052 { 0053 if ( data_start < data_end ) 0054 { 0055 ++data_start; 0056 return data_start[-1]; 0057 } 0058 0059 on_overflow(); 0060 return {}; 0061 } 0062 0063 quint32 glaxnimate::io::BinaryInputStream::read_uint32_le() 0064 { 0065 static_assert(sizeof(quint32) == 4); 0066 auto data = read(4); 0067 if ( data.size() == 4 ) 0068 { 0069 return qFromLittleEndian<quint32>(data.data()); 0070 } 0071 else 0072 { 0073 return 0; 0074 } 0075 } 0076 0077 glaxnimate::io::Float32 glaxnimate::io::BinaryInputStream::read_float32_le() 0078 { 0079 static_assert(sizeof(Float32) == 4); 0080 auto data = read(4); 0081 if ( data.size() == 4 ) 0082 { 0083 return qFromLittleEndian<Float32>(data.data()); 0084 } 0085 else 0086 { 0087 on_overflow(); 0088 return 0; 0089 } 0090 } 0091 0092 glaxnimate::io::VarUint glaxnimate::io::BinaryInputStream::read_uint_leb128() 0093 { 0094 VarUint result = 0; 0095 VarUint shift = 0; 0096 while (true) 0097 { 0098 quint8 byte = next(); 0099 if ( error ) 0100 return 0; 0101 0102 result |= VarUint(byte & 0x7f) << shift; 0103 0104 if ( !(byte & 0x80) ) 0105 return result; 0106 0107 shift += 7; 0108 } 0109 } 0110 0111 glaxnimate::io::BinaryOutputStream::BinaryOutputStream(QIODevice* file) 0112 : file(file) 0113 { 0114 } 0115 0116 void glaxnimate::io::BinaryOutputStream::write(const QByteArray& data) 0117 { 0118 file->write(data); 0119 } 0120 0121 void glaxnimate::io::BinaryOutputStream::write_byte(quint8 v) 0122 { 0123 file->putChar(v); 0124 } 0125 0126 void glaxnimate::io::BinaryOutputStream::write_float32_le(glaxnimate::io::Float32 v) 0127 { 0128 static_assert(sizeof(Float32) == 4); 0129 std::array<quint8, 4> data; 0130 qToLittleEndian(v, data.data()); 0131 file->write((const char*)data.data(), 4); 0132 } 0133 0134 void glaxnimate::io::BinaryOutputStream::write_uint32_le(quint32 v) 0135 { 0136 static_assert(sizeof(quint32) == 4); 0137 std::array<quint8, 4> data; 0138 qToLittleEndian(v, data.data()); 0139 file->write((const char*)data.data(), 4); 0140 } 0141 0142 void glaxnimate::io::BinaryOutputStream::write_uint_leb128(glaxnimate::io::VarUint v) 0143 { 0144 while ( true ) 0145 { 0146 quint8 byte = v & 0x7f; 0147 v >>= 7; 0148 if ( v == 0 ) 0149 { 0150 write_byte(byte); 0151 break; 0152 } 0153 write_byte(byte | 0x80); 0154 } 0155 }