payloadutil and unhelpful commit message

This commit is contained in:
minjaesong
2019-02-20 22:43:35 +09:00
parent c9ac844e75
commit 1906cff519
8 changed files with 200 additions and 92 deletions

View File

@@ -0,0 +1,114 @@
package net.torvald.terrarum.serialise
import net.torvald.terrarum.AppLoader
import net.torvald.terrarum.serialise.WriteLayerDataZip.FILE_FOOTER
import net.torvald.terrarum.serialise.WriteLayerDataZip.PAYLOAD_FOOTER
import net.torvald.terrarum.toHex
import java.nio.charset.Charset
import java.util.*
/**
* Created by minjaesong on 2019-02-20.
*/
object PayloadUtil {
/**
* InputStream must be located manually at the payload begin
*
* For the actual use case, take a look at the source of the [ReadLayerDataZip].
*/
fun readAll(inputStream: MarkableFileInputStream, footer: ByteArray = FILE_FOOTER): HashMap<String, TEMzPayload> {
val pldBuffer4 = ByteArray(4)
val pldBuffer6 = ByteArray(6)
val pldBuffer8 = ByteArray(8)
val payloads = HashMap<String, TEMzPayload>()
var pldCnt = 1
while (true) {
// read header and get payload's name
inputStream.read(pldBuffer8)
// check if end of payload reached
if (pldBuffer8.contentEquals(footer)) {
break
}
val payloadName = pldBuffer8.copyOfRange(4, 8).toString(Charset.forName("US-ASCII"))
AppLoader.printdbg(this, "Payload $pldCnt name: $payloadName") // maybe maybe related with buffer things?
// get uncompressed size
inputStream.read(pldBuffer6)
val uncompressedSize = pldBuffer6.toLittleInt48()
// get deflated size
inputStream.mark(2147483647) // FIXME deflated stream cannot be larger than 2 GB
// creep forward until we hit the PAYLOAD_FOOTER
var compressedSize: Int = 0 // FIXME deflated stream cannot be larger than 2 GB
// loop init
inputStream.read(pldBuffer8)
// loop main
while (!pldBuffer8.contentEquals(PAYLOAD_FOOTER)) {
val aByte = inputStream.read(); compressedSize += 1
if (aByte == -1) throw InternalError("Unexpected end-of-file at payload $pldCnt")
pldBuffer8.shiftLeftBy(1, aByte.toByte())
}
// at this point, we should have correct size of deflated bytestream
AppLoader.printdbg(this, "Payload $pldCnt compressed size: $compressedSize")
val compressedBytes = ByteArray(compressedSize) // FIXME deflated stream cannot be larger than 2 GB
inputStream.reset() // go back to marked spot
inputStream.read(compressedBytes)
// PRO Debug tip: every deflated bytes must begin with 0x789C or 0x78DA
// Thus, \0pLd + [10] must be either of these.
// put constructed payload into a container
payloads.put(payloadName, TEMzPayload(uncompressedSize, compressedBytes))
// skip over to be aligned with the next payload
inputStream.skip(8)
pldCnt += 1
}
return payloads
}
private fun ByteArray.shiftLeftBy(size: Int, fill: Byte = 0.toByte()) {
if (size == 0) {
return
}
else if (size < 0) {
throw IllegalArgumentException("This won't shift to right (size = $size)")
}
else if (size >= this.size) {
Arrays.fill(this, 0.toByte())
}
else {
for (c in size..this.lastIndex) {
this[c - size] = this[c]
}
for (c in (this.size - size)..this.lastIndex) {
this[c] = fill
}
}
}
private fun ByteArray.toByteString(): String {
val sb = StringBuilder()
this.forEach {
sb.append(it.toUint().toHex().takeLast(2))
sb.append(' ')
}
sb.deleteCharAt(sb.lastIndex)
return sb.toString()
}
data class TEMzPayload(val uncompressedSize: Long, val bytes: ByteArray) // FIXME deflated stream cannot be larger than 2 GB
}

View File

@@ -8,9 +8,7 @@ import net.torvald.terrarum.gameworld.MapLayer
import net.torvald.terrarum.gameworld.PairedMapLayer
import net.torvald.terrarum.modulecomputers.virtualcomputer.tvd.DiskSkimmer.Companion.read
import net.torvald.terrarum.realestate.LandUtil
import net.torvald.terrarum.toHex
import java.io.*
import java.nio.charset.Charset
import java.util.*
import kotlin.collections.HashMap
@@ -60,7 +58,8 @@ internal object ReadLayerDataLzma {
// read payloads
val pldBuffer4 = ByteArray(4)
val payloads = PayloadUtil.readAll(inputStream)
/*val pldBuffer4 = ByteArray(4)
val pldBuffer6 = ByteArray(6)
val pldBuffer8 = ByteArray(8)
@@ -121,7 +120,7 @@ internal object ReadLayerDataLzma {
// test for EOF
inputStream.read(pldBuffer8)
if (!pldBuffer8.contentEquals(WriteLayerDataZip.FILE_FOOTER))
throw InternalError("Expected end-of-file, got not-so-end-of-file")
throw InternalError("Expected end-of-file, got not-so-end-of-file")*/
//////////////////////
@@ -199,8 +198,6 @@ internal object ReadLayerDataLzma {
)
}
private data class TEMzPayload(val uncompressedSize: Long, val bytes: ByteArray) // FIXME deflated stream cannot be larger than 2 GB
/**
* Immediately deployable, a part of the gameworld
*/
@@ -221,27 +218,6 @@ internal object ReadLayerDataLzma {
val fluidFills: HashMap<BlockAddress, Float>
)
private fun ByteArray.shiftLeftBy(size: Int, fill: Byte = 0.toByte()) {
if (size == 0) {
return
}
else if (size < 0) {
throw IllegalArgumentException("This won't shift to right (size = $size)")
}
else if (size >= this.size) {
Arrays.fill(this, 0.toByte())
}
else {
for (c in size..this.lastIndex) {
this[c - size] = this[c]
}
for (c in (this.size - size)..this.lastIndex) {
this[c] = fill
}
}
}
internal fun InputStream.readRelative(b: ByteArray, off: Int, len: Int): Int {
if (b == null) {
throw NullPointerException()
@@ -272,14 +248,4 @@ internal object ReadLayerDataLzma {
return i
}
fun ByteArray.toByteString(): String {
val sb = StringBuilder()
this.forEach {
sb.append(it.toUint().toHex().takeLast(2))
sb.append(' ')
}
sb.deleteCharAt(sb.lastIndex)
return sb.toString()
}
}

View File

@@ -6,12 +6,10 @@ import net.torvald.terrarum.gameworld.MapLayer
import net.torvald.terrarum.gameworld.PairedMapLayer
import net.torvald.terrarum.modulecomputers.virtualcomputer.tvd.DiskSkimmer.Companion.read
import net.torvald.terrarum.realestate.LandUtil
import net.torvald.terrarum.toHex
import java.io.File
import java.io.FileInputStream
import java.io.IOException
import java.io.InputStream
import java.nio.charset.Charset
import java.util.*
import java.util.zip.Inflater
import kotlin.collections.HashMap
@@ -62,7 +60,8 @@ internal object ReadLayerDataZip {
// read payloads
val pldBuffer4 = ByteArray(4)
val payloads = PayloadUtil.readAll(inputStream)
/*val pldBuffer4 = ByteArray(4)
val pldBuffer6 = ByteArray(6)
val pldBuffer8 = ByteArray(8)
@@ -123,7 +122,7 @@ internal object ReadLayerDataZip {
// test for EOF
inputStream.read(pldBuffer8)
if (!pldBuffer8.contentEquals(WriteLayerDataZip.FILE_FOOTER))
throw InternalError("Expected end-of-file, got not-so-end-of-file")
throw InternalError("Expected end-of-file, got not-so-end-of-file")*/
//////////////////////
@@ -194,8 +193,6 @@ internal object ReadLayerDataZip {
)
}
private data class TEMzPayload(val uncompressedSize: Long, val bytes: ByteArray) // FIXME deflated stream cannot be larger than 2 GB
/**
* Immediately deployable, a part of the gameworld
*/
@@ -214,27 +211,6 @@ internal object ReadLayerDataZip {
val terrainDamages: HashMap<BlockAddress, Float>
)
private fun ByteArray.shiftLeftBy(size: Int, fill: Byte = 0.toByte()) {
if (size == 0) {
return
}
else if (size < 0) {
throw IllegalArgumentException("This won't shift to right (size = $size)")
}
else if (size >= this.size) {
Arrays.fill(this, 0.toByte())
}
else {
for (c in size..this.lastIndex) {
this[c - size] = this[c]
}
for (c in (this.size - size)..this.lastIndex) {
this[c] = fill
}
}
}
internal fun InputStream.readRelative(b: ByteArray, off: Int, len: Int): Int {
if (b == null) {
throw NullPointerException()
@@ -265,14 +241,4 @@ internal object ReadLayerDataZip {
return i
}
fun ByteArray.toByteString(): String {
val sb = StringBuilder()
this.forEach {
sb.append(it.toUint().toHex().takeLast(2))
sb.append(' ')
}
sb.deleteCharAt(sb.lastIndex)
return sb.toString()
}
}
}

View File

@@ -4,6 +4,9 @@ import com.badlogic.gdx.utils.compression.Lzma
import net.torvald.terrarum.AppLoader
import net.torvald.terrarum.Terrarum
import net.torvald.terrarum.realestate.LandUtil
import net.torvald.terrarum.serialise.WriteLayerDataZip.FILE_FOOTER
import net.torvald.terrarum.serialise.WriteLayerDataZip.PAYLOAD_FOOTER
import net.torvald.terrarum.serialise.WriteLayerDataZip.PAYLOAD_HEADER
import java.io.*
import java.util.zip.DeflaterOutputStream
@@ -35,9 +38,6 @@ internal object WriteLayerDataLzma {
val NUMBER_OF_PAYLOADS = 5.toByte()
val COMPRESSION_ALGORITHM = 2.toByte()
val GENERATOR_VERSION = WORLD_GENERATOR_VERSION.toULittleShort()
val PAYLOAD_HEADER = byteArrayOf(0, 0x70, 0x4C, 0x64)
val PAYLOAD_FOOTER = byteArrayOf(0x45, 0x6E, 0x64, 0x50, 0x59, 0x4C, 0x64, -1)
val FILE_FOOTER = byteArrayOf(0x45, 0x6E, 0x64, 0x54, 0x45, 0x4D, -1, -2)
//val NULL: Byte = 0

View File

@@ -40,9 +40,9 @@ internal object WriteLayerDataZip {
val NUMBER_OF_PAYLOADS = 5.toByte()
val COMPRESSION_ALGORITHM = 1.toByte()
val GENERATOR_VERSION = WORLD_GENERATOR_VERSION.toULittleShort()
val PAYLOAD_HEADER = byteArrayOf(0, 0x70, 0x4C, 0x64)
val PAYLOAD_FOOTER = byteArrayOf(0x45, 0x6E, 0x64, 0x50, 0x59, 0x4C, 0x64, -1)
val FILE_FOOTER = byteArrayOf(0x45, 0x6E, 0x64, 0x54, 0x45, 0x4D, -1, -2)
val PAYLOAD_HEADER = byteArrayOf(0, 0x70, 0x4C, 0x64) // \0pLd
val PAYLOAD_FOOTER = byteArrayOf(0x45, 0x6E, 0x64, 0x50, 0x59, 0x4C, 0x64, -1) // EndPYLd\xFF
val FILE_FOOTER = byteArrayOf(0x45, 0x6E, 0x64, 0x54, 0x45, 0x4D, -1, -2) // EndTEM with BOM
//val NULL: Byte = 0