0.1.1-SNAPSHOT: storages, sync tools, docs
This commit is contained in:
1 parent
3e6c487601
commit
babc3933eb
24 files changed
+925
-52
No files matched your search
@@ -0,0 +1,47 @@
|
||||
package net.sergeych.bintools
|
||||
|
||||
import java.io.InputStream
|
||||
import java.io.OutputStream
|
||||
import java.nio.file.Path
|
||||
import kotlin.io.path.*
|
||||
|
||||
class FileDataProvider(val folder: Path): DataProvider {
|
||||
|
||||
class Source(private val input: InputStream): DataSource {
|
||||
override fun readByte(): Byte {
|
||||
val b = input.read()
|
||||
if( b < 0) throw DataSource.EndOfData()
|
||||
return b.toByte()
|
||||
}
|
||||
|
||||
override fun readBytes(size: Int): ByteArray {
|
||||
return input.readNBytes(size).also {
|
||||
if( it.size < size ) throw DataSource.EndOfData()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class Sink(private val out: OutputStream): DataSink {
|
||||
override fun writeByte(data: Byte) {
|
||||
out.write(data.toInt())
|
||||
}
|
||||
}
|
||||
|
||||
override fun <T> read(name: String, f: (DataSource) -> T): T = folder.resolve(name).inputStream().buffered().use {
|
||||
f(Source(it))
|
||||
}
|
||||
|
||||
override fun write(name: String, f: (DataSink) -> Unit) {
|
||||
folder.resolve(name).outputStream().use { f(Sink(it)) }
|
||||
}
|
||||
|
||||
override fun delete(name: String) {
|
||||
println("file: $folder -- $name")
|
||||
folder.resolve(name).deleteExisting()
|
||||
}
|
||||
|
||||
override fun list(): List<String> = folder
|
||||
.listDirectoryEntries()
|
||||
.filter { it.isRegularFile() && it.isReadable() }
|
||||
.map { it.name }
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package net.sergeych.bintools
|
||||
|
||||
import java.nio.file.Paths
|
||||
import kotlin.io.path.createDirectories
|
||||
|
||||
actual fun defaultNamedStorage(name: String): KVStorage {
|
||||
val rootFolder = Paths.get(when {
|
||||
// absolute path
|
||||
name.startsWith("/") -> name
|
||||
// path - assume the caller knows what to do
|
||||
name.contains("/") -> name
|
||||
// simple name - we will create it in the user home:
|
||||
else -> {
|
||||
val home = System.getProperty("user.home")
|
||||
"$home/.local_storage/$name"
|
||||
}
|
||||
})
|
||||
rootFolder.createDirectories()
|
||||
val provider = FileDataProvider(rootFolder)
|
||||
return DataKVStorage(provider)
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package net.sergeych.tools
|
||||
|
||||
import java.util.concurrent.locks.ReentrantLock
|
||||
|
||||
/**
|
||||
* Get the platform-depended implementation of a mutex-protected operation.
|
||||
* JVM version uses a concealed object synchronization pattern (per-object monitor lock)
|
||||
*/
|
||||
actual fun ProtectedOp(): ProtectedOpImplementation = object : ProtectedOpImplementation {
|
||||
private val access = ReentrantLock()
|
||||
override fun lock() {
|
||||
access.lock()
|
||||
}
|
||||
|
||||
override fun unlock() {
|
||||
access.unlock()
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package net.sergeych.synctools
|
||||
|
||||
@Suppress("EXPECT_ACTUAL_CLASSIFIERS_ARE_IN_BETA_WARNING")
|
||||
actual class WaitHandle {
|
||||
private val access = Object()
|
||||
|
||||
actual fun await(milliseconds: Long): Boolean {
|
||||
return synchronized(access) {
|
||||
try {
|
||||
access.wait(milliseconds)
|
||||
true
|
||||
}
|
||||
catch(_: InterruptedException) {
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
actual fun wakeUp() {
|
||||
synchronized(access) { access.notifyAll() }
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user