Example #1
0
    private void buildIndex() throws IOException {
      int entryCount = get2ByteLittleEndian(zipDir, 0);

      // Add each of the files
      if (entryCount > 0) {
        directories = new HashMap<RelativeDirectory, DirectoryEntry>();
        ArrayList<Entry> entryList = new ArrayList<Entry>();
        int pos = 2;
        for (int i = 0; i < entryCount; i++) {
          pos = readEntry(pos, entryList, directories);
        }

        // Add the accumulated dirs into the same list
        for (RelativeDirectory d : directories.keySet()) {
          // use shared RelativeDirectory objects for parent dirs
          RelativeDirectory parent = getRelativeDirectory(d.dirname().getPath());
          String file = d.basename();
          Entry zipFileIndexEntry = new Entry(parent, file);
          zipFileIndexEntry.isDir = true;
          entryList.add(zipFileIndexEntry);
        }

        entries = entryList.toArray(new Entry[entryList.size()]);
        Arrays.sort(entries);
      } else {
        cleanupState();
      }
    }
Example #2
0
    private int readEntry(
        int pos, List<Entry> entryList, Map<RelativeDirectory, DirectoryEntry> directories)
        throws IOException {
      if (get4ByteLittleEndian(zipDir, pos) != 0x02014b50) {
        throw new ZipException("cannot read zip file entry");
      }

      int dirStart = pos + 46;
      int fileStart = dirStart;
      int fileEnd = fileStart + get2ByteLittleEndian(zipDir, pos + 28);

      if (zipFileIndex.symbolFilePrefixLength != 0
          && ((fileEnd - fileStart) >= symbolFilePrefixLength)) {
        dirStart += zipFileIndex.symbolFilePrefixLength;
        fileStart += zipFileIndex.symbolFilePrefixLength;
      }
      // Force any '\' to '/'. Keep the position of the last separator.
      for (int index = fileStart; index < fileEnd; index++) {
        byte nextByte = zipDir[index];
        if (nextByte == (byte) '\\') {
          zipDir[index] = (byte) '/';
          fileStart = index + 1;
        } else if (nextByte == (byte) '/') {
          fileStart = index + 1;
        }
      }

      RelativeDirectory directory = null;
      if (fileStart == dirStart) directory = getRelativeDirectory("");
      else if (lastDir != null && lastLen == fileStart - dirStart - 1) {
        int index = lastLen - 1;
        while (zipDir[lastStart + index] == zipDir[dirStart + index]) {
          if (index == 0) {
            directory = lastDir;
            break;
          }
          index--;
        }
      }

      // Sub directories
      if (directory == null) {
        lastStart = dirStart;
        lastLen = fileStart - dirStart - 1;

        directory = getRelativeDirectory(new String(zipDir, dirStart, lastLen, "UTF-8"));
        lastDir = directory;

        // Enter also all the parent directories
        RelativeDirectory tempDirectory = directory;

        while (directories.get(tempDirectory) == null) {
          directories.put(tempDirectory, new DirectoryEntry(tempDirectory, zipFileIndex));
          if (tempDirectory.path.indexOf("/") == tempDirectory.path.length() - 1) break;
          else {
            // use shared RelativeDirectory objects for parent dirs
            tempDirectory = getRelativeDirectory(tempDirectory.dirname().getPath());
          }
        }
      } else {
        if (directories.get(directory) == null) {
          directories.put(directory, new DirectoryEntry(directory, zipFileIndex));
        }
      }

      // For each dir create also a file
      if (fileStart != fileEnd) {
        Entry entry =
            new Entry(directory, new String(zipDir, fileStart, fileEnd - fileStart, "UTF-8"));

        entry.setNativeTime(get4ByteLittleEndian(zipDir, pos + 12));
        entry.compressedSize = get4ByteLittleEndian(zipDir, pos + 20);
        entry.size = get4ByteLittleEndian(zipDir, pos + 24);
        entry.offset = get4ByteLittleEndian(zipDir, pos + 42);
        entryList.add(entry);
      }

      return pos
          + 46
          + get2ByteLittleEndian(zipDir, pos + 28)
          + get2ByteLittleEndian(zipDir, pos + 30)
          + get2ByteLittleEndian(zipDir, pos + 32);
    }