mirror of
https://github.com/revanced/Apktool.git
synced 2024-12-04 18:12:54 +01:00
StringBlock, AXmlResourceParser: reformat.
This commit is contained in:
parent
843768aad0
commit
4ced4222f9
File diff suppressed because it is too large
Load Diff
@ -14,7 +14,6 @@
|
||||
* limitations under the License.
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package brut.androlib.res.decoder;
|
||||
|
||||
import java.io.IOException;
|
||||
@ -30,219 +29,214 @@ import java.io.IOException;
|
||||
*
|
||||
*/
|
||||
public class StringBlock {
|
||||
|
||||
/**
|
||||
* Reads whole (including chunk type) string block from stream.
|
||||
* Stream must be at the chunk type.
|
||||
*/
|
||||
public static StringBlock read(IntReader reader) throws IOException {
|
||||
ChunkUtil.readCheckType(reader,CHUNK_TYPE);
|
||||
int chunkSize=reader.readInt();
|
||||
int stringCount=reader.readInt();
|
||||
int styleOffsetCount=reader.readInt();
|
||||
/*?*/reader.readInt();
|
||||
int stringsOffset=reader.readInt();
|
||||
int stylesOffset=reader.readInt();
|
||||
|
||||
StringBlock block=new StringBlock();
|
||||
block.m_stringOffsets=reader.readIntArray(stringCount);
|
||||
if (styleOffsetCount!=0) {
|
||||
block.m_styleOffsets=reader.readIntArray(styleOffsetCount);
|
||||
}
|
||||
{
|
||||
int size=((stylesOffset==0)?chunkSize:stylesOffset)-stringsOffset;
|
||||
if ((size%4)!=0) {
|
||||
throw new IOException("String data size is not multiple of 4 ("+size+").");
|
||||
}
|
||||
block.m_strings=reader.readIntArray(size/4);
|
||||
}
|
||||
if (stylesOffset!=0) {
|
||||
int size=(chunkSize-stylesOffset);
|
||||
if ((size%4)!=0) {
|
||||
throw new IOException("Style data size is not multiple of 4 ("+size+").");
|
||||
}
|
||||
block.m_styles=reader.readIntArray(size/4);
|
||||
}
|
||||
|
||||
return block;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns number of strings in block.
|
||||
*/
|
||||
public int getCount() {
|
||||
return m_stringOffsets!=null?
|
||||
m_stringOffsets.length:
|
||||
0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns raw string (without any styling information) at specified index.
|
||||
*/
|
||||
public String getString(int index) {
|
||||
if (index<0 ||
|
||||
m_stringOffsets==null ||
|
||||
index>=m_stringOffsets.length)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
int offset=m_stringOffsets[index];
|
||||
int length=getShort(m_strings,offset);
|
||||
StringBuilder result=new StringBuilder(length);
|
||||
for (;length!=0;length-=1) {
|
||||
offset+=2;
|
||||
result.append((char)getShort(m_strings,offset));
|
||||
}
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Not yet implemented.
|
||||
*
|
||||
* Returns string with style information (if any).
|
||||
*/
|
||||
public CharSequence get(int index) {
|
||||
return getString(index);
|
||||
}
|
||||
/**
|
||||
* Reads whole (including chunk type) string block from stream.
|
||||
* Stream must be at the chunk type.
|
||||
*/
|
||||
public static StringBlock read(IntReader reader) throws IOException {
|
||||
ChunkUtil.readCheckType(reader, CHUNK_TYPE);
|
||||
int chunkSize = reader.readInt();
|
||||
int stringCount = reader.readInt();
|
||||
int styleOffsetCount = reader.readInt();
|
||||
/*?*/ reader.readInt();
|
||||
int stringsOffset = reader.readInt();
|
||||
int stylesOffset = reader.readInt();
|
||||
|
||||
/**
|
||||
* Returns string with style tags (html-like).
|
||||
*/
|
||||
public String getHTML(int index) {
|
||||
String raw=getString(index);
|
||||
if (raw==null) {
|
||||
return raw;
|
||||
}
|
||||
int[] style=getStyle(index);
|
||||
if (style==null) {
|
||||
return raw;
|
||||
}
|
||||
StringBuilder html=new StringBuilder(raw.length()+32);
|
||||
int offset=0;
|
||||
while (true) {
|
||||
int i=-1;
|
||||
for (int j=0;j!=style.length;j+=3) {
|
||||
if (style[j+1]==-1) {
|
||||
continue;
|
||||
}
|
||||
if (i==-1 || style[i+1]>style[j+1]) {
|
||||
i=j;
|
||||
}
|
||||
}
|
||||
int start=((i!=-1)?style[i+1]:raw.length());
|
||||
for (int j=0;j!=style.length;j+=3) {
|
||||
int end=style[j+2];
|
||||
if (end==-1 || end>=start) {
|
||||
continue;
|
||||
}
|
||||
if (offset<=end) {
|
||||
html.append(raw,offset,end+1);
|
||||
offset=end+1;
|
||||
}
|
||||
style[j+2]=-1;
|
||||
html.append('<');
|
||||
html.append('/');
|
||||
html.append(getString(style[j]));
|
||||
html.append('>');
|
||||
}
|
||||
if (offset<start) {
|
||||
html.append(raw,offset,start);
|
||||
offset=start;
|
||||
}
|
||||
if (i==-1) {
|
||||
break;
|
||||
}
|
||||
html.append('<');
|
||||
html.append(getString(style[i]));
|
||||
html.append('>');
|
||||
style[i+1]=-1;
|
||||
}
|
||||
return html.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds index of the string.
|
||||
* Returns -1 if the string was not found.
|
||||
*/
|
||||
public int find(String string) {
|
||||
if (string==null) {
|
||||
return -1;
|
||||
}
|
||||
for (int i=0;i!=m_stringOffsets.length;++i) {
|
||||
int offset=m_stringOffsets[i];
|
||||
int length=getShort(m_strings,offset);
|
||||
if (length!=string.length()) {
|
||||
continue;
|
||||
}
|
||||
int j=0;
|
||||
for (;j!=length;++j) {
|
||||
offset+=2;
|
||||
if (string.charAt(j)!=getShort(m_strings,offset)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (j==length) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////// implementation
|
||||
StringBlock block = new StringBlock();
|
||||
block.m_stringOffsets = reader.readIntArray(stringCount);
|
||||
if (styleOffsetCount != 0) {
|
||||
block.m_styleOffsets = reader.readIntArray(styleOffsetCount);
|
||||
}
|
||||
{
|
||||
int size = ((stylesOffset == 0) ? chunkSize : stylesOffset) - stringsOffset;
|
||||
if ((size % 4) != 0) {
|
||||
throw new IOException("String data size is not multiple of 4 (" + size + ").");
|
||||
}
|
||||
block.m_strings = reader.readIntArray(size / 4);
|
||||
}
|
||||
if (stylesOffset != 0) {
|
||||
int size = (chunkSize - stylesOffset);
|
||||
if ((size % 4) != 0) {
|
||||
throw new IOException("Style data size is not multiple of 4 (" + size + ").");
|
||||
}
|
||||
block.m_styles = reader.readIntArray(size / 4);
|
||||
}
|
||||
|
||||
private StringBlock() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns style information - array of int triplets,
|
||||
* where in each triplet:
|
||||
* * first int is index of tag name ('b','i', etc.)
|
||||
* * second int is tag start index in string
|
||||
* * third int is tag end index in string
|
||||
*/
|
||||
private int[] getStyle(int index) {
|
||||
if (m_styleOffsets==null || m_styles==null ||
|
||||
index>=m_styleOffsets.length)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
int offset=m_styleOffsets[index]/4;
|
||||
int style[];
|
||||
{
|
||||
int count=0;
|
||||
for (int i=offset;i<m_styles.length;++i) {
|
||||
if (m_styles[i]==-1) {
|
||||
break;
|
||||
}
|
||||
count+=1;
|
||||
}
|
||||
if (count==0 || (count%3)!=0) {
|
||||
return null;
|
||||
}
|
||||
style=new int[count];
|
||||
}
|
||||
for (int i=offset,j=0;i<m_styles.length;) {
|
||||
if (m_styles[i]==-1) {
|
||||
break;
|
||||
}
|
||||
style[j++]=m_styles[i++];
|
||||
}
|
||||
return style;
|
||||
}
|
||||
|
||||
private static final int getShort(int[] array,int offset) {
|
||||
int value=array[offset/4];
|
||||
if ((offset%4)/2==0) {
|
||||
return (value & 0xFFFF);
|
||||
} else {
|
||||
return (value >>> 16);
|
||||
}
|
||||
}
|
||||
|
||||
private int[] m_stringOffsets;
|
||||
private int[] m_strings;
|
||||
private int[] m_styleOffsets;
|
||||
private int[] m_styles;
|
||||
return block;
|
||||
}
|
||||
|
||||
private static final int CHUNK_TYPE=0x001C0001;
|
||||
/**
|
||||
* Returns number of strings in block.
|
||||
*/
|
||||
public int getCount() {
|
||||
return m_stringOffsets != null
|
||||
? m_stringOffsets.length
|
||||
: 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns raw string (without any styling information) at specified index.
|
||||
*/
|
||||
public String getString(int index) {
|
||||
if (index < 0
|
||||
|| m_stringOffsets == null
|
||||
|| index >= m_stringOffsets.length) {
|
||||
return null;
|
||||
}
|
||||
int offset = m_stringOffsets[index];
|
||||
int length = getShort(m_strings, offset);
|
||||
StringBuilder result = new StringBuilder(length);
|
||||
for (; length != 0; length -= 1) {
|
||||
offset += 2;
|
||||
result.append((char) getShort(m_strings, offset));
|
||||
}
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Not yet implemented.
|
||||
*
|
||||
* Returns string with style information (if any).
|
||||
*/
|
||||
public CharSequence get(int index) {
|
||||
return getString(index);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns string with style tags (html-like).
|
||||
*/
|
||||
public String getHTML(int index) {
|
||||
String raw = getString(index);
|
||||
if (raw == null) {
|
||||
return raw;
|
||||
}
|
||||
int[] style = getStyle(index);
|
||||
if (style == null) {
|
||||
return raw;
|
||||
}
|
||||
StringBuilder html = new StringBuilder(raw.length() + 32);
|
||||
int offset = 0;
|
||||
while (true) {
|
||||
int i = -1;
|
||||
for (int j = 0; j != style.length; j += 3) {
|
||||
if (style[j + 1] == -1) {
|
||||
continue;
|
||||
}
|
||||
if (i == -1 || style[i + 1] > style[j + 1]) {
|
||||
i = j;
|
||||
}
|
||||
}
|
||||
int start = ((i != -1) ? style[i + 1] : raw.length());
|
||||
for (int j = 0; j != style.length; j += 3) {
|
||||
int end = style[j + 2];
|
||||
if (end == -1 || end >= start) {
|
||||
continue;
|
||||
}
|
||||
if (offset <= end) {
|
||||
html.append(raw, offset, end + 1);
|
||||
offset = end + 1;
|
||||
}
|
||||
style[j + 2] = -1;
|
||||
html.append('<');
|
||||
html.append('/');
|
||||
html.append(getString(style[j]));
|
||||
html.append('>');
|
||||
}
|
||||
if (offset < start) {
|
||||
html.append(raw, offset, start);
|
||||
offset = start;
|
||||
}
|
||||
if (i == -1) {
|
||||
break;
|
||||
}
|
||||
html.append('<');
|
||||
html.append(getString(style[i]));
|
||||
html.append('>');
|
||||
style[i + 1] = -1;
|
||||
}
|
||||
return html.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds index of the string.
|
||||
* Returns -1 if the string was not found.
|
||||
*/
|
||||
public int find(String string) {
|
||||
if (string == null) {
|
||||
return -1;
|
||||
}
|
||||
for (int i = 0; i != m_stringOffsets.length; ++i) {
|
||||
int offset = m_stringOffsets[i];
|
||||
int length = getShort(m_strings, offset);
|
||||
if (length != string.length()) {
|
||||
continue;
|
||||
}
|
||||
int j = 0;
|
||||
for (; j != length; ++j) {
|
||||
offset += 2;
|
||||
if (string.charAt(j) != getShort(m_strings, offset)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (j == length) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////// implementation
|
||||
private StringBlock() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns style information - array of int triplets,
|
||||
* where in each triplet:
|
||||
* * first int is index of tag name ('b','i', etc.)
|
||||
* * second int is tag start index in string
|
||||
* * third int is tag end index in string
|
||||
*/
|
||||
private int[] getStyle(int index) {
|
||||
if (m_styleOffsets == null || m_styles == null
|
||||
|| index >= m_styleOffsets.length) {
|
||||
return null;
|
||||
}
|
||||
int offset = m_styleOffsets[index] / 4;
|
||||
int style[];
|
||||
{
|
||||
int count = 0;
|
||||
for (int i = offset; i < m_styles.length; ++i) {
|
||||
if (m_styles[i] == -1) {
|
||||
break;
|
||||
}
|
||||
count += 1;
|
||||
}
|
||||
if (count == 0 || (count % 3) != 0) {
|
||||
return null;
|
||||
}
|
||||
style = new int[count];
|
||||
}
|
||||
for (int i = offset, j = 0; i < m_styles.length;) {
|
||||
if (m_styles[i] == -1) {
|
||||
break;
|
||||
}
|
||||
style[j++] = m_styles[i++];
|
||||
}
|
||||
return style;
|
||||
}
|
||||
|
||||
private static final int getShort(int[] array, int offset) {
|
||||
int value = array[offset / 4];
|
||||
if ((offset % 4) / 2 == 0) {
|
||||
return (value & 0xFFFF);
|
||||
} else {
|
||||
return (value >>> 16);
|
||||
}
|
||||
}
|
||||
private int[] m_stringOffsets;
|
||||
private int[] m_strings;
|
||||
private int[] m_styleOffsets;
|
||||
private int[] m_styles;
|
||||
private static final int CHUNK_TYPE = 0x001C0001;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user