mirror of https://github.com/NekoX-Dev/NekoX.git
112 lines
4.7 KiB
Kotlin
112 lines
4.7 KiB
Kotlin
/*******************************************************************************
|
|
* *
|
|
* Copyright (C) 2017 by Max Lv <max.c.lv@gmail.com> *
|
|
* Copyright (C) 2017 by Mygod Studio <contact-shadowsocks-android@mygod.be> *
|
|
* *
|
|
* This program is free software: you can redistribute it and/or modify *
|
|
* it under the terms of the GNU General Public License as published by *
|
|
* the Free Software Foundation, either version 3 of the License, or *
|
|
* (at your option) any later version. *
|
|
* *
|
|
* This program is distributed in the hope that it will be useful, *
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
|
* GNU General Public License for more details. *
|
|
* *
|
|
* You should have received a copy of the GNU General Public License *
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
|
* *
|
|
*******************************************************************************/
|
|
|
|
package com.github.shadowsocks.plugin
|
|
|
|
import android.os.Build
|
|
import androidx.annotation.RequiresApi
|
|
import java.util.*
|
|
|
|
/**
|
|
* Helper class for processing plugin options.
|
|
*
|
|
* Based on: https://github.com/apache/ant/blob/588ce1f/src/main/org/apache/tools/ant/types/Commandline.java
|
|
*/
|
|
@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
|
|
class PluginOptions : HashMap<String, String?> {
|
|
var id = ""
|
|
|
|
constructor() : super()
|
|
constructor(initialCapacity: Int) : super(initialCapacity)
|
|
constructor(initialCapacity: Int, loadFactor: Float) : super(initialCapacity, loadFactor)
|
|
|
|
private constructor(options: String?, parseId: Boolean) : this() {
|
|
@Suppress("NAME_SHADOWING")
|
|
var parseId = parseId
|
|
if (options.isNullOrEmpty()) return
|
|
check(options.all { !it.isISOControl() }) { "No control characters allowed." }
|
|
val tokenizer = StringTokenizer("$options;", "\\=;", true)
|
|
val current = StringBuilder()
|
|
var key: String? = null
|
|
while (tokenizer.hasMoreTokens()) when (val nextToken = tokenizer.nextToken()) {
|
|
"\\" -> current.append(tokenizer.nextToken())
|
|
"=" -> if (key == null) {
|
|
key = current.toString()
|
|
current.setLength(0)
|
|
} else current.append(nextToken)
|
|
";" -> {
|
|
if (key != null) {
|
|
put(key, current.toString())
|
|
key = null
|
|
} else if (current.isNotEmpty())
|
|
if (parseId) id = current.toString() else put(current.toString(), null)
|
|
current.setLength(0)
|
|
parseId = false
|
|
}
|
|
else -> current.append(nextToken)
|
|
}
|
|
}
|
|
|
|
constructor(options: String?) : this(options, true)
|
|
constructor(id: String, options: String?) : this(options, false) {
|
|
this.id = id
|
|
}
|
|
|
|
/**
|
|
* Put but if value is null or default, the entry is deleted.
|
|
*
|
|
* @return Old value before put.
|
|
*/
|
|
fun putWithDefault(key: String, value: String?, default: String? = null) =
|
|
if (value == null || value == default) remove(key) else put(key, value)
|
|
|
|
private fun append(result: StringBuilder, str: String) = str.indices.map { str[it] }.forEach {
|
|
when (it) {
|
|
'\\', '=', ';' -> {
|
|
result.append('\\') // intentionally no break
|
|
result.append(it)
|
|
}
|
|
else -> result.append(it)
|
|
}
|
|
}
|
|
|
|
fun toString(trimId: Boolean): String {
|
|
val result = StringBuilder()
|
|
if (!trimId) if (id.isEmpty()) return "" else append(result, id)
|
|
for ((key, value) in entries) {
|
|
if (result.isNotEmpty()) result.append(';')
|
|
append(result, key)
|
|
if (value != null) {
|
|
result.append('=')
|
|
append(result, value)
|
|
}
|
|
}
|
|
return result.toString()
|
|
}
|
|
|
|
override fun toString(): String = toString(true)
|
|
|
|
override fun equals(other: Any?): Boolean {
|
|
if (this === other) return true
|
|
return javaClass == other?.javaClass && super.equals(other) && id == (other as PluginOptions).id
|
|
}
|
|
override fun hashCode(): Int = Objects.hash(super.hashCode(), id)
|
|
}
|