Example #1
0
  public static ARSCFile read(IntReader reader) throws IOException {
    ARSCFile arsc = new ARSCFile();
    ReadUtil.readCheckType(reader, ARSC_CHUNK_TYPE);
    /* size */ reader.readInt();
    int groupCount = reader.readInt();

    if (groupCount != 1) {
      throw new IOException("Only one package per file is supported.");
    }

    arsc.strings = StringBlock.read(reader);
    arsc.pkges = new Pkge[1];
    arsc.pkges[0] = readPackage(arsc, reader);

    return arsc;
  }
  private final void doNext() throws IOException {
    // Delayed initialization.
    if (m_strings == null) {
      ChunkUtil.readCheckType(m_reader, CHUNK_AXML_FILE);
      /* chunkSize */ m_reader.skipInt();
      m_strings = StringBlock.read(m_reader);
      m_namespaces.increaseDepth();
      m_operational = true;
    }

    if (m_event == END_DOCUMENT) {
      return;
    }

    int event = m_event;
    resetEventInfo();

    while (true) {
      if (m_decreaseDepth) {
        m_decreaseDepth = false;
        m_namespaces.decreaseDepth();
      }

      // Fake END_DOCUMENT event.
      if (event == END_TAG && m_namespaces.getDepth() == 1 && m_namespaces.getCurrentCount() == 0) {
        m_event = END_DOCUMENT;
        break;
      }

      int chunkType;
      if (event == START_DOCUMENT) {
        // Fake event, see CHUNK_XML_START_TAG handler.
        chunkType = CHUNK_XML_START_TAG;
      } else {
        chunkType = m_reader.readInt();
      }

      if (chunkType == CHUNK_RESOURCEIDS) {
        int chunkSize = m_reader.readInt();
        if (chunkSize < 8 || (chunkSize % 4) != 0) {
          throw new IOException("Invalid resource ids size (" + chunkSize + ").");
        }
        m_resourceIDs = m_reader.readIntArray(chunkSize / 4 - 2);
        continue;
      }

      if (chunkType < CHUNK_XML_FIRST || chunkType > CHUNK_XML_LAST) {
        throw new IOException("Invalid chunk type (" + chunkType + ").");
      }

      // Fake START_DOCUMENT event.
      if (chunkType == CHUNK_XML_START_TAG && event == -1) {
        m_event = START_DOCUMENT;
        break;
      }

      // Common header.
      /* chunkSize */ m_reader.skipInt();
      int lineNumber = m_reader.readInt();
      /* 0xFFFFFFFF */ m_reader.skipInt();

      if (chunkType == CHUNK_XML_START_NAMESPACE || chunkType == CHUNK_XML_END_NAMESPACE) {
        if (chunkType == CHUNK_XML_START_NAMESPACE) {
          int prefix = m_reader.readInt();
          int uri = m_reader.readInt();
          m_namespaces.push(prefix, uri);
        } else {
          /* prefix */ m_reader.skipInt();
          /* uri */ m_reader.skipInt();
          m_namespaces.pop();
        }
        continue;
      }

      m_lineNumber = lineNumber;

      if (chunkType == CHUNK_XML_START_TAG) {
        m_namespaceUri = m_reader.readInt();
        m_name = m_reader.readInt();
        /* flags? */ m_reader.skipInt();
        int attributeCount = m_reader.readInt();
        m_idAttribute = (attributeCount >>> 16) - 1;
        attributeCount &= 0xFFFF;
        m_classAttribute = m_reader.readInt();
        m_styleAttribute = (m_classAttribute >>> 16) - 1;
        m_classAttribute = (m_classAttribute & 0xFFFF) - 1;
        m_attributes = m_reader.readIntArray(attributeCount * ATTRIBUTE_LENGHT);
        for (int i = ATTRIBUTE_IX_VALUE_TYPE; i < m_attributes.length; ) {
          m_attributes[i] = (m_attributes[i] >>> 24);
          i += ATTRIBUTE_LENGHT;
        }
        m_namespaces.increaseDepth();
        m_event = START_TAG;
        break;
      }

      if (chunkType == CHUNK_XML_END_TAG) {
        m_namespaceUri = m_reader.readInt();
        m_name = m_reader.readInt();
        m_event = END_TAG;
        m_decreaseDepth = true;
        break;
      }

      if (chunkType == CHUNK_XML_TEXT) {
        m_name = m_reader.readInt();
        /* ? */ m_reader.skipInt();
        /* ? */ m_reader.skipInt();
        m_event = TEXT;
        break;
      }
    }
  }
Example #3
0
  private static Pkge readPackage(ARSCFile file, IntReader reader) throws IOException {
    Pkge pkge = new Pkge();
    pkge.file = file;

    ReadUtil.readCheckType(reader, PACKAGE_CHUNK_TYPE);
    /* size */ reader.skipInt();
    pkge.id = reader.readInt();
    {
      final int nameLength = 128;
      StringBuilder name = new StringBuilder(16);
      int i = 0;
      for (; i != nameLength; ) {
        ++i;
        int ch = reader.readShort();
        if (ch == 0) {
          break;
        }
        name.append((char) ch);
      }
      reader.skip((nameLength - i) * 2);
      reader.skip((nameLength * 2) % 4);
      pkge.name = name.toString();
    }

    /* signature? */ reader.skipInt();
    int assetCount = reader.readInt();
    /* idNamesOffset */ reader.skipInt();
    /* idNamesCount */ reader.skipInt();

    pkge.assetNames = StringBlock.read(reader);
    pkge.resourceNames = StringBlock.read(reader);
    pkge.assets = new Asset[assetCount];

    ArrayList contents = new ArrayList();
    int assetsRead = 0;
    Asset currentAsset = null;
    while (reader.available() != 0) {
      int chunkType = reader.readInt();
      if (chunkType != CONTENT_CHUNK_TYPE) {
        if (currentAsset != null) {
          currentAsset.contents = new Content[contents.size()];
          contents.toArray(currentAsset.contents);
          contents.clear();
        }
      }
      if (chunkType == ASSET_CHUNK_TYPE) {
        currentAsset = readAsset(reader, pkge);
        pkge.assets[assetsRead] = currentAsset;
        assetsRead += 1;
      } else if (chunkType == CONTENT_CHUNK_TYPE) {
        if (currentAsset == null) {
          throw new IOException("Invalid chunk sequence: content read before asset.");
        }
        contents.add(readContent(reader, currentAsset));
      } else {
        throw new IOException("Unexpected chunk type (" + chunkType + ").");
      }
    }
    if (currentAsset != null) {
      currentAsset.contents = new Content[contents.size()];
      contents.toArray(currentAsset.contents);
      contents.clear();
    }
    if (assetsRead != assetCount) {
      throw new IOException("Not all assets where read (" + (assetCount - assetsRead) + " left).");
    }
    return pkge;
  }