view src/main/kotlin/name/blackcap/passman/See.kt @ 4:02b101422726

See bugs.
author David Barts <n5jrn@me.com>
date Sun, 11 Sep 2022 20:44:59 -0700
parents eafa3779aef8
children ad997df1f560
line wrap: on
line source

package name.blackcap.passman

/* Would be nice if there was a more programmatic and comprehensive way of
   doing this, but alas. Even the oft-recommended StringEscapeUtils does
   something cruder than the below. Le sigh. */

import java.util.Formatter

private const val DELIM = '"'
private const val SHY = '\u00ad'

private val STD_ESC_MAP = mapOf<Char, Char>('\t' to 't', '\b' to 'b', '\n' to 'n',
    '\r' to 'r', '\u000c' to 'f', '"' to '"', '\\' to '\\')
private val BANNED = setOf<Char>(DELIM, SHY, '\\')
private const val MIN_ASCII = ' '
private const val MAX_ASCII = '~'
private const val MIN_8859 = '\u00a1'
private const val MAX_8859 = '\u00ff'

fun see(input: String, simple: Boolean = false): String =
    if (simple) seeSimple(input) else seeAggressive(input)

private fun seeSimple(input: String): String = StringBuilder().run {
    append(DELIM)
    append(input)
    append(DELIM)
    toString()
}

private fun seeAggressive(input: String): String {
    val accum = Formatter()
    accum.format("%c", DELIM)
    for (ch in input) {
        if ((ch !in BANNED) && ((ch in MIN_ASCII..MAX_ASCII) || (ch in MIN_8859 .. MAX_8859))) {
            accum.format("%c", ch)
            continue
        }
        val mapped = STD_ESC_MAP[ch]
        if (mapped != null) {
            accum.format("\\%c", mapped)
        } else {
            accum.format("\\u%04x", ch.code)
        }
    }
    accum.format("%c", DELIM)
    return accum.toString()
}