summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorJason A. Donenfeld <Jason@zx2c4.com>2020-03-28 01:41:54 -0600
committerJason A. Donenfeld <Jason@zx2c4.com>2020-03-28 01:42:06 -0600
commitb75946af46f7760559d91f66d184d82c78bf7ea6 (patch)
tree204796f6d94a7bcd43884004aceebb6f9b7a0e4c
parentb9b188693c9a8c7f7a90ced7e12da0deef0eecdc (diff)
TunnelComparator: naturally sort tunnel list
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
-rw-r--r--ui/src/main/java/com/wireguard/android/model/TunnelComparator.kt60
-rw-r--r--ui/src/main/java/com/wireguard/android/model/TunnelManager.kt4
2 files changed, 61 insertions, 3 deletions
diff --git a/ui/src/main/java/com/wireguard/android/model/TunnelComparator.kt b/ui/src/main/java/com/wireguard/android/model/TunnelComparator.kt
new file mode 100644
index 00000000..96e69c58
--- /dev/null
+++ b/ui/src/main/java/com/wireguard/android/model/TunnelComparator.kt
@@ -0,0 +1,60 @@
+/*
+ * Copyright © 2020 WireGuard LLC. All Rights Reserved.
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package com.wireguard.android.model
+
+import java.util.Locale
+
+object TunnelComparator : Comparator<String> {
+ private class NaturalSortString(originalString: String) {
+ class NaturalSortToken(val maybeString: String?, val maybeNumber: Int?) : Comparable<NaturalSortToken> {
+ override fun compareTo(other: NaturalSortToken): Int {
+ if (maybeString == null) {
+ if (other.maybeString != null || maybeNumber!! < other.maybeNumber!!) {
+ return -1
+ } else if (maybeNumber > other.maybeNumber) {
+ return 1
+ }
+ } else if (other.maybeString == null || maybeString > other.maybeString) {
+ return 1
+ } else if (maybeString < other.maybeString) {
+ return -1
+ }
+ return 0
+ }
+ }
+ val tokens: MutableList<NaturalSortToken> = ArrayList()
+ init {
+ for (s in NATURAL_SORT_DIGIT_FINDER.findAll(originalString.split(WHITESPACE_FINDER).joinToString(" ").toLowerCase(Locale.ENGLISH))) {
+ try {
+ val n = s.value.toInt()
+ tokens.add(NaturalSortToken(null, n))
+ } catch (_: NumberFormatException) {
+ tokens.add(NaturalSortToken(s.value, null))
+ }
+ }
+ }
+ private companion object {
+ private val NATURAL_SORT_DIGIT_FINDER = Regex("""\d+|\D+""")
+ private val WHITESPACE_FINDER = Regex("""\s""")
+ }
+ }
+
+ override fun compare(a: String, b: String): Int {
+ if (a == b)
+ return 0
+ val na = NaturalSortString(a)
+ val nb = NaturalSortString(b)
+ for (i in 0 until nb.tokens.size) {
+ if (i == na.tokens.size) {
+ return -1
+ }
+ val c = na.tokens[i].compareTo(nb.tokens[i])
+ if (c != 0)
+ return c
+ }
+ return 1
+ }
+}
diff --git a/ui/src/main/java/com/wireguard/android/model/TunnelManager.kt b/ui/src/main/java/com/wireguard/android/model/TunnelManager.kt
index 43e94fdc..7d3a5e37 100644
--- a/ui/src/main/java/com/wireguard/android/model/TunnelManager.kt
+++ b/ui/src/main/java/com/wireguard/android/model/TunnelManager.kt
@@ -24,7 +24,6 @@ import com.wireguard.android.configStore.ConfigStore
import com.wireguard.android.util.ExceptionLoggers
import com.wireguard.android.databinding.ObservableSortedKeyedArrayList
import com.wireguard.config.Config
-import java9.util.Comparators
import java9.util.concurrent.CompletableFuture
import java9.util.concurrent.CompletionStage
import java.util.ArrayList
@@ -36,7 +35,7 @@ class TunnelManager(private val configStore: ConfigStore) : BaseObservable() {
val tunnels = CompletableFuture<ObservableSortedKeyedArrayList<String, ObservableTunnel>>()
private val context: Context = get()
private val delayedLoadRestoreTunnels = ArrayList<CompletableFuture<Void>>()
- private val tunnelMap: ObservableSortedKeyedArrayList<String, ObservableTunnel> = ObservableSortedKeyedArrayList(COMPARATOR)
+ private val tunnelMap: ObservableSortedKeyedArrayList<String, ObservableTunnel> = ObservableSortedKeyedArrayList(TunnelComparator)
private var haveLoaded = false
private fun addToList(name: String, config: Config?, state: Tunnel.State): ObservableTunnel? {
@@ -230,7 +229,6 @@ class TunnelManager(private val configStore: ConfigStore) : BaseObservable() {
.supplyAsync { getBackend().getStatistics(tunnel) }.thenApply(tunnel::onStatisticsChanged)
companion object {
- private val COMPARATOR = Comparators.thenComparing(java.lang.String.CASE_INSENSITIVE_ORDER, Comparators.naturalOrder())
private const val KEY_LAST_USED_TUNNEL = "last_used_tunnel"
private const val KEY_RESTORE_ON_BOOT = "restore_on_boot"
private const val KEY_RUNNING_TUNNELS = "enabled_configs"