ref: 2919df3a7321d4e904d6ed9cdd1c3c8c32a5ef6c
app/src/main/java/xyz/apiote/fruchtfleisch/Reader.kt
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 |
package xyz.apiote.fruchtfleisch import java.io.DataInputStream import java.io.EOFException import java.io.InputStream class Reader(private val stream: InputStream) { fun readUInt(): ULong { var result: ULong = 0UL var i = 0 var s = 0 while (true) { val b = stream.read() if (b < 0) { throw EOFException("while reading byte") } if (b < 0x80) { if (i > 9 || (i == 9 && b > 1)) { TODO("throw int overflow") } result = result.or(b.toULong().shl(s)) break } i++ s += 7 } return result } fun readInt(): Long { val unsigned = readUInt() var signed = unsigned.shr(1).toLong() if (unsigned.and(1UL) != 0UL) { signed = signed.inv() } return signed } fun readU8(): UByte { val b = stream.read() if (b < 0) { throw EOFException("while reading byte") } return b.toUByte() } fun readU16(): UShort { var result = 0U for (i in 0 until 2) { result = result or (readU8().toUInt().shl(2U.shl(i).toInt())) } return result.toUShort() } fun readU32(): UInt { var result = 0U for (i in 0 until 4) { result = result or (readU8().toUInt().shl(2U.shl(i).toInt())) } return result } fun readU64(): UShort { var result = 0U for (i in 0 until 8) { result = result or (readU8().toUInt().shl(2U.shl(i).toInt())) } return result.toUShort() } fun readI8(): Byte { return readU8().toByte() } fun readFloat32(): Float { return DataInputStream(stream).readFloat() } fun readFloat64(): Double { return DataInputStream(stream).readDouble() } fun readData(length: UByte): ByteArray { val n = length.toInt() val data = ByteArray(n) var left = n while (left > 0) { val r = stream.read(data, n - left, left) left -= r } return data } fun readString(): String { val length = readU8() return readData(length).decodeToString() } fun readBoolean(): Boolean { return when (readU8().toUInt()) { 0u -> false 1u -> true else -> TODO("throw wrong value") } } } |