mirror of
https://github.com/revanced/Apktool.git
synced 2024-12-05 02:22:55 +01:00
StringBlock, AXmlResourceParser: reformat.
This commit is contained in:
parent
4ced4222f9
commit
20817df69f
File diff suppressed because it is too large
Load Diff
@ -1,242 +1,242 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010 Ryszard Wiśniewski <brut.alll@gmail.com>.
|
* Copyright 2010 Ryszard Wiśniewski <brut.alll@gmail.com>.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
* under the License.
|
* under the License.
|
||||||
*/
|
*/
|
||||||
package brut.androlib.res.decoder;
|
package brut.androlib.res.decoder;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Ryszard Wiśniewski <brut.alll@gmail.com>
|
* @author Ryszard Wiśniewski <brut.alll@gmail.com>
|
||||||
* @author Dmitry Skiba
|
* @author Dmitry Skiba
|
||||||
*
|
*
|
||||||
* Block of strings, used in binary xml and arsc.
|
* Block of strings, used in binary xml and arsc.
|
||||||
*
|
*
|
||||||
* TODO:
|
* TODO:
|
||||||
* - implement get()
|
* - implement get()
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class StringBlock {
|
public class StringBlock {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reads whole (including chunk type) string block from stream.
|
* Reads whole (including chunk type) string block from stream.
|
||||||
* Stream must be at the chunk type.
|
* Stream must be at the chunk type.
|
||||||
*/
|
*/
|
||||||
public static StringBlock read(IntReader reader) throws IOException {
|
public static StringBlock read(IntReader reader) throws IOException {
|
||||||
ChunkUtil.readCheckType(reader, CHUNK_TYPE);
|
ChunkUtil.readCheckType(reader, CHUNK_TYPE);
|
||||||
int chunkSize = reader.readInt();
|
int chunkSize = reader.readInt();
|
||||||
int stringCount = reader.readInt();
|
int stringCount = reader.readInt();
|
||||||
int styleOffsetCount = reader.readInt();
|
int styleOffsetCount = reader.readInt();
|
||||||
/*?*/ reader.readInt();
|
/*?*/ reader.readInt();
|
||||||
int stringsOffset = reader.readInt();
|
int stringsOffset = reader.readInt();
|
||||||
int stylesOffset = reader.readInt();
|
int stylesOffset = reader.readInt();
|
||||||
|
|
||||||
StringBlock block = new StringBlock();
|
StringBlock block = new StringBlock();
|
||||||
block.m_stringOffsets = reader.readIntArray(stringCount);
|
block.m_stringOffsets = reader.readIntArray(stringCount);
|
||||||
if (styleOffsetCount != 0) {
|
if (styleOffsetCount != 0) {
|
||||||
block.m_styleOffsets = reader.readIntArray(styleOffsetCount);
|
block.m_styleOffsets = reader.readIntArray(styleOffsetCount);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
int size = ((stylesOffset == 0) ? chunkSize : stylesOffset) - stringsOffset;
|
int size = ((stylesOffset == 0) ? chunkSize : stylesOffset) - stringsOffset;
|
||||||
if ((size % 4) != 0) {
|
if ((size % 4) != 0) {
|
||||||
throw new IOException("String data size is not multiple of 4 (" + size + ").");
|
throw new IOException("String data size is not multiple of 4 (" + size + ").");
|
||||||
}
|
}
|
||||||
block.m_strings = reader.readIntArray(size / 4);
|
block.m_strings = reader.readIntArray(size / 4);
|
||||||
}
|
}
|
||||||
if (stylesOffset != 0) {
|
if (stylesOffset != 0) {
|
||||||
int size = (chunkSize - stylesOffset);
|
int size = (chunkSize - stylesOffset);
|
||||||
if ((size % 4) != 0) {
|
if ((size % 4) != 0) {
|
||||||
throw new IOException("Style data size is not multiple of 4 (" + size + ").");
|
throw new IOException("Style data size is not multiple of 4 (" + size + ").");
|
||||||
}
|
}
|
||||||
block.m_styles = reader.readIntArray(size / 4);
|
block.m_styles = reader.readIntArray(size / 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
return block;
|
return block;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns number of strings in block.
|
* Returns number of strings in block.
|
||||||
*/
|
*/
|
||||||
public int getCount() {
|
public int getCount() {
|
||||||
return m_stringOffsets != null
|
return m_stringOffsets != null
|
||||||
? m_stringOffsets.length
|
? m_stringOffsets.length
|
||||||
: 0;
|
: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns raw string (without any styling information) at specified index.
|
* Returns raw string (without any styling information) at specified index.
|
||||||
*/
|
*/
|
||||||
public String getString(int index) {
|
public String getString(int index) {
|
||||||
if (index < 0
|
if (index < 0
|
||||||
|| m_stringOffsets == null
|
|| m_stringOffsets == null
|
||||||
|| index >= m_stringOffsets.length) {
|
|| index >= m_stringOffsets.length) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
int offset = m_stringOffsets[index];
|
int offset = m_stringOffsets[index];
|
||||||
int length = getShort(m_strings, offset);
|
int length = getShort(m_strings, offset);
|
||||||
StringBuilder result = new StringBuilder(length);
|
StringBuilder result = new StringBuilder(length);
|
||||||
for (; length != 0; length -= 1) {
|
for (; length != 0; length -= 1) {
|
||||||
offset += 2;
|
offset += 2;
|
||||||
result.append((char) getShort(m_strings, offset));
|
result.append((char) getShort(m_strings, offset));
|
||||||
}
|
}
|
||||||
return result.toString();
|
return result.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Not yet implemented.
|
* Not yet implemented.
|
||||||
*
|
*
|
||||||
* Returns string with style information (if any).
|
* Returns string with style information (if any).
|
||||||
*/
|
*/
|
||||||
public CharSequence get(int index) {
|
public CharSequence get(int index) {
|
||||||
return getString(index);
|
return getString(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns string with style tags (html-like).
|
* Returns string with style tags (html-like).
|
||||||
*/
|
*/
|
||||||
public String getHTML(int index) {
|
public String getHTML(int index) {
|
||||||
String raw = getString(index);
|
String raw = getString(index);
|
||||||
if (raw == null) {
|
if (raw == null) {
|
||||||
return raw;
|
return raw;
|
||||||
}
|
}
|
||||||
int[] style = getStyle(index);
|
int[] style = getStyle(index);
|
||||||
if (style == null) {
|
if (style == null) {
|
||||||
return raw;
|
return raw;
|
||||||
}
|
}
|
||||||
StringBuilder html = new StringBuilder(raw.length() + 32);
|
StringBuilder html = new StringBuilder(raw.length() + 32);
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
while (true) {
|
while (true) {
|
||||||
int i = -1;
|
int i = -1;
|
||||||
for (int j = 0; j != style.length; j += 3) {
|
for (int j = 0; j != style.length; j += 3) {
|
||||||
if (style[j + 1] == -1) {
|
if (style[j + 1] == -1) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (i == -1 || style[i + 1] > style[j + 1]) {
|
if (i == -1 || style[i + 1] > style[j + 1]) {
|
||||||
i = j;
|
i = j;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
int start = ((i != -1) ? style[i + 1] : raw.length());
|
int start = ((i != -1) ? style[i + 1] : raw.length());
|
||||||
for (int j = 0; j != style.length; j += 3) {
|
for (int j = 0; j != style.length; j += 3) {
|
||||||
int end = style[j + 2];
|
int end = style[j + 2];
|
||||||
if (end == -1 || end >= start) {
|
if (end == -1 || end >= start) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (offset <= end) {
|
if (offset <= end) {
|
||||||
html.append(raw, offset, end + 1);
|
html.append(raw, offset, end + 1);
|
||||||
offset = end + 1;
|
offset = end + 1;
|
||||||
}
|
}
|
||||||
style[j + 2] = -1;
|
style[j + 2] = -1;
|
||||||
html.append('<');
|
html.append('<');
|
||||||
html.append('/');
|
html.append('/');
|
||||||
html.append(getString(style[j]));
|
html.append(getString(style[j]));
|
||||||
html.append('>');
|
html.append('>');
|
||||||
}
|
}
|
||||||
if (offset < start) {
|
if (offset < start) {
|
||||||
html.append(raw, offset, start);
|
html.append(raw, offset, start);
|
||||||
offset = start;
|
offset = start;
|
||||||
}
|
}
|
||||||
if (i == -1) {
|
if (i == -1) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
html.append('<');
|
html.append('<');
|
||||||
html.append(getString(style[i]));
|
html.append(getString(style[i]));
|
||||||
html.append('>');
|
html.append('>');
|
||||||
style[i + 1] = -1;
|
style[i + 1] = -1;
|
||||||
}
|
}
|
||||||
return html.toString();
|
return html.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Finds index of the string.
|
* Finds index of the string.
|
||||||
* Returns -1 if the string was not found.
|
* Returns -1 if the string was not found.
|
||||||
*/
|
*/
|
||||||
public int find(String string) {
|
public int find(String string) {
|
||||||
if (string == null) {
|
if (string == null) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
for (int i = 0; i != m_stringOffsets.length; ++i) {
|
for (int i = 0; i != m_stringOffsets.length; ++i) {
|
||||||
int offset = m_stringOffsets[i];
|
int offset = m_stringOffsets[i];
|
||||||
int length = getShort(m_strings, offset);
|
int length = getShort(m_strings, offset);
|
||||||
if (length != string.length()) {
|
if (length != string.length()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
int j = 0;
|
int j = 0;
|
||||||
for (; j != length; ++j) {
|
for (; j != length; ++j) {
|
||||||
offset += 2;
|
offset += 2;
|
||||||
if (string.charAt(j) != getShort(m_strings, offset)) {
|
if (string.charAt(j) != getShort(m_strings, offset)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (j == length) {
|
if (j == length) {
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////// implementation
|
///////////////////////////////////////////// implementation
|
||||||
private StringBlock() {
|
private StringBlock() {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns style information - array of int triplets,
|
* Returns style information - array of int triplets,
|
||||||
* where in each triplet:
|
* where in each triplet:
|
||||||
* * first int is index of tag name ('b','i', etc.)
|
* * first int is index of tag name ('b','i', etc.)
|
||||||
* * second int is tag start index in string
|
* * second int is tag start index in string
|
||||||
* * third int is tag end index in string
|
* * third int is tag end index in string
|
||||||
*/
|
*/
|
||||||
private int[] getStyle(int index) {
|
private int[] getStyle(int index) {
|
||||||
if (m_styleOffsets == null || m_styles == null
|
if (m_styleOffsets == null || m_styles == null
|
||||||
|| index >= m_styleOffsets.length) {
|
|| index >= m_styleOffsets.length) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
int offset = m_styleOffsets[index] / 4;
|
int offset = m_styleOffsets[index] / 4;
|
||||||
int style[];
|
int style[];
|
||||||
{
|
{
|
||||||
int count = 0;
|
int count = 0;
|
||||||
for (int i = offset; i < m_styles.length; ++i) {
|
for (int i = offset; i < m_styles.length; ++i) {
|
||||||
if (m_styles[i] == -1) {
|
if (m_styles[i] == -1) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
count += 1;
|
count += 1;
|
||||||
}
|
}
|
||||||
if (count == 0 || (count % 3) != 0) {
|
if (count == 0 || (count % 3) != 0) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
style = new int[count];
|
style = new int[count];
|
||||||
}
|
}
|
||||||
for (int i = offset, j = 0; i < m_styles.length;) {
|
for (int i = offset, j = 0; i < m_styles.length;) {
|
||||||
if (m_styles[i] == -1) {
|
if (m_styles[i] == -1) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
style[j++] = m_styles[i++];
|
style[j++] = m_styles[i++];
|
||||||
}
|
}
|
||||||
return style;
|
return style;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final int getShort(int[] array, int offset) {
|
private static final int getShort(int[] array, int offset) {
|
||||||
int value = array[offset / 4];
|
int value = array[offset / 4];
|
||||||
if ((offset % 4) / 2 == 0) {
|
if ((offset % 4) / 2 == 0) {
|
||||||
return (value & 0xFFFF);
|
return (value & 0xFFFF);
|
||||||
} else {
|
} else {
|
||||||
return (value >>> 16);
|
return (value >>> 16);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private int[] m_stringOffsets;
|
private int[] m_stringOffsets;
|
||||||
private int[] m_strings;
|
private int[] m_strings;
|
||||||
private int[] m_styleOffsets;
|
private int[] m_styleOffsets;
|
||||||
private int[] m_styles;
|
private int[] m_styles;
|
||||||
private static final int CHUNK_TYPE = 0x001C0001;
|
private static final int CHUNK_TYPE = 0x001C0001;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user