diff options
author | Jason A. Donenfeld <Jason@zx2c4.com> | 2020-03-28 01:41:54 -0600 |
---|---|---|
committer | Jason A. Donenfeld <Jason@zx2c4.com> | 2020-03-28 01:42:06 -0600 |
commit | b75946af46f7760559d91f66d184d82c78bf7ea6 (patch) | |
tree | 204796f6d94a7bcd43884004aceebb6f9b7a0e4c /ui/src | |
parent | b9b188693c9a8c7f7a90ced7e12da0deef0eecdc (diff) |
TunnelComparator: naturally sort tunnel list
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
Diffstat (limited to 'ui/src')
-rw-r--r-- | ui/src/main/java/com/wireguard/android/model/TunnelComparator.kt | 60 | ||||
-rw-r--r-- | ui/src/main/java/com/wireguard/android/model/TunnelManager.kt | 4 |
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" |