package
import java.io.{IOException, InputStream, OutputStream}
import java.nio.charset.StandardCharsets
import java.nio.{ByteBuffer, ByteOrder}
object StreamUtil {
def readBytes(stream: InputStream, byteCount: Int): Array[Byte] = {
val bytes = new Array[Byte](byteCount)
var offset = 0
while (offset < bytes.size) {
val read = stream.read(bytes, offset, bytes.size - offset)
if (read == -1) {
return bytes
}
offset += read
}
if (offset != bytes.size) {
throw new IOException("Unexpected EOF")
}
bytes
}
def readBoolean(stream: InputStream): Boolean = {
ByteBuffer.wrap(readBytes(stream, 1)).get() != 0
}
def readInt(stream: InputStream): Int = {
ByteBuffer.wrap(readBytes(stream, Integer.BYTES)).order(ByteOrder.LITTLE_ENDIAN).getInt
}
def readLong(stream: InputStream): Long = {
ByteBuffer.wrap(readBytes(stream, java.lang.Long.BYTES)).order(ByteOrder.LITTLE_ENDIAN).getLong
}
def readFloat(stream: InputStream): Float = {
ByteBuffer.wrap(readBytes(stream, java.lang.Float.BYTES)).order(ByteOrder.LITTLE_ENDIAN).getFloat
}
def readDouble(stream: InputStream): Double = {
ByteBuffer.wrap(readBytes(stream, java.lang.Double.BYTES)).order(ByteOrder.LITTLE_ENDIAN).getDouble
}
def readString(stream: InputStream): String = {
new String(readBytes(stream, readInt(stream)), StandardCharsets.UTF_8)
}
def writeBytes(stream: OutputStream, bytes: Array[Byte]): Unit = {
stream.write(bytes)
}
def writeBoolean(stream: OutputStream, value: Boolean): Unit = {
writeBytes(stream, Array.fill[Byte](1)((if (value) 1 else 0).toByte))
}
def writeInt(stream: OutputStream, value: Int): Unit = {
writeBytes(stream, ByteBuffer.allocate(Integer.BYTES).order(ByteOrder.LITTLE_ENDIAN).putInt(value).array())
}
def writeLong(stream: OutputStream, value: Long): Unit = {
writeBytes(stream, ByteBuffer.allocate(java.lang.Long.BYTES).order(ByteOrder.LITTLE_ENDIAN).putLong(value).array())
}
def writeFloat(stream: OutputStream, value: Float): Unit = {
writeBytes(stream, ByteBuffer.allocate(java.lang.Float.BYTES).order(ByteOrder.LITTLE_ENDIAN).putFloat(value).array())
}
def writeDouble(stream: OutputStream, value: Double): Unit = {
writeBytes(stream, ByteBuffer.allocate(java.lang.Double.BYTES).order(ByteOrder.LITTLE_ENDIAN).putDouble(value).array())
}
def writeString(stream: OutputStream, value: String): Unit = {
val bytes = value.getBytes(StandardCharsets.UTF_8)
writeInt(stream, bytes.size)
writeBytes(stream, bytes)
}
}