new outputstream for bytearray64

This commit is contained in:
Minjae Song
2018-10-06 01:16:26 +09:00
parent e072aff897
commit 74d76440ee
4 changed files with 72 additions and 21 deletions

View File

@@ -1,9 +1,7 @@
package net.torvald.terrarum.modulecomputers.virtualcomputer.tvd package net.torvald.terrarum.modulecomputers.virtualcomputer.tvd
import java.io.BufferedOutputStream import java.io.*
import java.io.File import java.util.*
import java.io.FileOutputStream
import java.io.InputStream
/** /**
@@ -18,7 +16,7 @@ class ByteArray64(val size: Long) {
val bankSize: Int = 8192 val bankSize: Int = 8192
} }
private val data: Array<ByteArray> internal val __data: Array<ByteArray>
init { init {
if (size < 0) if (size < 0)
@@ -26,7 +24,7 @@ class ByteArray64(val size: Long) {
val requiredBanks: Int = 1 + ((size - 1) / bankSize).toInt() val requiredBanks: Int = 1 + ((size - 1) / bankSize).toInt()
data = Array<ByteArray>( __data = Array<ByteArray>(
requiredBanks, requiredBanks,
{ bankIndex -> { bankIndex ->
kotlin.ByteArray( kotlin.ByteArray(
@@ -48,14 +46,14 @@ class ByteArray64(val size: Long) {
if (index < 0 || index >= size) if (index < 0 || index >= size)
throw ArrayIndexOutOfBoundsException("size $size, index $index") throw ArrayIndexOutOfBoundsException("size $size, index $index")
data[index.toBankNumber()][index.toBankOffset()] = value __data[index.toBankNumber()][index.toBankOffset()] = value
} }
operator fun get(index: Long): Byte { operator fun get(index: Long): Byte {
if (index < 0 || index >= size) if (index < 0 || index >= size)
throw ArrayIndexOutOfBoundsException("size $size, index $index") throw ArrayIndexOutOfBoundsException("size $size, index $index")
return data[index.toBankNumber()][index.toBankOffset()] return __data[index.toBankNumber()][index.toBankOffset()]
} }
operator fun iterator(): ByteIterator { operator fun iterator(): ByteIterator {
@@ -99,7 +97,7 @@ class ByteArray64(val size: Long) {
fun forEach(consumer: (Byte) -> Unit) = iterator().forEach { consumer(it) } fun forEach(consumer: (Byte) -> Unit) = iterator().forEach { consumer(it) }
fun forEachInt32(consumer: (Int) -> Unit) = iteratorChoppedToInt().forEach { consumer(it) } fun forEachInt32(consumer: (Int) -> Unit) = iteratorChoppedToInt().forEach { consumer(it) }
fun forEachBanks(consumer: (ByteArray) -> Unit) = data.forEach(consumer) fun forEachBanks(consumer: (ByteArray) -> Unit) = __data.forEach(consumer)
fun sliceArray64(range: LongRange): ByteArray64 { fun sliceArray64(range: LongRange): ByteArray64 {
val newarr = ByteArray64(range.last - range.first + 1) val newarr = ByteArray64(range.last - range.first + 1)
@@ -126,14 +124,14 @@ class ByteArray64(val size: Long) {
fun writeToFile(file: File) { fun writeToFile(file: File) {
var fos = FileOutputStream(file, false) var fos = FileOutputStream(file, false)
fos.write(data[0]) fos.write(__data[0])
fos.flush() fos.flush()
fos.close() fos.close()
if (data.size > 1) { if (__data.size > 1) {
fos = FileOutputStream(file, true) fos = FileOutputStream(file, true)
for (i in 1..data.lastIndex) { for (i in 1..__data.lastIndex) {
fos.write(data[i]) fos.write(__data[i])
fos.flush() fos.flush()
} }
fos.close() fos.close()
@@ -141,8 +139,8 @@ class ByteArray64(val size: Long) {
} }
} }
class ByteArray64InputStream(val byteArray64: ByteArray64): InputStream() { open class ByteArray64InputStream(val byteArray64: ByteArray64): InputStream() {
private var readCounter = 0L protected open var readCounter = 0L
override fun read(): Int { override fun read(): Int {
readCounter += 1 readCounter += 1
@@ -154,4 +152,62 @@ class ByteArray64InputStream(val byteArray64: ByteArray64): InputStream() {
-1 -1
} }
} }
}
/** Static ByteArray OutputStream. Less leeway, more stable. */
open class ByteArray64OutputStream(val byteArray64: ByteArray64): OutputStream() {
protected open var writeCounter = 0L
override fun write(b: Int) {
try {
writeCounter += 1
byteArray64[writeCounter - 1] = b.toByte()
}
catch (e: ArrayIndexOutOfBoundsException) {
throw IOException(e)
}
}
}
/** Just like Java's ByteArrayOutputStream, except DON'T TRY TO GROW THE BUFFER */
open class ByteArray64GrowableOutputStream(val size: Long = ByteArray64.bankSize.toLong()): OutputStream() {
protected open var buf = ByteArray64(size)
protected open var count = 0L
override fun write(b: Int) {
ensureCapacity(count + 1)
buf[count] = b.toByte()
count += 1
}
private fun ensureCapacity(minCapacity: Long) {
// overflow-conscious code
if (minCapacity - buf.size > 0)
grow(minCapacity)
}
private fun grow(minCapacity: Long) {
// overflow-conscious code
val oldCapacity = buf.size
var newCapacity = oldCapacity shl 1
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity
// double the capacity
val newBuffer = ByteArray64(buf.size * 2)
buf.__data.forEachIndexed { index, bytes ->
System.arraycopy(
buf.__data[index], 0,
newBuffer.__data[index], 0, buf.__data.size
)
}
buf = newBuffer
System.gc()
}
/** Unlike Java's, this does NOT create a copy of the internal buffer; this just returns its internal. */
@Synchronized
fun toByteArray64(): ByteArray64 {
return buf
}
} }

View File

@@ -15,6 +15,7 @@ Ord Hex Description
06 05 Number of payloads 06 05 Number of payloads
07 01 Compression algorithm, 0 for none, 1 for DEFLATE, 2 for LZMA, otherwise undefined (maybe LZMA2 for the future?) 07 01 Compression algorithm, 0 for none, 1 for DEFLATE, 2 for LZMA, otherwise undefined (maybe LZMA2 for the future?)
Value of 01 (DEFLATE) is recommended for its faster compression
08 World width 08 World width
09 World width 09 World width