Commit 7e9b937b authored by Mygod's avatar Mygod

Fix platform nullability checks

parent 5841e26e
...@@ -128,7 +128,7 @@ class App : Application() { ...@@ -128,7 +128,7 @@ class App : Application() {
val assetManager = assets val assetManager = assets
for (dir in arrayOf("acl", "overture")) for (dir in arrayOf("acl", "overture"))
try { try {
for (file in assetManager.list(dir)) assetManager.open("$dir/$file").use { input -> for (file in assetManager.list(dir)!!) assetManager.open("$dir/$file").use { input ->
File(deviceStorage.filesDir, file).outputStream().use { output -> input.copyTo(output) } File(deviceStorage.filesDir, file).outputStream().use { output -> input.copyTo(output) }
} }
} catch (e: IOException) { } catch (e: IOException) {
......
...@@ -174,8 +174,8 @@ class AppManager : AppCompatActivity(), Toolbar.OnMenuItemClickListener { ...@@ -174,8 +174,8 @@ class AppManager : AppCompatActivity(), Toolbar.OnMenuItemClickListener {
toolbar.setNavigationIcon(theme.resolveResourceId(R.attr.homeAsUpIndicator)) toolbar.setNavigationIcon(theme.resolveResourceId(R.attr.homeAsUpIndicator))
toolbar.setNavigationOnClickListener { toolbar.setNavigationOnClickListener {
val intent = parentActivityIntent val intent = parentActivityIntent
if (shouldUpRecreateTask(intent) || isTaskRoot) if (intent == null || !shouldUpRecreateTask(intent) && !isTaskRoot) finish() else
TaskStackBuilder.create(this).addNextIntentWithParentStack(intent).startActivities() else finish() TaskStackBuilder.create(this).addNextIntentWithParentStack(intent).startActivities()
} }
toolbar.inflateMenu(R.menu.app_manager_menu) toolbar.inflateMenu(R.menu.app_manager_menu)
toolbar.setOnMenuItemClickListener(this) toolbar.setOnMenuItemClickListener(this)
......
...@@ -142,10 +142,13 @@ class MainActivity : AppCompatActivity(), ShadowsocksConnection.Interface, OnPre ...@@ -142,10 +142,13 @@ class MainActivity : AppCompatActivity(), ShadowsocksConnection.Interface, OnPre
} }
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
if (requestCode != REQUEST_CONNECT) super.onActivityResult(requestCode, resultCode, data) when {
else if (resultCode == Activity.RESULT_OK) app.startService() else { requestCode != REQUEST_CONNECT -> super.onActivityResult(requestCode, resultCode, data)
snackbar().setText(R.string.vpn_permission_denied).show() resultCode == Activity.RESULT_OK -> app.startService()
Crashlytics.log(Log.ERROR, TAG, "Failed to start VpnService from onActivityResult: $data") else -> {
snackbar().setText(R.string.vpn_permission_denied).show()
Crashlytics.log(Log.ERROR, TAG, "Failed to start VpnService from onActivityResult: $data")
}
} }
} }
...@@ -194,7 +197,7 @@ class MainActivity : AppCompatActivity(), ShadowsocksConnection.Interface, OnPre ...@@ -194,7 +197,7 @@ class MainActivity : AppCompatActivity(), ShadowsocksConnection.Interface, OnPre
} }
private fun handleShareIntent(intent: Intent) { private fun handleShareIntent(intent: Intent) {
val sharedStr = when (intent.action) { val sharedStr = when (intent.action) {
Intent.ACTION_VIEW -> intent.data.toString() Intent.ACTION_VIEW -> intent.data?.toString()
NfcAdapter.ACTION_NDEF_DISCOVERED -> { NfcAdapter.ACTION_NDEF_DISCOVERED -> {
val rawMsgs = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES) val rawMsgs = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES)
if (rawMsgs != null && rawMsgs.isNotEmpty()) String((rawMsgs[0] as NdefMessage).records[0].payload) if (rawMsgs != null && rawMsgs.isNotEmpty()) String((rawMsgs[0] as NdefMessage).records[0].payload)
......
...@@ -50,8 +50,8 @@ class ProfileConfigActivity : AppCompatActivity() { ...@@ -50,8 +50,8 @@ class ProfileConfigActivity : AppCompatActivity() {
override fun onBackPressed() { override fun onBackPressed() {
if (DataStore.dirty) AlertDialog.Builder(this) if (DataStore.dirty) AlertDialog.Builder(this)
.setTitle(R.string.unsaved_changes_prompt) .setTitle(R.string.unsaved_changes_prompt)
.setPositiveButton(R.string.yes, { _, _ -> child.saveAndExit() }) .setPositiveButton(R.string.yes) { _, _ -> child.saveAndExit() }
.setNegativeButton(R.string.no, { _, _ -> finish() }) .setNegativeButton(R.string.no) { _, _ -> finish() }
.setNeutralButton(android.R.string.cancel, null) .setNeutralButton(android.R.string.cancel, null)
.create() .create()
.show() else super.onBackPressed() .show() else super.onBackPressed()
......
...@@ -85,12 +85,11 @@ class ProfilesFragment : ToolbarFragment(), Toolbar.OnMenuItemClickListener { ...@@ -85,12 +85,11 @@ class ProfilesFragment : ToolbarFragment(), Toolbar.OnMenuItemClickListener {
@SuppressLint("ValidFragment") @SuppressLint("ValidFragment")
class QRCodeDialog() : DialogFragment() { class QRCodeDialog() : DialogFragment() {
constructor(url: String) : this() { constructor(url: String) : this() {
arguments = bundleOf(Pair(KEY_URL, url)) arguments = bundleOf(Pair(KEY_URL, url))
} }
private val url get() = arguments!!.getString(KEY_URL) private val url get() = arguments?.getString(KEY_URL)!!
private val nfcShareItem by lazy { url.toByteArray() } private val nfcShareItem by lazy { url.toByteArray() }
private var adapter: NfcAdapter? = null private var adapter: NfcAdapter? = null
...@@ -424,7 +423,7 @@ class ProfilesFragment : ToolbarFragment(), Toolbar.OnMenuItemClickListener { ...@@ -424,7 +423,7 @@ class ProfilesFragment : ToolbarFragment(), Toolbar.OnMenuItemClickListener {
var success = false var success = false
val activity = activity as MainActivity val activity = activity as MainActivity
for (uri in data!!.datas) try { for (uri in data!!.datas) try {
Profile.parseJson(activity.contentResolver.openInputStream(uri).bufferedReader().readText(), Profile.parseJson(activity.contentResolver.openInputStream(uri)!!.bufferedReader().readText(),
feature).forEach { feature).forEach {
ProfileManager.createProfile(it) ProfileManager.createProfile(it)
success = true success = true
...@@ -438,7 +437,7 @@ class ProfilesFragment : ToolbarFragment(), Toolbar.OnMenuItemClickListener { ...@@ -438,7 +437,7 @@ class ProfilesFragment : ToolbarFragment(), Toolbar.OnMenuItemClickListener {
REQUEST_EXPORT_PROFILES -> { REQUEST_EXPORT_PROFILES -> {
val profiles = ProfileManager.getAllProfiles() val profiles = ProfileManager.getAllProfiles()
if (profiles != null) try { if (profiles != null) try {
requireContext().contentResolver.openOutputStream(data!!.data).bufferedWriter().use { requireContext().contentResolver.openOutputStream(data?.data!!)!!.bufferedWriter().use {
it.write(JSONArray(profiles.map { it.toJson() }.toTypedArray()).toString(2)) it.write(JSONArray(profiles.map { it.toJson() }.toTypedArray()).toString(2))
} }
} catch (e: Exception) { } catch (e: Exception) {
......
...@@ -64,9 +64,8 @@ class ScannerActivity : AppCompatActivity(), Toolbar.OnMenuItemClickListener, Ba ...@@ -64,9 +64,8 @@ class ScannerActivity : AppCompatActivity(), Toolbar.OnMenuItemClickListener, Ba
private fun navigateUp() { private fun navigateUp() {
val intent = parentActivityIntent val intent = parentActivityIntent
if (shouldUpRecreateTask(intent) || isTaskRoot) if (intent == null || !shouldUpRecreateTask(intent) && !isTaskRoot) finish() else
TaskStackBuilder.create(this).addNextIntentWithParentStack(intent).startActivities() TaskStackBuilder.create(this).addNextIntentWithParentStack(intent).startActivities()
else finish()
} }
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
......
...@@ -36,60 +36,57 @@ object LocalDnsService { ...@@ -36,60 +36,57 @@ object LocalDnsService {
val data = data val data = data
val profile = data.profile!! val profile = data.profile!!
fun makeDns(name: String, address: String, timeout: Int, edns: Boolean = true): JSONObject { fun makeDns(name: String, address: String, timeout: Int, edns: Boolean = true) = JSONObject().apply {
val dns = JSONObject() put("Name", name)
.put("Name", name) put("Address", when (address.parseNumericAddress()) {
.put("Address", when (address.parseNumericAddress()) {
is Inet6Address -> "[$address]" is Inet6Address -> "[$address]"
else -> address else -> address
}) })
.put("Timeout", timeout) put("Timeout", timeout)
.put("EDNSClientSubnet", JSONObject().put("Policy", "disable")) put("EDNSClientSubnet", JSONObject().put("Policy", "disable"))
if (edns) dns put("Protocol", if (edns) {
.put("Protocol", "tcp") put("Socks5Address", "127.0.0.1:" + DataStore.portProxy)
.put("Socks5Address", "127.0.0.1:" + DataStore.portProxy) "tcp"
else dns.put("Protocol", "udp") } else "udp")
return dns
} }
fun buildOvertureConfig(file: String): String { fun buildOvertureConfig(file: String) = file.also {
val config = JSONObject() File(app.deviceStorage.filesDir, it).writeText(JSONObject().run {
.put("BindAddress", "127.0.0.1:" + DataStore.portLocalDns) put("BindAddress", "127.0.0.1:" + DataStore.portLocalDns)
.put("RedirectIPv6Record", true) put("RedirectIPv6Record", true)
.put("DomainBase64Decode", false) put("DomainBase64Decode", false)
.put("HostsFile", "hosts") put("HostsFile", "hosts")
.put("MinimumTTL", 120) put("MinimumTTL", 120)
.put("CacheSize", 4096) put("CacheSize", 4096)
val remoteDns = JSONArray(profile.remoteDns.split(",") val remoteDns = JSONArray(profile.remoteDns.split(",")
.mapIndexed { i, dns -> makeDns("UserDef-$i", dns.trim() + ":53", 12) }) .mapIndexed { i, dns -> makeDns("UserDef-$i", dns.trim() + ":53", 12) })
val localDns = JSONArray(arrayOf( val localDns = JSONArray(arrayOf(
makeDns("Primary-1", "208.67.222.222:443", 9, false), makeDns("Primary-1", "208.67.222.222:443", 9, false),
makeDns("Primary-2", "119.29.29.29:53", 9, false), makeDns("Primary-2", "119.29.29.29:53", 9, false),
makeDns("Primary-3", "114.114.114.114:53", 9, false) makeDns("Primary-3", "114.114.114.114:53", 9, false)))
)) when (profile.route) {
Acl.BYPASS_CHN, Acl.BYPASS_LAN_CHN, Acl.GFWLIST, Acl.CUSTOM_RULES -> {
when (profile.route) { put("PrimaryDNS", localDns)
Acl.BYPASS_CHN, Acl.BYPASS_LAN_CHN, Acl.GFWLIST, Acl.CUSTOM_RULES -> config put("AlternativeDNS", remoteDns)
.put("PrimaryDNS", localDns) put("IPNetworkFile", "china_ip_list.txt")
.put("AlternativeDNS", remoteDns) }
.put("IPNetworkFile", "china_ip_list.txt") Acl.CHINALIST -> {
Acl.CHINALIST -> config put("PrimaryDNS", localDns)
.put("PrimaryDNS", localDns) put("AlternativeDNS", remoteDns)
.put("AlternativeDNS", remoteDns) }
else -> config else -> {
.put("PrimaryDNS", remoteDns) put("PrimaryDNS", remoteDns)
// no need to setup AlternativeDNS in Acl.ALL/BYPASS_LAN mode // no need to setup AlternativeDNS in Acl.ALL/BYPASS_LAN mode
.put("OnlyPrimaryDNS", true) put("OnlyPrimaryDNS", true)
} }
File(app.deviceStorage.filesDir, file).writeText(config.toString()) }
return file toString()
})
} }
if (!profile.udpdns) data.processes.start(buildAdditionalArguments(arrayListOf( if (!profile.udpdns) data.processes.start(buildAdditionalArguments(arrayListOf(
File(app.applicationInfo.nativeLibraryDir, Executable.OVERTURE).absolutePath, File(app.applicationInfo.nativeLibraryDir, Executable.OVERTURE).absolutePath,
"-c", buildOvertureConfig("overture.conf") "-c", buildOvertureConfig("overture.conf"))))
)))
} }
} }
} }
...@@ -22,7 +22,6 @@ package com.github.shadowsocks.bg ...@@ -22,7 +22,6 @@ package com.github.shadowsocks.bg
import android.app.Service import android.app.Service
import android.content.Intent import android.content.Intent
import android.os.IBinder
/** /**
* Shadowsocks service at its minimum. * Shadowsocks service at its minimum.
...@@ -36,7 +35,7 @@ class ProxyService : Service(), BaseService.Interface { ...@@ -36,7 +35,7 @@ class ProxyService : Service(), BaseService.Interface {
override fun createNotification(profileName: String): ServiceNotification = override fun createNotification(profileName: String): ServiceNotification =
ServiceNotification(this, profileName, "service-proxy", true) ServiceNotification(this, profileName, "service-proxy", true)
override fun onBind(intent: Intent): IBinder? = super.onBind(intent) override fun onBind(intent: Intent) = super.onBind(intent)
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int = override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int =
super<BaseService.Interface>.onStartCommand(intent, flags, startId) super<BaseService.Interface>.onStartCommand(intent, flags, startId)
} }
...@@ -91,7 +91,7 @@ class ServiceNotification(private val service: BaseService.Interface, profileNam ...@@ -91,7 +91,7 @@ class ServiceNotification(private val service: BaseService.Interface, profileNam
service.registerReceiver(lockReceiver, screenFilter) service.registerReceiver(lockReceiver, screenFilter)
} }
private fun update(action: String, forceShow: Boolean = false) { private fun update(action: String?, forceShow: Boolean = false) {
if (forceShow || service.data.state == BaseService.CONNECTED) when (action) { if (forceShow || service.data.state == BaseService.CONNECTED) when (action) {
Intent.ACTION_SCREEN_OFF -> { Intent.ACTION_SCREEN_OFF -> {
setVisible(false, forceShow) setVisible(false, forceShow)
......
...@@ -22,7 +22,6 @@ package com.github.shadowsocks.bg ...@@ -22,7 +22,6 @@ package com.github.shadowsocks.bg
import android.app.Service import android.app.Service
import android.content.Intent import android.content.Intent
import android.os.IBinder
import com.github.shadowsocks.App.Companion.app import com.github.shadowsocks.App.Companion.app
import com.github.shadowsocks.preference.DataStore import com.github.shadowsocks.preference.DataStore
import java.io.File import java.io.File
...@@ -36,7 +35,7 @@ class TransproxyService : Service(), LocalDnsService.Interface { ...@@ -36,7 +35,7 @@ class TransproxyService : Service(), LocalDnsService.Interface {
override fun createNotification(profileName: String): ServiceNotification = override fun createNotification(profileName: String): ServiceNotification =
ServiceNotification(this, profileName, "service-transproxy", true) ServiceNotification(this, profileName, "service-transproxy", true)
override fun onBind(intent: Intent): IBinder? = super.onBind(intent) override fun onBind(intent: Intent) = super.onBind(intent)
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int = override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int =
super<LocalDnsService.Interface>.onStartCommand(intent, flags, startId) super<LocalDnsService.Interface>.onStartCommand(intent, flags, startId)
......
...@@ -26,7 +26,6 @@ import android.content.Intent ...@@ -26,7 +26,6 @@ import android.content.Intent
import android.content.pm.PackageManager import android.content.pm.PackageManager
import android.net.* import android.net.*
import android.os.Build import android.os.Build
import android.os.IBinder
import android.os.ParcelFileDescriptor import android.os.ParcelFileDescriptor
import androidx.core.content.getSystemService import androidx.core.content.getSystemService
import com.github.shadowsocks.App.Companion.app import com.github.shadowsocks.App.Companion.app
...@@ -127,7 +126,7 @@ class VpnService : BaseVpnService(), LocalDnsService.Interface { ...@@ -127,7 +126,7 @@ class VpnService : BaseVpnService(), LocalDnsService.Interface {
} }
private var listeningForDefaultNetwork = false private var listeningForDefaultNetwork = false
override fun onBind(intent: Intent): IBinder? = when (intent.action) { override fun onBind(intent: Intent) = when (intent.action) {
SERVICE_INTERFACE -> super<BaseVpnService>.onBind(intent) SERVICE_INTERFACE -> super<BaseVpnService>.onBind(intent)
else -> super<LocalDnsService.Interface>.onBind(intent) else -> super<LocalDnsService.Interface>.onBind(intent)
} }
......
...@@ -38,9 +38,9 @@ class PluginConfiguration(val pluginsOptions: Map<String, PluginOptions>, val se ...@@ -38,9 +38,9 @@ class PluginConfiguration(val pluginsOptions: Map<String, PluginOptions>, val se
while (iterator.hasNext()) { while (iterator.hasNext()) {
val option = iterator.next() val option = iterator.next()
when { when {
option == "--nocomp" -> opt.put("nocomp", null) option == "--nocomp" -> opt["nocomp"] = null
option.startsWith("--") -> opt.put(option.substring(2), iterator.next()) option.startsWith("--") -> opt[option.substring(2)] = iterator.next()
else -> throw IllegalArgumentException("Unknown kcptun parameter: " + option) else -> throw IllegalArgumentException("Unknown kcptun parameter: $option")
} }
} }
} catch (exc: Exception) { } catch (exc: Exception) {
......
...@@ -152,7 +152,7 @@ object PluginManager { ...@@ -152,7 +152,7 @@ object PluginManager {
private fun initNativeFast(cr: ContentResolver, options: PluginOptions, uri: Uri): String { private fun initNativeFast(cr: ContentResolver, options: PluginOptions, uri: Uri): String {
val result = cr.call(uri, PluginContract.METHOD_GET_EXECUTABLE, null, val result = cr.call(uri, PluginContract.METHOD_GET_EXECUTABLE, null,
bundleOf(Pair(PluginContract.EXTRA_OPTIONS, options.id))).getString(PluginContract.EXTRA_ENTRY) bundleOf(Pair(PluginContract.EXTRA_OPTIONS, options.id)))!!.getString(PluginContract.EXTRA_ENTRY)!!
check(File(result).canExecute()) check(File(result).canExecute())
return result return result
} }
...@@ -173,7 +173,7 @@ object PluginManager { ...@@ -173,7 +173,7 @@ object PluginManager {
val path = cursor.getString(0) val path = cursor.getString(0)
val file = File(pluginDir, path) val file = File(pluginDir, path)
check(file.absolutePath.startsWith(pluginDirPath)) check(file.absolutePath.startsWith(pluginDirPath))
cr.openInputStream(uri.buildUpon().path(path).build()).use { inStream -> cr.openInputStream(uri.buildUpon().path(path).build())!!.use { inStream ->
file.outputStream().use { outStream -> inStream.copyTo(outStream) } file.outputStream().use { outStream -> inStream.copyTo(outStream) }
} }
list += Commandline.toString(arrayOf("chmod", cursor.getString(1), file.absolutePath)) list += Commandline.toString(arrayOf("chmod", cursor.getString(1), file.absolutePath))
......
...@@ -38,7 +38,7 @@ class PluginConfigurationDialogFragment : EditTextPreferenceDialogFragmentCompat ...@@ -38,7 +38,7 @@ class PluginConfigurationDialogFragment : EditTextPreferenceDialogFragmentCompat
override fun onPrepareDialogBuilder(builder: AlertDialog.Builder) { override fun onPrepareDialogBuilder(builder: AlertDialog.Builder) {
super.onPrepareDialogBuilder(builder) super.onPrepareDialogBuilder(builder)
val intent = PluginManager.buildIntent(arguments!!.getString(PLUGIN_ID_FRAGMENT_TAG), val intent = PluginManager.buildIntent(arguments?.getString(PLUGIN_ID_FRAGMENT_TAG)!!,
PluginContract.ACTION_HELP) PluginContract.ACTION_HELP)
val activity = requireActivity() val activity = requireActivity()
if (intent.resolveActivity(activity.packageManager) != null) builder.setNeutralButton("?") { _, _ -> if (intent.resolveActivity(activity.packageManager) != null) builder.setNeutralButton("?") { _, _ ->
......
...@@ -165,9 +165,9 @@ object Commandline { ...@@ -165,9 +165,9 @@ object Commandline {
result.add(current.toString()) result.add(current.toString())
} }
if (state == inQuote || state == inDoubleQuote) { if (state == inQuote || state == inDoubleQuote) {
throw IllegalArgumentException("unbalanced quotes in " + toProcess) throw IllegalArgumentException("unbalanced quotes in $toProcess")
} }
if (lastTokenIsSlash) throw IllegalArgumentException("escape character following nothing in " + toProcess) if (lastTokenIsSlash) throw IllegalArgumentException("escape character following nothing in $toProcess")
return result.toTypedArray() return result.toTypedArray()
} }
} }
...@@ -28,7 +28,7 @@ object TcpFastOpen { ...@@ -28,7 +28,7 @@ object TcpFastOpen {
* Is kernel version >= 3.7.1. * Is kernel version >= 3.7.1.
*/ */
val supported by lazy { val supported by lazy {
val match = """^(\d+)\.(\d+)\.(\d+)""".toRegex().find(System.getProperty("os.version")) val match = """^(\d+)\.(\d+)\.(\d+)""".toRegex().find(System.getProperty("os.version") ?: "")
if (match == null) false else when (match.groupValues[1].toInt()) { if (match == null) false else when (match.groupValues[1].toInt()) {
in Int.MIN_VALUE..2 -> false in Int.MIN_VALUE..2 -> false
3 -> when (match.groupValues[2].toInt()) { 3 -> when (match.groupValues[2].toInt()) {
......
...@@ -62,7 +62,7 @@ fun Resources.Theme.resolveResourceId(@AttrRes resId: Int): Int { ...@@ -62,7 +62,7 @@ fun Resources.Theme.resolveResourceId(@AttrRes resId: Int): Int {
return typedValue.resourceId return typedValue.resourceId
} }
val Intent.datas get() = listOfNotNull(data) + (clipData?.asIterable()?.map { it.uri }?.filterNotNull() ?: emptyList()) val Intent.datas get() = listOfNotNull(data) + (clipData?.asIterable()?.mapNotNull { it.uri } ?: emptyList())
fun printLog(t: Throwable) { fun printLog(t: Throwable) {
Crashlytics.logException(t) Crashlytics.logException(t)
......
...@@ -84,7 +84,7 @@ abstract class NativePluginProvider : ContentProvider() { ...@@ -84,7 +84,7 @@ abstract class NativePluginProvider : ContentProvider() {
return openFile(uri) return openFile(uri)
} }
override fun call(method: String?, arg: String?, extras: Bundle?): Bundle? = when (method) { override fun call(method: String, arg: String?, extras: Bundle?): Bundle? = when (method) {
PluginContract.METHOD_GET_EXECUTABLE -> bundleOf(Pair(PluginContract.EXTRA_ENTRY, getExecutable())) PluginContract.METHOD_GET_EXECUTABLE -> bundleOf(Pair(PluginContract.EXTRA_ENTRY, getExecutable()))
else -> super.call(method, arg, extras) else -> super.call(method, arg, extras)
} }
......
...@@ -38,7 +38,7 @@ class PluginOptions : HashMap<String, String?> { ...@@ -38,7 +38,7 @@ class PluginOptions : HashMap<String, String?> {
@Suppress("NAME_SHADOWING") @Suppress("NAME_SHADOWING")
var parseId = parseId var parseId = parseId
if (options.isNullOrEmpty()) return if (options.isNullOrEmpty()) return
val tokenizer = StringTokenizer(options + ';', "\\=;", true) val tokenizer = StringTokenizer("$options;", "\\=;", true)
val current = StringBuilder() val current = StringBuilder()
var key: String? = null var key: String? = null
while (tokenizer.hasMoreTokens()) { while (tokenizer.hasMoreTokens()) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment