Skip to main content Skip to docs navigation

Compression

Compression (zlib, deflate, lzma, zip) and checksum tools (adler32, crc32)

Document not reviewed yet, might be outdated. Please, let us know if you find something invalid here.
On this page

KorIO has some compression and checksum tools.

Checksum

fun SimpleChecksum.compute(data: ByteArray, offset: Int = 0, len: Int = data.size - offset): Int
fun ByteArray.checksum(checksum: SimpleChecksum): Int

fun SyncInputStream.checksum(checksum: SimpleChecksum): Int
suspend fun AsyncInputStream.checksum(checksum: SimpleChecksum): Int
suspend fun AsyncInputOpenable.checksum(checksum: SimpleChecksum): Int

interface SimpleChecksum {
	val initialValue: Int
	fun update(old: Int, data: ByteArray, offset: Int = 0, len: Int = data.size - offset): Int
}

Standard (Adler32, CRC32)

com.soywiz.korio.util.checksum.Adler32
com.soywiz.korio.util.checksum.CRC32

Compression

Korio includes Deflate, GZIP, ZLib and LZMA compressions out of the box working on all the targets.

It defines a CompressionMethod interface:

// Asynchronous API
interface CompressionMethod {
    suspend fun uncompress(reader: BitReader, out: AsyncOutputStream): Unit
    suspend fun compress(i: BitReader, o: AsyncOutputStream, context: CompressionContext): Unit
}

// Synchronous API
fun CompressionMethod.uncompress(i: SyncInputStream, o: SyncOutputStream)
fun CompressionMethod.compress(i: SyncInputStream, o: SyncOutputStream, context: CompressionContext)

It also provides several extension methods for compressing/decompressing data:

fun ByteArray.uncompress(method: CompressionMethod, outputSizeHint: Int): ByteArray
fun ByteArray.compress(method: CompressionMethod, context: CompressionContext, outputSizeHint: Int): ByteArray

suspend fun AsyncInputStreamWithLength.uncompressed(method: CompressionMethod): AsyncInputStream
suspend fun AsyncInputStreamWithLength.compressed(method: CompressionMethod, context: CompressionContext): AsyncInputStream

Standard (Deflate, GZIP, ZLib and LZMA)

And the CompressionMethod singletons/classes:

com.soywiz.korio.compression.deflate.Deflate
com.soywiz.korio.compression.deflate.GZIP
com.soywiz.korio.compression.deflate.GZIPNoCrc
com.soywiz.korio.compression.deflate.ZLib
com.soywiz.korio.compression.lzma.Lzma

Zip

ZipFile

class ZipFile {
    val s: AsyncStream,
    val caseSensitive: Boolean = true
    val files = LinkedHashMap<String, ZipEntry2>()
    val filesPerFolder = LinkedHashMap<String, MutableMap<String, ZipEntry2>>()

    companion object {
        suspend operator fun invoke(s: AsyncStream, caseSensitive: Boolean = true): ZipFile
    }

    fun normalizeName(name: String) = if (caseSensitive) name.trim('/') else name.trim('/').toLowerCase()
}

data class DosFileDateTime(var dosTime: Int, var dosDate: Int) {
    val seconds: Int
    val minutes: Int
    val hours: Int
    val day: Int
    val month1: Int
    val fullYear: Int
    val utc: DateTime
}

data class ZipEntry(
    val versionMadeBy: Int,
    val extractVersion: Int,
    val headerOffset: Long,
    val compressionMethod: Int,
    val flags: Int,
    val date: Int,
    val time: Int,
    val crc32: Int,
    val compressedSize: Int,
    val uncompressedSize: Int,
    val nameBytes: ByteArray,
    val extraBytes: ByteArray,
    val diskNumberStart: Int,
    val internalAttributes: Int,
    val externalAttributes: Int,
    val commentBytes: ByteArray
)

data class ZipEntry2(
    val path: String,
    val compressionMethod: Int,
    val isDirectory: Boolean,
    val time: DosFileDateTime,
    val offset: Int,
    val inode: Long,
    val headerEntry: AsyncStream,
    val compressedSize: Long,
    val uncompressedSize: Long
)

ZipVfs

There is a ZipVfs (check the File System for more details).

suspend fun VfsFile.openAsZip(caseSensitive: Boolean = true, useNativeDecompression: Boolean = true): VfsFile
suspend fun AsyncStream.openAsZip(caseSensitive: Boolean = true, useNativeDecompression: Boolean = true): VfsFile
suspend fun <R> VfsFile.openAsZip(caseSensitive: Boolean = true, useNativeDecompression: Boolean = true, callback: suspend (VfsFile) -> R): R
suspend fun <R> AsyncStream.openAsZip(caseSensitive: Boolean = true, useNativeDecompression: Boolean = true, callback: suspend (VfsFile) -> R): R

ZipBuilder

object ZipBuilder {
	suspend fun createZipFromTree(file: VfsFile): ByteArray
	suspend fun createZipFromTreeTo(file: VfsFile, s: AsyncStream)
	suspend fun addZipFileEntry(s: AsyncStream, entry: VfsFile): ZipEntry
	suspend fun addZipFileEntryTree(s: AsyncStream, entry: VfsFile, entries: MutableList<ZipEntry>)
	suspend fun addDirEntry(s: AsyncStream, e: ZipEntry)
}

Creating a .zip file from a VfsFile

suspend fun VfsFile.createZipFromTree(): ByteArray
suspend fun VfsFile.createZipFromTreeTo(s: AsyncStream)
Was this article useful?