Open-source multiplayer game server compatible with the RuneScape client
https://www.openrs2.org/
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
72 lines
1.8 KiB
72 lines
1.8 KiB
package org.openrs2.compress.gzip
|
|
|
|
import com.google.common.io.LittleEndianDataOutputStream
|
|
import java.io.DataOutputStream
|
|
import java.io.OutputStream
|
|
import java.util.zip.CRC32
|
|
import java.util.zip.Deflater
|
|
|
|
public class JagexGzipOutputStream(
|
|
private val output: OutputStream
|
|
) : OutputStream() {
|
|
private val deflater = Deflater(Deflater.DEFAULT_COMPRESSION, true)
|
|
private val buffer = ByteArray(4096)
|
|
private val checksum = CRC32()
|
|
private var closed = false
|
|
|
|
init {
|
|
val dataOutput = DataOutputStream(output)
|
|
dataOutput.writeShort(HEADER_MAGIC)
|
|
dataOutput.writeByte(METHOD_DEFLATE)
|
|
dataOutput.writeByte(0) // FLG
|
|
dataOutput.writeInt(0) // MTIME
|
|
dataOutput.writeByte(0) // XFL
|
|
dataOutput.writeByte(0) // OS
|
|
}
|
|
|
|
override fun write(b: Int) {
|
|
buffer[0] = b.toByte()
|
|
write(buffer, 0, 1)
|
|
}
|
|
|
|
override fun write(b: ByteArray, off: Int, len: Int) {
|
|
checksum.update(b, off, len)
|
|
deflater.setInput(b, off, len)
|
|
|
|
while (!deflater.needsInput()) {
|
|
drain()
|
|
}
|
|
}
|
|
|
|
private fun drain() {
|
|
val n = deflater.deflate(buffer)
|
|
if (n != 0) {
|
|
output.write(buffer, 0, n)
|
|
}
|
|
}
|
|
|
|
override fun close() {
|
|
if (!closed) {
|
|
deflater.finish()
|
|
|
|
while (!deflater.finished()) {
|
|
drain()
|
|
}
|
|
|
|
val dataOutput = LittleEndianDataOutputStream(output)
|
|
dataOutput.writeInt(checksum.value.toInt())
|
|
dataOutput.writeInt(deflater.totalIn)
|
|
|
|
deflater.end()
|
|
output.close()
|
|
|
|
closed = true
|
|
}
|
|
}
|
|
|
|
private companion object {
|
|
private const val HEADER_MAGIC = 0x1F8B
|
|
|
|
private const val METHOD_DEFLATE = 8
|
|
}
|
|
}
|
|
|