Example #1
0
  /**
   * Re-reads the contents of the .plist file and updates the cached data.
   *
   * @throws IOException if there is an I/O error, or the data in the plist is invalid.
   */
  protected void refresh() throws IOException {
    long fileLength = file.length();
    if (fileLength > Integer.MAX_VALUE)
      throw new ArrayIndexOutOfBoundsException(
          "Info.plist is " + "unreasonably large and doesn't fit in memory.");

    byte[] plistData = new byte[(int) fileLength];
    int bytesRead = file.read(plistData);
    if (bytesRead != fileLength)
      throw new IOException(
          "Failed to read entire file. Read " + bytesRead + "/" + fileLength + " bytes.");

    XmlPlist plist = new XmlPlist(plistData, true);
    PlistNode dictNode = plist.getRootNode().cd("dict");
    if (dictNode == null) {
      throw new IOException("Malformed Info.plist file: No 'dict' " + "element at root.");
    }

    final String cfBundleInfoDictionaryVersionKey = "CFBundleInfoDictionaryVersion";
    final String bandSizeKey = "band-size";
    final String bundleBackingstoreVersionKey = "bundle-backingstore-version";
    final String diskImageBundleTypeKey = "diskimage-bundle-type";
    final String sizeKey = "size";

    Reader cfBundleInfoDictionaryVersionReader =
        dictNode.getKeyValue(cfBundleInfoDictionaryVersionKey);
    Reader bandSizeReader = dictNode.getKeyValue(bandSizeKey);
    Reader bundleBackingstoreVersionReader = dictNode.getKeyValue(bundleBackingstoreVersionKey);
    Reader diskImageBundleTypeReader = dictNode.getKeyValue(diskImageBundleTypeKey);
    Reader sizeReader = dictNode.getKeyValue(sizeKey);

    if (cfBundleInfoDictionaryVersionReader == null)
      throw new IOException(
          "Could not find '" + cfBundleInfoDictionaryVersionKey + "' key in Info.plist " + "file.");
    if (bandSizeReader == null)
      throw new IOException("Could not find '" + bandSizeKey + "' key " + "in Info.plist file.");
    if (bundleBackingstoreVersionReader == null)
      throw new IOException(
          "Could not find '" + bundleBackingstoreVersionKey + "' key in Info.plist file.");
    if (diskImageBundleTypeReader == null)
      throw new IOException(
          "Could not find '" + diskImageBundleTypeKey + "' key in Info.plist file.");
    if (sizeReader == null)
      throw new IOException("Could not find '" + sizeKey + "' key in " + "Info.plist file.");

    // We ignore the value of the dictionary version.
    // String cfBundleInfoDictionaryVersionString =
    //        Util.readFully(cfBundleInfoDictionaryVersionReader);
    String bandSizeString = Util.readFully(bandSizeReader);
    String bundleBackingstoreVersionString = Util.readFully(bundleBackingstoreVersionReader);
    String diskImageBundleTypeString = Util.readFully(diskImageBundleTypeReader);
    String sizeString = Util.readFully(sizeReader);

    if (!diskImageBundleTypeString.equals("com.apple.diskimage.sparsebundle")) {
      throw new IOException(
          "Unexpected value for '" + diskImageBundleTypeKey + "': " + diskImageBundleTypeString);
    }

    if (!bundleBackingstoreVersionString.equals("1")) {
      throw new IOException("Unknown backing store version: " + bundleBackingstoreVersionString);
    }

    final long bandSizeLong;
    try {
      bandSizeLong = Long.parseLong(bandSizeString);
    } catch (NumberFormatException nfe) {
      throw new IOException("Illegal numeric value for " + bandSizeKey + ": " + bandSizeString);
    }

    final long sizeLong;
    try {
      sizeLong = Long.parseLong(sizeString);
    } catch (NumberFormatException nfe) {
      throw new IOException("Illegal numeric value for " + sizeKey + ": " + sizeString);
    }

    this.bandSize = bandSizeLong;
    this.size = sizeLong;
  }
Example #2
0
  public PlistPartition[] getPartitions() throws IOException {
    LinkedList<PlistPartition> partitionList = new LinkedList<PlistPartition>();
    PlistNode current = getRootNode();
    current = current.cd("dict");
    current = current.cdkey("resource-fork");
    current = current.cdkey("blkx");

    // Variables to keep track of the pointers of the previous partition
    long previousOutOffset = 0;
    long previousInOffset = 0;

    // Iterate over the partitions and gather data
    for (PlistNode pn : current.getChildren()) {
      String partitionName = Util.readFully(pn.getKeyValue("Name"));
      String partitionID = Util.readFully(pn.getKeyValue("ID"));
      String partitionAttributes = Util.readFully(pn.getKeyValue("Attributes"));
      // System.err.println("Retrieving data...");
      // (new BufferedReader(new InputStreamReader(System.in))).readLine();
      Reader base64Data = pn.getKeyValue("Data");
      // System.gc();
      // System.err.println("Converting data to binary form... free memory: " +
      // Runtime.getRuntime().freeMemory() + " total memory: " +
      // Runtime.getRuntime().totalMemory());
      // byte[] data = Base64.decode(base64Data);

      //             try {
      //                 InputStream yo = new Base64.InputStream(new ReaderInputStream(base64Data,
      // Charset.forName("US-ASCII")));
      //                 String filename1 = "dump_plist_java-" + System.currentTimeMillis() +
      // ".datadpp";
      //                 System.err.println("Dumping output from ReaderInputStream to file \"" +
      // filename1 + "\"");
      //                 FileOutputStream fos = new FileOutputStream(filename1);
      //                 if(false) { // Standard way
      //                     byte[] buffer = new byte[4096];
      //                     int curBytesRead = yo.read(buffer);
      //                     while(curBytesRead == buffer.length) {
      //                         fos.write(buffer, 0, curBytesRead);
      //                         curBytesRead = yo.read(buffer);
      //                     }
      //                     if(curBytesRead > 0)
      //                         fos.write(buffer, 0, curBytesRead);
      //                 }
      //                 else { // Simulating PlistPartition constructor
      //                     byte[] buf1 = new byte[0xCC];
      //                     byte[] buf2 = new byte[0x28];
      //                     int curBytesRead = (int)yo.skip(0xCC); // SKIP OPERATION F***S UP!one
      //                     fos.write(buf1, 0, curBytesRead);
      //                     curBytesRead = yo.read(buf2);
      //                     while(curBytesRead == buf2.length) {
      //                         fos.write(buf2, 0, curBytesRead);
      //                         curBytesRead = yo.read(buf2);
      //                     }
      //                     if(curBytesRead > 0)
      //                         fos.write(buf2, 0, curBytesRead);

      //                 }
      //                 fos.close();
      //             } catch(Exception e) { e.printStackTrace(); }

      InputStream base64DataInputStream =
          new Base64.InputStream(new ReaderInputStream(base64Data, Charset.forName("US-ASCII")));

      // System.err.println("Creating PlistPartition.");
      // System.out.println("Block list for partition " + i++ + ":");
      PlistPartition dpp =
          new PlistPartition(
              partitionName,
              partitionID,
              partitionAttributes,
              base64DataInputStream,
              previousOutOffset,
              previousInOffset);
      previousOutOffset = dpp.getFinalOutOffset();
      previousInOffset = dpp.getFinalInOffset();
      partitionList.addLast(dpp);
    }

    return partitionList.toArray(new PlistPartition[partitionList.size()]);
  }