Add FlatFileStoreZipWriter

Signed-off-by: Graham <gpe@openrs2.org>
pull/132/head
Graham 3 years ago
parent e0a2df889b
commit 6aea0cfc8e
  1. 91
      cache/src/main/kotlin/org/openrs2/cache/FlatFileStoreZipWriter.kt
  2. 2
      cache/src/test/kotlin/org/openrs2/cache/DiskStoreZipWriterTest.kt
  3. 125
      cache/src/test/kotlin/org/openrs2/cache/FlatFileStoreZipWriterTest.kt
  4. 0
      cache/src/test/resources/org/openrs2/cache/disk-store-zip/cache.zip
  5. BIN
      cache/src/test/resources/org/openrs2/cache/flat-file-store-zip/cache.zip

@ -0,0 +1,91 @@
package org.openrs2.cache
import io.netty.buffer.ByteBuf
import java.nio.file.attribute.FileTime
import java.time.Instant
import java.util.zip.Deflater
import java.util.zip.ZipEntry
import java.util.zip.ZipOutputStream
/**
* A specialised [Store] implementation that writes a cache in the
* [FlatFileStore] format to a [ZipOutputStream].
*
* The cache is not buffered to disk.
*
* This implementation only supports the [create] and [write] methods. All
* other methods throw [UnsupportedOperationException].
*
* It is only intended for use by the cache archiving service's web interface.
*/
public class FlatFileStoreZipWriter(
private val out: ZipOutputStream,
private val prefix: String = "cache/",
level: Int = Deflater.BEST_COMPRESSION,
timestamp: Instant = Instant.EPOCH
) : Store {
private val timestamp = FileTime.from(timestamp)
init {
out.setLevel(level)
}
private fun createZipEntry(name: String): ZipEntry {
val entry = ZipEntry(prefix + name)
entry.creationTime = timestamp
entry.lastAccessTime = timestamp
entry.lastModifiedTime = timestamp
return entry
}
override fun exists(archive: Int): Boolean {
throw UnsupportedOperationException()
}
override fun exists(archive: Int, group: Int): Boolean {
throw UnsupportedOperationException()
}
override fun list(): List<Int> {
throw UnsupportedOperationException()
}
override fun list(archive: Int): List<Int> {
throw UnsupportedOperationException()
}
override fun create(archive: Int) {
require(archive in 0..Store.MAX_ARCHIVE)
out.putNextEntry(createZipEntry("$archive/"))
}
override fun read(archive: Int, group: Int): ByteBuf {
throw UnsupportedOperationException()
}
override fun write(archive: Int, group: Int, buf: ByteBuf) {
require(archive in 0..Store.MAX_ARCHIVE)
require(group >= 0)
require(buf.readableBytes() <= Store.MAX_GROUP_SIZE)
out.putNextEntry(createZipEntry("$archive/$group.dat"))
buf.readBytes(out, buf.readableBytes())
}
override fun remove(archive: Int) {
throw UnsupportedOperationException()
}
override fun remove(archive: Int, group: Int) {
throw UnsupportedOperationException()
}
override fun flush() {
out.flush()
}
override fun close() {
out.close()
}
}

@ -118,6 +118,6 @@ class DiskStoreZipWriterTest {
}
private companion object {
private val ROOT = Path.of(DiskStoreZipWriterTest::class.java.getResource("zip").toURI())
private val ROOT = Path.of(DiskStoreZipWriterTest::class.java.getResource("disk-store-zip").toURI())
}
}

@ -0,0 +1,125 @@
package org.openrs2.cache
import com.google.common.jimfs.Configuration
import com.google.common.jimfs.Jimfs
import io.netty.buffer.Unpooled
import org.openrs2.buffer.copiedBuffer
import org.openrs2.buffer.use
import org.openrs2.util.io.recursiveEquals
import java.io.OutputStream
import java.nio.file.Files
import java.nio.file.Path
import java.util.zip.ZipOutputStream
import kotlin.test.Test
import kotlin.test.assertFailsWith
import kotlin.test.assertTrue
public class FlatFileStoreZipWriterTest {
@Test
fun testBounds() {
FlatFileStoreZipWriter(ZipOutputStream(OutputStream.nullOutputStream())).use { store ->
// create
assertFailsWith<IllegalArgumentException> {
store.create(-1)
}
store.create(0)
store.create(1)
store.create(254)
store.create(255)
assertFailsWith<IllegalArgumentException> {
store.create(256)
}
// write archive
assertFailsWith<IllegalArgumentException> {
store.write(-1, 0, Unpooled.EMPTY_BUFFER)
}
store.write(0, 0, Unpooled.EMPTY_BUFFER)
store.write(1, 0, Unpooled.EMPTY_BUFFER)
store.write(254, 0, Unpooled.EMPTY_BUFFER)
store.write(255, 0, Unpooled.EMPTY_BUFFER)
assertFailsWith<IllegalArgumentException> {
store.write(256, 0, Unpooled.EMPTY_BUFFER)
}
// write group
assertFailsWith<IllegalArgumentException> {
store.write(0, -1, Unpooled.EMPTY_BUFFER)
}
store.write(2, 0, Unpooled.EMPTY_BUFFER)
store.write(2, 1, Unpooled.EMPTY_BUFFER)
}
}
@Test
fun testUnsupported() {
FlatFileStoreZipWriter(ZipOutputStream(OutputStream.nullOutputStream())).use { store ->
assertFailsWith<UnsupportedOperationException> {
store.exists(0)
}
assertFailsWith<UnsupportedOperationException> {
store.exists(0, 0)
}
assertFailsWith<UnsupportedOperationException> {
store.list()
}
assertFailsWith<UnsupportedOperationException> {
store.list(0)
}
assertFailsWith<UnsupportedOperationException> {
store.read(0, 0)
}
assertFailsWith<UnsupportedOperationException> {
store.remove(0)
}
assertFailsWith<UnsupportedOperationException> {
store.remove(0, 0)
}
}
}
@Test
fun testWrite() {
Jimfs.newFileSystem(Configuration.forCurrentPlatform()).use { fs ->
val actual = fs.rootDirectories.first().resolve("zip")
Files.createDirectories(actual)
Files.newOutputStream(actual.resolve("cache.zip")).use { out ->
FlatFileStoreZipWriter(ZipOutputStream(out)).use { store ->
store.create(0)
copiedBuffer("OpenRS2").use { buf ->
store.write(2, 0, buf)
}
copiedBuffer("OpenRS2".repeat(100)).use { buf ->
store.write(2, 65535, buf)
}
copiedBuffer("OpenRS2".repeat(100)).use { buf ->
store.write(2, 65536, buf)
}
}
}
assertTrue(ROOT.recursiveEquals(actual))
}
}
private companion object {
private val ROOT = Path.of(
FlatFileStoreZipWriterTest::class.java.getResource("flat-file-store-zip").toURI()
)
}
}
Loading…
Cancel
Save