loggersoft.kotlin.streams.StreamAdapter.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of binary-streams Show documentation
Show all versions of binary-streams Show documentation
Implementation of I/O binary streams for Kotlin.
/*
* Copyright (C) 2018 Alexander Kornilov ([email protected])
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package loggersoft.kotlin.streams
import java.io.EOFException
import java.io.InputStream
import java.io.OutputStream
import java.math.BigInteger
/**
* Provides [Stream] interface from Java [InputStream] and [OutputStream].
*
* @author Alexander Kornilov ([email protected]).
*/
class StreamAdapter(private val input: InputStream?, private val output: OutputStream?) : AbstractStream() {
/**
* Constructs adapter from [input] Java stream.
*/
constructor(input: InputStream): this(input, null)
/**
* Constructs adapter from [output] Java stream.
*/
constructor(output: OutputStream): this(null, output)
override val isReadable = input != null
override val isWritable = output != null
/**
* @see BasicStream.isSeekable
*/
override val isSeekable = false
/**
* @see BasicStream.isFixedSize
*/
override val isFixedSize = false
/**
* @see BasicStream.isSupportLimit
*/
override val isSupportLimit = false
/**
* @see BasicStream.bytesAvailable
*/
override val bytesAvailable: Long
get() = input?.available()?.toLong() ?: -1
/**
* @see BasicStream.isEof
*/
override val isEof: Boolean
get() = bytesAvailable == 0L
/**
* @see BasicStream.size
*/
override val size = -1L
override var position
get() = -1L; set(_) = Unit
private companion object {
const val DefaultBufferSize = 16
}
private var buffer = ByteArray(DefaultBufferSize)
override fun skip(bytes: Long): Long = input?.skip(bytes) ?: super.skip(bytes)
override fun readBytes(buffer: ByteArray, size: Int, offset: Int): Int {
input ?: throw IllegalStateException()
return input.read(buffer, offset, size)
}
override fun readByte(): Byte {
input ?: throw IllegalStateException()
return input.read().toByte()
}
override fun readInt(bytes: Int, signed: Boolean, byteOrder: ByteOrder): Long {
input ?: throw IllegalStateException()
checkBufSize(bytes)
if (input.read(buffer, 0, bytes) != bytes) throw EOFException()
return buffer.toInteger(bytes, signed, byteOrder)
}
override fun readLong(bytes: Int, signed: Boolean, byteOrder: ByteOrder): BigInteger {
input ?: throw IllegalStateException()
checkBufSize(bytes)
if (input.read(buffer, 0, bytes) != bytes) throw EOFException()
return buffer.toBigInteger(bytes, signed, byteOrder)
}
override fun writeBytes(buffer: ByteArray, size: Int, offset: Int) {
output ?: throw IllegalStateException()
output.write(buffer, offset, size)
}
override fun writeByte(value: Byte) {
output ?: throw IllegalStateException()
output.write(value.toInt())
}
override fun writeInt(value: Long, bytes: Int, byteOrder: ByteOrder) {
output ?: throw IllegalStateException()
checkBufSize(bytes)
value.toBytes(buffer, bytes, byteOrder)
output.write(buffer, 0, bytes)
}
override fun writeLong(value: BigInteger, bytes: Int, byteOrder: ByteOrder) {
output ?: throw IllegalStateException()
checkBufSize(bytes)
value.toBytes(buffer, bytes, byteOrder)
output.write(buffer, 0, bytes)
}
/**
* @see java.io.Flushable.flush
*/
override fun flush() {
output?.flush()
}
/**
* @see java.io.Closeable.close
*/
override fun close() {
isClosed = true
input?.close()
output?.close()
}
@Suppress("NOTHING_TO_INLINE")
private inline fun checkBufSize(bytes: Int) {
require(bytes > 0)
if (bytes > buffer.size) buffer = ByteArray(bytes)
}
}