/** * 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; }
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()]); }