Skip to content

Instantly share code, notes, and snippets.

@swankjesse
Created February 7, 2021 16:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save swankjesse/bc8cd35263aeaf8ade089de38e2256e7 to your computer and use it in GitHub Desktop.
Save swankjesse/bc8cd35263aeaf8ade089de38e2256e7 to your computer and use it in GitHub Desktop.
/*
* Copyright (C) 2021 Square, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package okio
import java.util.zip.InflaterInputStream
import okio.Path.Companion.toPath
@ExperimentalFileSystem
class ZipFileSystemSketch private constructor(
private val fileSystem: FileSystem,
private val zipPath: Path,
private val entries: List<Entry>
) : FileSystem() {
override fun canonicalize(path: Path): Path {
return "/".toPath() / path
}
override fun metadataOrNull(path: Path): FileMetadata? {
val canonicalPath = canonicalize(path)
return entries.firstOrNull { it.path == canonicalPath }?.metadata
}
override fun list(dir: Path): List<Path> {
val canonicalDir = canonicalize(dir)
return entries.mapNotNull { if (it.path.parent == canonicalDir) it.path else null }
}
override fun source(file: Path): Source {
val canonicalPath = canonicalize(file)
val entry = entries.firstOrNull { it.path == canonicalPath }
?: throw FileNotFoundException("no such file: $file")
val zipSource = fileSystem.source(zipPath)
val cursor = zipSource.cursor ?: throw IOException("zip file not random access")
cursor.seek(entry.offset)
// TODO(jwilson): there's some framing needed here.
return InflaterInputStream(zipSource.buffer().inputStream()).source()
}
override fun sink(file: Path): Sink = throw IOException("zip file systems are read-only")
override fun appendingSink(file: Path): Sink =
throw IOException("zip file systems are read-only")
override fun createDirectory(dir: Path): Unit =
throw IOException("zip file systems are read-only")
override fun atomicMove(source: Path, target: Path): Unit =
throw IOException("zip file systems are read-only")
override fun delete(path: Path): Unit = throw IOException("zip file systems are read-only")
private class Entry(
val path: Path,
val metadata: FileMetadata,
val offset: Long
)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment