Mercurial > cgi-bin > hgweb.cgi > PassMan
comparison src/main/kotlin/name/blackcap/passman/See.kt @ 5:ad997df1f560
Fix see() to be about as good as sccc.
author | David Barts <n5jrn@me.com> |
---|---|
date | Sun, 11 Sep 2022 21:29:20 -0700 |
parents | 02b101422726 |
children | 72619175004e |
comparison
equal
deleted
inserted
replaced
4:02b101422726 | 5:ad997df1f560 |
---|---|
1 package name.blackcap.passman | 1 package name.blackcap.passman |
2 | |
3 /* Would be nice if there was a more programmatic and comprehensive way of | |
4 doing this, but alas. Even the oft-recommended StringEscapeUtils does | |
5 something cruder than the below. Le sigh. */ | |
6 | 2 |
7 import java.util.Formatter | 3 import java.util.Formatter |
8 | 4 |
9 private const val DELIM = '"' | 5 private const val DELIM = '"' |
10 private const val SHY = '\u00ad' | 6 private val ALWAYS_ALLOW = setOf<Char>(' ') |
11 | 7 private val ALWAYS_BAN = setOf<Char>(DELIM, '\\') |
8 private val FORBIDDEN = setOf<Byte>(Character.CONTROL, Character.FORMAT, | |
9 Character.SURROGATE, Character.PRIVATE_USE, Character.UNASSIGNED, | |
10 Character.SPACE_SEPARATOR) | |
12 private val STD_ESC_MAP = mapOf<Char, Char>('\t' to 't', '\b' to 'b', '\n' to 'n', | 11 private val STD_ESC_MAP = mapOf<Char, Char>('\t' to 't', '\b' to 'b', '\n' to 'n', |
13 '\r' to 'r', '\u000c' to 'f', '"' to '"', '\\' to '\\') | 12 '\r' to 'r', '\u000c' to 'f', '"' to '"', '\\' to '\\') |
14 private val BANNED = setOf<Char>(DELIM, SHY, '\\') | |
15 private const val MIN_ASCII = ' ' | |
16 private const val MAX_ASCII = '~' | |
17 private const val MIN_8859 = '\u00a1' | |
18 private const val MAX_8859 = '\u00ff' | |
19 | 13 |
20 fun see(input: String, simple: Boolean = false): String = | 14 fun see(input: String): String { |
21 if (simple) seeSimple(input) else seeAggressive(input) | |
22 | |
23 private fun seeSimple(input: String): String = StringBuilder().run { | |
24 append(DELIM) | |
25 append(input) | |
26 append(DELIM) | |
27 toString() | |
28 } | |
29 | |
30 private fun seeAggressive(input: String): String { | |
31 val accum = Formatter() | 15 val accum = Formatter() |
32 accum.format("%c", DELIM) | 16 accum.format("%c", DELIM) |
33 for (ch in input) { | 17 for (ch in input) { |
34 if ((ch !in BANNED) && ((ch in MIN_ASCII..MAX_ASCII) || (ch in MIN_8859 .. MAX_8859))) { | 18 if (ch in ALWAYS_ALLOW) { |
35 accum.format("%c", ch) | 19 accum.format("%c", ch) |
36 continue | 20 continue |
37 } | 21 } |
38 val mapped = STD_ESC_MAP[ch] | 22 if (ch in ALWAYS_BAN || Character.getType(ch).toByte() in FORBIDDEN) { |
39 if (mapped != null) { | 23 val mapped = STD_ESC_MAP[ch] |
40 accum.format("\\%c", mapped) | 24 if (mapped != null) { |
41 } else { | 25 accum.format("\\%c", mapped) |
42 accum.format("\\u%04x", ch.code) | 26 } else { |
27 accum.format("\\u%04x", ch.code) | |
28 } | |
29 continue | |
43 } | 30 } |
31 accum.format("%c", ch) | |
44 } | 32 } |
45 accum.format("%c", DELIM) | 33 accum.format("%c", DELIM) |
46 return accum.toString() | 34 return accum.toString() |
47 } | 35 } |