Skip to content

Commit

Permalink
Process string styles of resources.arsc, refer to wequick#441
Browse files Browse the repository at this point in the history
  • Loading branch information
galenlin committed Mar 22, 2017
1 parent a2f8313 commit 9c80e3b
Showing 1 changed file with 119 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -157,12 +157,16 @@ public class AssetEditor extends CppHexEditor {
// Read styles
for (int i = 0; i < s.styleCount; i++) {
seek(start + s.styleOffsets[i])
s.styles[i] = readStringPoolSpan()
s.styles[i] = readStringStyle()
}

s.styleSize = tellp() - start

// Validate styles end span
s.styleEnd = readBytes(8)
assert (Arrays.equals(s.styleEnd, ResStringPoolSpan.END_SPAN))
def end = readBytes(8)
assert (Arrays.equals(end, ResStringPoolSpan.END_SPAN))

s.styleEnd = end

return s
}
Expand Down Expand Up @@ -194,8 +198,8 @@ public class AssetEditor extends CppHexEditor {
if (s.stringPadding > 0) writeBytes(new byte[s.stringPadding])

// Write styles
s.styles.eachWithIndex { it, i ->
writeStringPoolSpan(it)
s.styles.each {
writeStringStyle(it)
}
if (s.styleEnd != null) writeBytes(s.styleEnd)
}
Expand All @@ -213,22 +217,49 @@ public class AssetEditor extends CppHexEditor {
//
// }

/** Read array of ResStringPool_span */
protected def readStringStyle() {
def spans = []
while (true) {
def span = readStringPoolSpan()
if (span.name == ResStringPoolSpan.END) {
break
}
spans.add(span)
}
return spans;
}

/** Write array of ResStringPool_span */
protected def writeStringStyle(spans) {
spans.each {
writeStringPoolSpan(it)
}
writeInt(ResStringPoolSpan.END)
}

/** Read struct ResStringPool_span */
protected def readStringPoolSpan() {
def ss = [:]
ss.name = readInt()
if (ss.name == ResStringPoolSpan.END) {
return ss
}

ss.firstChar = readInt()
ss.lastChar = readInt()
skip(4) // END: 0xFFFFFFFF
return ss
}

/** Write struct ResStringPool_span */
protected def writeStringPoolSpan(ss) {
writeInt(ss.name)
if (ss.name == ResStringPoolSpan.END) {
return
}

writeInt(ss.firstChar)
writeInt(ss.lastChar)
writeInt(ResStringPoolSpan.END)
}

/** Get utf-8 from utf-16 */
Expand Down Expand Up @@ -323,6 +354,32 @@ public class AssetEditor extends CppHexEditor {
def offsets = []
def lens = []
def offset = 0
def stringCount = ids.size()
def entryDiff = 0

if (sp.styleCount > 0) {
// The styles indexes are related to the strings.
// As example:
//
// <xml>
// <string><b>Wequick</b><string>
// <string><i>Small</i><string>
// </xml>
//
// would be compiled to:
//
// String #0: Wequick
// String #1: Small
// ...
// String #M: b
// String #N: i
//
// Style #0: [name: M, firstChar: 0, lastChar: 6]
// Style #1: [name: N, firstChar: 0, lastChar: 4]
//
// Hereby, resort the strings ordered by the ids to make sense.
ids.sort()
}

// Filter strings
ids.each {
Expand All @@ -334,12 +391,62 @@ public class AssetEditor extends CppHexEditor {
def l = s.length
offset += l + lenData.length + 1 // 1 for 0x0
}
def newStringCount = strings.size()
def d = (sp.stringCount - newStringCount) * 4

// Filter styles
def styleSizeDiff = 0
if (sp.styleCount > 0) {
def styles = []
def styleOffsets = []
def styleOffset = 0

for (int i = 0; i < stringCount; i++) {
int id = ids[i]
if (id >= sp.styleCount) {
break
}

styleOffsets.add(styleOffset)
def spans = sp.styles[id]
spans.each {
if (it.name != ResStringPoolSpan.END) {
def newName = ids.indexOf(it.name)
if (newName == -1) {
// Append the style tag string
def s = sp.strings[it.name]
strings.add(s)
offsets.add(offset)
def lenData = sp.stringLens[it.name]
lens.add(lenData)
def l = s.length
offset += l + lenData.length + 1 // 1 for 0x0

it.name = stringCount
stringCount++
} else {
it.name = newName
}

styleOffset += 12 // SPAN_SIZE
}
}
styleOffset += 4 // END_SPAN
styles.add(spans)
}

def styleCount = styles.size()
entryDiff += sp.styleCount - styleCount
sp.styleCount = styleCount
sp.styles = styles
sp.styleOffsets = styleOffsets
styleSizeDiff = sp.styleSize - styleOffset
}

entryDiff += sp.stringCount - stringCount
def d = entryDiff * 4
sp.strings = strings
sp.stringOffsets = offsets
sp.stringLens = lens
sp.stringCount = strings.size()
sp.stringCount = stringCount

// Adjust strings start position
sp.stringsStart -= d
Expand All @@ -357,8 +464,9 @@ public class AssetEditor extends CppHexEditor {
sp.stringPadding = newStringPadding

// Adjust styles start position
if (sp.stylesStart > 0) {
if (sp.styleCount > 0) {
sp.stylesStart = sp.stringsStart + sp.stringsSize + sp.stringPadding
d += styleSizeDiff
}

// Adjust entry size
Expand Down

0 comments on commit 9c80e3b

Please sign in to comment.