import java.io.IOException import java.io.InputStream import java.util.* @Throws(IOException::class) fun InputStream.readNBytesCompat(len: Int): ByteArray? { require(len >= 0) { "len < 0" } var bufs: MutableList? = null var result: ByteArray? = null var total = 0 var remaining = len var n: Int do { val buf = ByteArray(remaining.coerceAtMost(8192)) var nread = 0 // read to EOF which may read more or less than buffer size while (read( buf, nread, (buf.size - nread).coerceAtMost(remaining) ).also { n = it } > 0 ) { nread += n remaining -= n } if (nread > 0) { if (Int.MAX_VALUE - 8 - total < nread) { throw OutOfMemoryError("Required array size too large") } total += nread if (result == null) { result = buf } else { if (bufs == null) { bufs = ArrayList() bufs.add(result) } bufs.add(buf) } } // if the last call to read returned -1 or the number of bytes // requested have been read then break } while (n >= 0 && remaining > 0) if (bufs == null) { if (result == null) { return ByteArray(0) } return if (result.size == total) result else Arrays.copyOf(result, total) } result = ByteArray(total) var offset = 0 remaining = total for (b in bufs) { val count = b.size.coerceAtMost(remaining) System.arraycopy(b, 0, result, offset, count) offset += count remaining -= count } return result } @Throws(IOException::class) fun InputStream.readAllBytesCompat(): ByteArray? { return readNBytesCompat(Int.MAX_VALUE) } fun ByteArray.toHexString() = joinToString("") { "%02X".format(it) }