Support escaped % signs and use a thread safe map for strings

This commit is contained in:
Syer10
2021-06-23 14:49:27 -04:00
parent 4dfd13845e
commit f36a7834db
2 changed files with 14 additions and 7 deletions

View File

@@ -16,17 +16,20 @@ import java.util.Collections
import java.util.Enumeration import java.util.Enumeration
import java.util.Locale import java.util.Locale
import java.util.ResourceBundle import java.util.ResourceBundle
import java.util.concurrent.ConcurrentHashMap
class XmlResourceBundle internal constructor(internal val lookup: Map<String, Any>) : ResourceBundle() { class XmlResourceBundle internal constructor(internal val lookup: ConcurrentHashMap<String, Any>) : ResourceBundle() {
constructor(stream: InputStream, charset: Charset = Charsets.UTF_8) : this( constructor(stream: InputStream, charset: Charset = Charsets.UTF_8) : this(
stream.reader(charset) stream.reader(charset)
) )
constructor(reader: Reader) : this( constructor(reader: Reader) : this(
format.decodeFromReader<Resources>( ConcurrentHashMap(
StAXReader(reader) format.decodeFromReader<Resources>(
).values.associate { it.name to it.value } StAXReader(reader)
).values.associate { it.name to it.value }
)
) )
public override fun handleGetObject(key: String): Any? { public override fun handleGetObject(key: String): Any? {
@@ -42,7 +45,7 @@ class XmlResourceBundle internal constructor(internal val lookup: Map<String, An
} }
operator fun plus(other: XmlResourceBundle): XmlResourceBundle { operator fun plus(other: XmlResourceBundle): XmlResourceBundle {
return XmlResourceBundle(lookup + other.lookup) return XmlResourceBundle(ConcurrentHashMap(lookup + other.lookup))
} }
fun getStringA(key: String): String { fun getStringA(key: String): String {
@@ -61,6 +64,10 @@ class XmlResourceBundle internal constructor(internal val lookup: Map<String, An
if (index < 0) { if (index < 0) {
stringBuilder.append(string) stringBuilder.append(string)
break break
} else if (string[(index - 1).coerceAtLeast(0)] == '\\') {
stringBuilder.append(string.substring(0, (index - 1).coerceAtLeast(0)))
stringBuilder.append('%')
string = string.substring((index + 1).coerceAtMost(string.length))
} else { } else {
stringBuilder.append(string.substring(0, index)) stringBuilder.append(string.substring(0, index))
val stringConfig = string.substring(index, index + 4) val stringConfig = string.substring(index, index + 4)
@@ -86,7 +93,7 @@ class XmlResourceBundle internal constructor(internal val lookup: Map<String, An
} }
} }
stringBuilder.append(item) stringBuilder.append(item)
string = string.substring((index + 4).coerceAtMost(string.length), string.length) string = string.substring((index + 4).coerceAtMost(string.length))
} }
} }
return stringBuilder.toString() return stringBuilder.toString()

View File

@@ -26,7 +26,7 @@ class XmlResourceBundleTest {
@Test @Test
fun `test each language parameters`() { fun `test each language parameters`() {
rootBundle.lookup.entries.forEach { (key, value) -> rootBundle.lookup.entries.forEach { (key, value) ->
if (value !is String || !value.contains('%')) return@forEach if (value !is String || !value.contains("[^\\\\]?%\\d".toRegex())) return@forEach
val testValues: Array<Any> = value.split('%').drop(1).map { val testValues: Array<Any> = value.split('%').drop(1).map {
when (val char = it[2]) { when (val char = it[2]) {
's' -> "Test string" 's' -> "Test string"