mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-06-14 20:44:05 +09:00
payloadutil and unhelpful commit message
This commit is contained in:
114
src/net/torvald/terrarum/serialise/PayloadUtil.kt
Normal file
114
src/net/torvald/terrarum/serialise/PayloadUtil.kt
Normal 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
|
||||
|
||||
}
|
||||
@@ -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()
|
||||
}
|
||||
}
|
||||
@@ -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()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user