コード例 #1
0
ファイル: ParseUtils.java プロジェクト: Bludge0n/apk-parser
  /**
   * read String pool, for apk binary xml file and resource table.
   *
   * @param in
   * @param stringPoolHeader
   * @return
   * @throws IOException
   */
  public static StringPool readStringPool(TellableInputStream in, StringPoolHeader stringPoolHeader)
      throws IOException {

    long beginPos = in.tell();
    long[] offsets = new long[(int) stringPoolHeader.stringCount];
    // read strings offset
    if (stringPoolHeader.stringCount > 0) {
      for (int idx = 0; idx < stringPoolHeader.stringCount; idx++) {
        offsets[idx] = in.readUInt();
      }
    }
    // read flag
    boolean sorted = (stringPoolHeader.flags & StringPoolHeader.SORTED_FLAG) != 0;
    StringEncoding stringEncoding =
        (stringPoolHeader.flags & StringPoolHeader.UTF8_FLAG) != 0
            ? StringEncoding.UTF8
            : StringEncoding.UTF16;

    // read strings. the head and metas have 28 bytes
    long stringPos = beginPos + stringPoolHeader.stringsStart - stringPoolHeader.headerSize;
    in.advanceIfNotRearch(stringPos);

    StringPoolEntry[] entries = new StringPoolEntry[offsets.length];
    for (int i = 0; i < offsets.length; i++) {
      entries[i] = new StringPoolEntry(i, stringPos + offsets[i]);
    }
    Arrays.sort(entries);

    String lastStr = null;
    long lastOffset = -1;
    StringPool stringPool = new StringPool((int) stringPoolHeader.stringCount);
    for (StringPoolEntry entry : entries) {
      if (entry.getOffset() == lastOffset) {
        stringPool.set(entry.getIdx(), lastStr);
        continue;
      }

      in.advanceIfNotRearch(entry.getOffset());
      lastOffset = entry.getOffset();
      String str = ParseUtils.readString(in, stringEncoding);
      lastStr = str;
      stringPool.set(entry.getIdx(), str);
    }

    // read styles
    if (stringPoolHeader.styleCount > 0) {
      // now we just skip it
    }

    in.advanceIfNotRearch(beginPos + stringPoolHeader.chunkSize - stringPoolHeader.headerSize);

    return stringPool;
  }