All Downloads are FREE. Search and download functionalities are using the official Maven repository.

loggersoft.kotlin.streams.StreamAdapter.kt Maven / Gradle / Ivy

There is a newer version: 0.33
Show newest version
/*
 * 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)
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy