Skip to content

Instantly share code, notes, and snippets.

View bnorm's full-sized avatar
🐢

Brian Norman bnorm

🐢
View GitHub Profile
@bnorm
bnorm / javax.script.ScriptEngineFactory
Last active November 29, 2017 14:56
Kotlin Script Engine
org.jetbrains.kotlin.script.jsr223.KotlinJsr223JvmLocalScriptEngineFactory
@bnorm
bnorm / strings.kt
Created December 20, 2017 20:33
Turns a Kotlin Data class toString() into formatted JSON-like output
fun Any?.toIndentString(): String {
val notFancy = toString()
return buildString(notFancy.length) {
var indent = 0
fun StringBuilder.line() {
appendln()
repeat(2 * indent) { append(' ') }
}
@bnorm
bnorm / ByteBuffers.java
Last active June 28, 2022 03:50
Okio Source/Sink for ByteBuffers
import java.io.IOException;
import java.nio.ByteBuffer;
import okio.Buffer;
import okio.BufferedSink;
import okio.BufferedSource;
import okio.Okio;
import okio.Sink;
import okio.Source;
import okio.Timeout;
@bnorm
bnorm / Ciphers.java
Created February 14, 2018 21:36
Example CipherSource and CipherSink
import java.io.IOException;
import java.net.ProtocolException;
import java.security.GeneralSecurityException;
import java.util.Random;
import javax.crypto.Cipher;
import javax.crypto.ShortBufferException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import okio.Buffer;
import okio.BufferedSink;
@bnorm
bnorm / OkioAsyncChannels.kt
Created May 22, 2018 18:15
Okio based Kotlin suspension extension functions for Java asynchronous NIO channels
import kotlinx.coroutines.experimental.nio.aRead
import kotlinx.coroutines.experimental.nio.aWrite
import okio.Buffer
import java.nio.ByteBuffer
import java.nio.channels.AsynchronousFileChannel
import java.nio.channels.AsynchronousSocketChannel
import java.util.concurrent.TimeUnit
suspend fun AsynchronousSocketChannel.aRead(
buffer: Buffer,
@bnorm
bnorm / websocket.kt
Last active September 29, 2020 15:50
Structured OkHttp WebSockets
interface WebSocketSession {
val incoming: ReceiveChannel<String>
val outgoing: SendChannel<String>
}
suspend fun <R> OkHttpClient.newWebSocket(
request: Request,
block: suspend WebSocketSession.() -> R
): R = coroutineScope {
val incoming = Channel<String>()
@bnorm
bnorm / buildconfig-configuration.kt
Last active November 21, 2020 18:49
Writing Your Second Kotlin Compiler Plugin
buildConfig {
val project = project(":kotlin-ir-plugin")
packageName(project.group.toString())
buildConfigField("String", "KOTLIN_PLUGIN_ID", "\"${rootProject.extra["kotlin_plugin_id"]}\"")
buildConfigField("String", "KOTLIN_PLUGIN_GROUP", "\"${project.group}\"")
buildConfigField("String", "KOTLIN_PLUGIN_NAME", "\"${project.name}\"")
buildConfigField("String", "KOTLIN_PLUGIN_VERSION", "\"${project.version}\"")
}
@bnorm
bnorm / TemplateGradlePlugin.kt
Created November 21, 2020 18:50
Writing Your Second Kotlin Compiler Plugin - Part 1
class TemplateGradlePlugin : KotlinCompilerPluginSupportPlugin {
override fun apply(target: Project): Unit = with(target) {
extensions.create("template", TemplateGradleExtension::class.java)
}
override fun isApplicable(kotlinCompilation: KotlinCompilation<*>): Boolean = true
override fun getCompilerPluginId(): String = BuildConfig.KOTLIN_PLUGIN_ID
override fun getPluginArtifact(): SubpluginArtifact = SubpluginArtifact(
@AutoService(CommandLineProcessor::class)
class TemplateCommandLineProcessor : CommandLineProcessor {
companion object {
private const val OPTION_STRING = "string"
private const val OPTION_FILE = "file"
val ARG_STRING = CompilerConfigurationKey<String>(OPTION_STRING)
val ARG_FILE = CompilerConfigurationKey<String>(OPTION_FILE)
}
@AutoService(ComponentRegistrar::class)
class TemplateComponentRegistrar(
private val defaultString: String,
private val defaultFile: String,
) : ComponentRegistrar {
@Suppress("unused") // Used by service loader
constructor() : this(
defaultString = "Hello, World!",
defaultFile = "file.txt"