changeset 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 711cc42e96d7
files src/main/kotlin/name/blackcap/passman/Database.kt src/main/kotlin/name/blackcap/passman/Entry.kt src/main/kotlin/name/blackcap/passman/See.kt
diffstat 3 files changed, 19 insertions(+), 39 deletions(-) [+]
line wrap: on
line diff
--- a/src/main/kotlin/name/blackcap/passman/Database.kt	Sun Sep 11 20:44:59 2022 -0700
+++ b/src/main/kotlin/name/blackcap/passman/Database.kt	Sun Sep 11 21:29:20 2022 -0700
@@ -18,9 +18,9 @@
             val exists = Files.exists(Path.of(fileName))
             if (!exists) {
                 if (create) {
-                    error("initializing database ${see(fileName, simple = true)}")
+                    error("initializing database ${see(fileName)}")
                 } else {
-                    die("${see(fileName, simple = true)} not found")
+                    die("${see(fileName)} not found")
                 }
             }
             val masterPassword = getPassword(passwordPrompt, !exists)
@@ -120,11 +120,6 @@
 public fun ResultSet.getDecrypted(columnIndex: Int, encryption: Encryption) =
     encryption.decrypt(getBytes(columnIndex))
 
-public fun ResultSet.getDate(columnIndex: Int): java.util.Date? {
-    val rawDate = getLong(columnIndex)
-    return if (wasNull()) { null } else { java.util.Date(rawDate) }
-}
-
 public fun PreparedStatement.setEncryptedString(columnIndex: Int, value: String, encryption: Encryption) =
     setBytes(columnIndex, encryption.encryptFromString(value))
 
--- a/src/main/kotlin/name/blackcap/passman/Entry.kt	Sun Sep 11 20:44:59 2022 -0700
+++ b/src/main/kotlin/name/blackcap/passman/Entry.kt	Sun Sep 11 21:29:20 2022 -0700
@@ -1,9 +1,6 @@
 package name.blackcap.passman
 
-import java.lang.StringBuilder
-import java.sql.Connection
-import java.sql.PreparedStatement
-import java.util.Date
+import java.util.*
 
 class Entry(val name: String, val username: String, val password: CharArray, val notes: String,
             val created: Date? = null, val modified: Date? = null, val accessed: Date? = null) {
--- a/src/main/kotlin/name/blackcap/passman/See.kt	Sun Sep 11 20:44:59 2022 -0700
+++ b/src/main/kotlin/name/blackcap/passman/See.kt	Sun Sep 11 21:29:20 2022 -0700
@@ -1,46 +1,34 @@
 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 ALWAYS_ALLOW = setOf<Char>(' ')
+private val ALWAYS_BAN = setOf<Char>(DELIM, '\\')
+private val FORBIDDEN = setOf<Byte>(Character.CONTROL, Character.FORMAT,
+    Character.SURROGATE, Character.PRIVATE_USE, Character.UNASSIGNED,
+    Character.SPACE_SEPARATOR)
 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 {
+fun see(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))) {
+        if (ch in ALWAYS_ALLOW) {
             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)
+        if (ch in ALWAYS_BAN || Character.getType(ch).toByte() in FORBIDDEN) {
+            val mapped = STD_ESC_MAP[ch]
+            if (mapped != null) {
+                accum.format("\\%c", mapped)
+            } else {
+                accum.format("\\u%04x", ch.code)
+            }
+            continue
         }
+        accum.format("%c", ch)
     }
     accum.format("%c", DELIM)
     return accum.toString()