blob: d03561b67a792625355ca1f4dbe19e75155e3fd5 [file] [log] [blame] [raw]
package li.cil.oc.server.fs
import dan200.computer.api.{IWritableMount, IMount}
import java.io
import java.util.zip.ZipFile
import li.cil.oc.api.fs.Label
import li.cil.oc.server.component
import li.cil.oc.{Config, api}
import net.minecraftforge.common.DimensionManager
object FileSystem extends api.detail.FileSystemAPI {
override def fromClass(clazz: Class[_], domain: String, root: String): api.fs.FileSystem = {
val codeSource = clazz.getProtectionDomain.getCodeSource
if (codeSource == null) return null
val file = new io.File(codeSource.getLocation.toURI)
if (!file.exists || file.isDirectory) return null
val path = ("/assets/" + domain + "/" + (root.trim + "/")).replace("//", "/")
if (file.getName.endsWith(".class"))
new io.File(new io.File(file.getParent), path) match {
case fsp if fsp.exists() && fsp.isDirectory =>
new ReadOnlyFileSystem(fsp)
case _ =>
System.getProperty("java.class.path").split(System.getProperty("path.separator")).
find(cp => {
val fsp = new io.File(new io.File(cp), path)
fsp.exists() && fsp.isDirectory
}) match {
case None => null
case Some(dir) => new ReadOnlyFileSystem(new io.File(new io.File(dir), path))
}
}
else {
val zip = new ZipFile(file)
val entry = zip.getEntry(path)
if (entry == null || !entry.isDirectory) {
zip.close()
return null
}
new ZipFileInputStreamFileSystem(zip, path)
}
}
override def fromSaveDirectory(root: String, capacity: Long, buffered: Boolean) = {
val path = new io.File(DimensionManager.getCurrentSaveRootDirectory, Config.savePath + root)
path.mkdirs()
if (path.exists() && path.isDirectory) {
if (buffered)
new BufferedFileSystem(path, capacity)
else
new ReadWriteFileSystem(path, capacity)
}
else null
}
def fromMemory(capacity: Long): api.fs.FileSystem = new RamFileSystem(capacity)
def fromComputerCraft(mount: IMount) = new ComputerCraftFileSystem(mount)
def fromComputerCraft(mount: IWritableMount) = new ComputerCraftWritableFileSystem(mount)
def asManagedEnvironment(fileSystem: api.fs.FileSystem, label: Label) =
Option(fileSystem).flatMap(fs => Some(new component.FileSystem(fs, label))).orNull
def asManagedEnvironment(fileSystem: api.fs.FileSystem, label: String) =
asManagedEnvironment(fileSystem, new ReadOnlyLabel(label))
def asManagedEnvironment(fileSystem: api.fs.FileSystem) =
asManagedEnvironment(fileSystem, null: Label)
private class ReadOnlyLabel(val label: String) extends Label {
def setLabel(value: String) = throw new Exception("label is read only")
def getLabel = label
}
private class ReadOnlyFileSystem(protected val root: io.File)
extends InputStreamFileSystem
with FileInputStreamFileSystem
private class ReadWriteFileSystem(protected val root: io.File, protected val capacity: Long)
extends OutputStreamFileSystem
with FileOutputStreamFileSystem
with Capacity
private class RamFileSystem(protected val capacity: Long)
extends VirtualFileSystem
with Capacity
with Volatile
private class BufferedFileSystem(protected val fileRoot: io.File, protected val capacity: Long)
extends VirtualFileSystem
with Capacity
with Buffered
}