ProguardMappingReader.kt
TLDR
This file contains the implementation of the ProguardMappingReader
class, which is responsible for reading and parsing ProGuard mapping files.
Methods
readProguardMapping
Reads the ProGuard mapping file and returns a ProguardMapping
object containing the parsed mapping information.
Classes
ProguardMappingReader
This class is responsible for reading and parsing ProGuard mapping files. It has the following methods:
-
readProguardMapping
: Reads the ProGuard mapping file and returns aProguardMapping
object containing the parsed mapping information.
That's it! There are no further classes or methods in this file.
package shark
import java.io.FileNotFoundException
import java.io.IOException
import java.io.InputStream
import java.text.ParseException
class ProguardMappingReader(
private val proguardMappingInputStream: InputStream
) {
@Throws(FileNotFoundException::class, IOException::class, ParseException::class)
fun readProguardMapping(): ProguardMapping {
val proguardMapping = ProguardMapping()
proguardMappingInputStream.bufferedReader(Charsets.UTF_8).use { bufferedReader ->
var currentClassName: String? = null
while (true) {
val line = bufferedReader.readLine()?.trim() ?: break
if (line.isEmpty() || line.startsWith(HASH_SYMBOL)) {
// empty line or comment
continue
}
if (line.endsWith(COLON_SYMBOL)) {
currentClassName = parseClassMapping(line, proguardMapping)
} else if (currentClassName != null) {
val isMethodMapping = line.contains(OPENING_PAREN_SYMBOL)
if (!isMethodMapping) {
parseClassField(line, currentClassName, proguardMapping)
}
}
}
}
return proguardMapping
}
// classes are stored as "clearName -> obfuscatedName:"
private fun parseClassMapping(
line: String,
proguardMapping: ProguardMapping
): String? {
val arrowPosition = line.indexOf(ARROW_SYMBOL)
if (arrowPosition == -1) {
return null
}
val colonPosition = line.indexOf(COLON_SYMBOL, arrowPosition + ARROW_SYMBOL.length)
if (colonPosition == -1) {
return null
}
val clearClassName = line.substring(0, arrowPosition).trim()
val obfuscatedClassName =
line.substring(arrowPosition + ARROW_SYMBOL.length, colonPosition).trim()
proguardMapping.addMapping(obfuscatedClassName, clearClassName)
return obfuscatedClassName
}
// fields are stored as "typeName clearFieldName -> obfuscatedFieldName"
private fun parseClassField(
line: String,
currentClassName: String,
proguardMapping: ProguardMapping
) {
val spacePosition = line.indexOf(SPACE_SYMBOL)
if (spacePosition == -1) {
return
}
val arrowPosition = line.indexOf(ARROW_SYMBOL, spacePosition + SPACE_SYMBOL.length)
if (arrowPosition == -1) {
return
}
val clearFieldName = line.substring(spacePosition + SPACE_SYMBOL.length, arrowPosition).trim()
val obfuscatedFieldName = line.substring(arrowPosition + ARROW_SYMBOL.length).trim()
proguardMapping.addMapping("$currentClassName.$obfuscatedFieldName", clearFieldName)
}
companion object {
private const val HASH_SYMBOL = "#"
private const val ARROW_SYMBOL = "->"
private const val COLON_SYMBOL = ":"
private const val SPACE_SYMBOL = " "
private const val OPENING_PAREN_SYMBOL = "("
}
}