Skip to content

Instantly share code, notes, and snippets.

View mrenouf's full-sized avatar

Mark Renouf mrenouf

View GitHub Profile
import import kotlinx.io.Source
import kotlinx.io.readLine
import kotlinx.serialization.json.Json
private inline fun <reified T> jsonlFlowOf(json: Json, source: Source): Flow<T> {
return flow {
val line = source.readLine() ?: return@flow
emit(json.decodeFromString(line))
}
}
@mrenouf
mrenouf / MutableLazy.kt
Last active December 9, 2025 04:13
MutableLazy
package com.bitgrind.scrabble.ext
import kotlin.concurrent.atomics.AtomicReference
import kotlin.concurrent.atomics.ExperimentalAtomicApi
import kotlin.reflect.KProperty
fun <T : Any> mutableLazy(initializer: () -> T) = MutableLazy(initializer)
/**
* A PUBLICATION-style atomic lazy that’s also mutable.
@mrenouf
mrenouf / IntHexSerializer.kt
Last active December 8, 2025 04:03
KSerializer for Int as Hex string
import kotlinx.serialization.KSerializer
import kotlinx.serialization.Serializable
import kotlinx.serialization.descriptors.PrimitiveKind
import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor
import kotlinx.serialization.descriptors.SerialDescriptor
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
class IntHexSerializer : KSerializer<Int> {
@mrenouf
mrenouf / crc32b.kt
Last active December 8, 2025 03:52
crc32b in Kotlin
private const val CRC32_POLYNOMIAL_MSB = 0xEDB88320.toInt()
private val CRC32_REVERSE_TABLE = IntArray(256) {
var crc = it
repeat(8) {
if ((crc and 1) != 0) {
crc = (crc ushr 1) xor CRC32_POLYNOMIAL_MSB
} else {
crc = crc ushr 1
}
}
@mrenouf
mrenouf / gist:53761f5dc1962b39c7e4b16ff1804a4b
Created December 1, 2025 20:02
Kotlin String extension that should exist: `fun indexAfter(token: String): Int`
private fun String.indexAfter(token: String): Int {
return indexOf(token).let { if (it < 0) -1 else it + token.length }
}
package com.bitgrind.common.trees
import java.util.*
class SuffixTree {
private class SuffixRef(val word: Int, val offset: Int)
private class Edge(val word: Int, var first: Int, val last: Int, var node: Node) {
val length: Int
object LChHues {
// --- Palette L*=67 C*=40 (24 Colors) ---
val lch_L67_C40_01 = Color(0xffe586a5)
val lch_L67_C40_02 = Color(0xffe78793)
val lch_L67_C40_03 = Color(0xffe48a81)
val lch_L67_C40_04 = Color(0xffdd8f72)
val lch_L67_C40_05 = Color(0xffd39566)
val lch_L67_C40_06 = Color(0xffc59c5d)
val lch_L67_C40_07 = Color(0xffb5a25a)
val lch_L67_C40_08 = Color(0xffa3a85b)
@mrenouf
mrenouf / Window.kt
Created April 8, 2025 02:47
Flow window function for log event flows -> lazy list UI
package com.android.atool.ui
import kotlinx.coroutines.channels.BufferOverflow.DROP_LATEST
import kotlinx.coroutines.flow.buffer
import kotlinx.coroutines.flow.channelFlow
import kotlinx.coroutines.flow.Flow
/**
* Creates a [Flow] that emits sliding windows of the elements from the original [Flow].
* Each emitted list represents a window of the specified [length]. The window starts with
@mrenouf
mrenouf / PosixFileModes.kt
Created April 22, 2024 14:18
Parse and format posix raw file modes (including file type and special (suid/setgid/sticky) bits)
private const val FILE_TYPES = "?pc?d?b?-?l?s???"
fun String.toPosixModeInt(): Int {
require(length == 10) { "Should have 10 characters" }
// type
val type = when(get(0)) {
'p' -> 1
'c' -> 2
'd' -> 4
'b' -> 6
package adb
import kotlinx.coroutines.CoroutineName
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.DelicateCoroutinesApi
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.isActive
import kotlinx.coroutines.launch
import java.lang.ref.Reference
import java.lang.ref.ReferenceQueue