<lambda>null1 package shark
2
3 import java.io.FileNotFoundException
4 import java.io.IOException
5 import java.io.InputStream
6 import java.text.ParseException
7
8 class ProguardMappingReader(
9 private val proguardMappingInputStream: InputStream
10 ) {
11
12 @Throws(FileNotFoundException::class, IOException::class, ParseException::class)
13 fun readProguardMapping(): ProguardMapping {
14 val proguardMapping = ProguardMapping()
15 proguardMappingInputStream.bufferedReader(Charsets.UTF_8).use { bufferedReader ->
16
17 var currentClassName: String? = null
18 while (true) {
19 val line = bufferedReader.readLine()?.trim() ?: break
20
21 if (line.isEmpty() || line.startsWith(HASH_SYMBOL)) {
22 // empty line or comment
23 continue
24 }
25
26 if (line.endsWith(COLON_SYMBOL)) {
27 currentClassName = parseClassMapping(line, proguardMapping)
28 } else if (currentClassName != null) {
29 val isMethodMapping = line.contains(OPENING_PAREN_SYMBOL)
30 if (!isMethodMapping) {
31 parseClassField(line, currentClassName, proguardMapping)
32 }
33 }
34 }
35 }
36 return proguardMapping
37 }
38
39 // classes are stored as "clearName -> obfuscatedName:"
40 private fun parseClassMapping(
41 line: String,
42 proguardMapping: ProguardMapping
43 ): String? {
44 val arrowPosition = line.indexOf(ARROW_SYMBOL)
45 if (arrowPosition == -1) {
46 return null
47 }
48
49 val colonPosition = line.indexOf(COLON_SYMBOL, arrowPosition + ARROW_SYMBOL.length)
50 if (colonPosition == -1) {
51 return null
52 }
53
54 val clearClassName = line.substring(0, arrowPosition).trim()
55 val obfuscatedClassName =
56 line.substring(arrowPosition + ARROW_SYMBOL.length, colonPosition).trim()
57
58 proguardMapping.addMapping(obfuscatedClassName, clearClassName)
59
60 return obfuscatedClassName
61 }
62
63 // fields are stored as "typeName clearFieldName -> obfuscatedFieldName"
64 private fun parseClassField(
65 line: String,
66 currentClassName: String,
67 proguardMapping: ProguardMapping
68 ) {
69 val spacePosition = line.indexOf(SPACE_SYMBOL)
70 if (spacePosition == -1) {
71 return
72 }
73
74 val arrowPosition = line.indexOf(ARROW_SYMBOL, spacePosition + SPACE_SYMBOL.length)
75 if (arrowPosition == -1) {
76 return
77 }
78
79 val clearFieldName = line.substring(spacePosition + SPACE_SYMBOL.length, arrowPosition).trim()
80 val obfuscatedFieldName = line.substring(arrowPosition + ARROW_SYMBOL.length).trim()
81
82 proguardMapping.addMapping("$currentClassName.$obfuscatedFieldName", clearFieldName)
83 }
84
85 companion object {
86 private const val HASH_SYMBOL = "#"
87 private const val ARROW_SYMBOL = "->"
88 private const val COLON_SYMBOL = ":"
89 private const val SPACE_SYMBOL = " "
90 private const val OPENING_PAREN_SYMBOL = "("
91 }
92 }