Add headerless bzip2 and gzip library

Signed-off-by: Graham <gpe@openrs2.dev>
Graham 5 years ago
parent a52d58e8b5
commit 892d21df10
  1. 2
      asm/build.gradle.kts
  2. 16
      asm/src/main/java/dev/openrs2/asm/classpath/Library.kt
  3. 1
      buildSrc/src/main/java/Versions.kt
  4. 25
      compress/build.gradle.kts
  5. 22
      compress/src/main/java/dev/openrs2/compress/bzip2/Bzip2.kt
  6. 21
      compress/src/main/java/dev/openrs2/compress/gzip/Gzip.kt
  7. 10
      compress/src/main/java/dev/openrs2/compress/gzip/GzipLevelOutputStream.kt
  8. 1
      settings.gradle.kts

@ -9,6 +9,8 @@ dependencies {
api("org.ow2.asm:asm-commons:${Versions.asm}")
api("org.ow2.asm:asm-tree:${Versions.asm}")
api("org.ow2.asm:asm-util:${Versions.asm}")
implementation(project(":compress"))
}
publishing {

@ -5,14 +5,12 @@ import dev.openrs2.asm.NopClassVisitor
import dev.openrs2.asm.remap
import dev.openrs2.common.crypto.Pkcs12KeyStore
import dev.openrs2.common.io.DeterministicJarOutputStream
import dev.openrs2.common.io.SkipOutputStream
import dev.openrs2.compress.gzip.Gzip
import org.objectweb.asm.ClassReader
import org.objectweb.asm.commons.Remapper
import org.objectweb.asm.tree.ClassNode
import org.objectweb.asm.util.CheckClassAdapter
import java.io.ByteArrayInputStream
import java.io.OutputStream
import java.io.SequenceInputStream
import java.nio.file.Files
import java.nio.file.Path
import java.util.TreeMap
@ -21,8 +19,6 @@ import java.util.jar.JarInputStream
import java.util.jar.JarOutputStream
import java.util.jar.Manifest
import java.util.jar.Pack200
import java.util.zip.GZIPInputStream
import java.util.zip.GZIPOutputStream
class Library constructor() : Iterable<ClassNode> {
private var classes = TreeMap<String, ClassNode>()
@ -120,9 +116,7 @@ class Library constructor() : Iterable<ClassNode> {
writeJar(classPath, temp)
JarInputStream(Files.newInputStream(temp)).use { `in` ->
val headerSize = GZIP_HEADER.size.toLong()
GZIPOutputStream(SkipOutputStream(out, headerSize)).use { gzip ->
Gzip.createHeaderlessOutputStream(out).use { gzip ->
Pack200.newPacker().pack(`in`, gzip)
}
}
@ -140,7 +134,6 @@ class Library constructor() : Iterable<ClassNode> {
private const val CLASS_SUFFIX = ".class"
private const val TEMP_PREFIX = "tmp"
private const val JAR_SUFFIX = ".jar"
private val GZIP_HEADER = byteArrayOf(0x1F, 0x8B.toByte())
fun readJar(path: Path): Library {
logger.info { "Reading jar $path" }
@ -170,10 +163,7 @@ class Library constructor() : Iterable<ClassNode> {
val temp = Files.createTempFile(TEMP_PREFIX, JAR_SUFFIX)
try {
val header = ByteArrayInputStream(GZIP_HEADER)
val data = Files.newInputStream(path)
GZIPInputStream(SequenceInputStream(header, data)).use { `in` ->
Gzip.createHeaderlessInputStream(Files.newInputStream(path)).use { `in` ->
JarOutputStream(Files.newOutputStream(temp)).use { out ->
Pack200.newUnpacker().unpack(`in`, out)
}

@ -2,6 +2,7 @@ object Versions {
const val asm = "8.0"
const val bouncyCastle = "1.64"
const val clikt = "2.6.0"
const val commonsCompress = "1.20"
const val dependencyLicenseReport = "1.13"
const val fernflower = "1.0.3"
const val guava = "28.2-jre"

@ -0,0 +1,25 @@
plugins {
`maven-publish`
kotlin("jvm")
}
dependencies {
implementation(project(":common"))
implementation("org.apache.commons:commons-compress:${Versions.commonsCompress}")
}
publishing {
publications.create<MavenPublication>("maven") {
from(components["java"])
pom {
packaging = "jar"
name.set("OpenRS2 Compression")
description.set(
"""
Provides headerless implementations of bzip2 and gzip.
""".trimIndent()
)
}
}
}

@ -0,0 +1,22 @@
package dev.openrs2.compress.bzip2
import dev.openrs2.common.io.SkipOutputStream
import org.apache.commons.compress.compressors.bzip2.BZip2CompressorInputStream
import org.apache.commons.compress.compressors.bzip2.BZip2CompressorOutputStream
import java.io.ByteArrayInputStream
import java.io.InputStream
import java.io.OutputStream
import java.io.SequenceInputStream
object Bzip2 {
private const val BLOCK_SIZE = 1
private val HEADER = byteArrayOf('B'.toByte(), 'Z'.toByte(), 'h'.toByte(), ('0' + BLOCK_SIZE).toByte())
fun createHeaderlessInputStream(input: InputStream): InputStream {
return BZip2CompressorInputStream(SequenceInputStream(ByteArrayInputStream(HEADER), input))
}
fun createHeaderlessOutputStream(output: OutputStream): OutputStream {
return BZip2CompressorOutputStream(SkipOutputStream(output, HEADER.size.toLong()), BLOCK_SIZE)
}
}

@ -0,0 +1,21 @@
package dev.openrs2.compress.gzip
import dev.openrs2.common.io.SkipOutputStream
import java.io.ByteArrayInputStream
import java.io.InputStream
import java.io.OutputStream
import java.io.SequenceInputStream
import java.util.zip.Deflater
import java.util.zip.GZIPInputStream
object Gzip {
private val HEADER = byteArrayOf(0x1F, 0x8B.toByte())
fun createHeaderlessInputStream(input: InputStream): InputStream {
return GZIPInputStream(SequenceInputStream(ByteArrayInputStream(HEADER), input))
}
fun createHeaderlessOutputStream(output: OutputStream, level: Int = Deflater.BEST_COMPRESSION): OutputStream {
return GzipLevelOutputStream(SkipOutputStream(output, HEADER.size.toLong()), level)
}
}

@ -0,0 +1,10 @@
package dev.openrs2.compress.gzip
import java.io.OutputStream
import java.util.zip.GZIPOutputStream
class GzipLevelOutputStream(output: OutputStream, level: Int) : GZIPOutputStream(output) {
init {
def.setLevel(level)
}
}

@ -7,6 +7,7 @@ include(
"asm",
"bundler",
"common",
"compress",
"decompiler",
"deob",
"deob-annotations",

Loading…
Cancel
Save