/* ** 2014 September 25 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. */ package info.ata4.junity.bundle; import info.ata4.io.DataReader; import info.ata4.io.DataReaders; import info.ata4.io.buffer.ByteBufferChannel; import info.ata4.io.buffer.ByteBufferOutputStream; import java.io.IOException; import java.io.InputStream; import java.nio.ByteBuffer; import java.nio.channels.SeekableByteChannel; import java.nio.charset.Charset; import java.nio.file.Files; import java.nio.file.Path; import static java.nio.file.StandardCopyOption.*; import static java.nio.file.StandardOpenOption.*; import org.apache.commons.io.IOUtils; /** * Asset bundle file utility class. * * @author Nico Bergemann <barracuda415 at yahoo.de> */ public class BundleUtils { private static final Charset PROP_CHARSET = Charset.forName("US-ASCII"); private BundleUtils() { } public static boolean isBundle(Path file) { if (!Files.isRegularFile(file)) { return false; } try (InputStream is = Files.newInputStream(file)) { byte[] header = new byte[8]; is.read(header); String headerString = new String(header, PROP_CHARSET); return headerString.equals(BundleHeader.SIGNATURE_WEB) || headerString.equals(BundleHeader.SIGNATURE_RAW); } catch (IOException ex) { return false; } } public static SeekableByteChannel byteChannelForEntry(BundleEntry entry) throws IOException { SeekableByteChannel chan; // check if the entry is larger than 128 MiB long size = entry.size(); if (size > 1 << 27) { // copy entry to temporary file Path tmpFile = Files.createTempFile("disunity", null); Files.copy(entry.inputStream(), tmpFile, REPLACE_EXISTING); chan = Files.newByteChannel(tmpFile, READ, DELETE_ON_CLOSE); } else { // copy entry to memory ByteBuffer bb = ByteBuffer.allocateDirect((int) size); IOUtils.copy(entry.inputStream(), new ByteBufferOutputStream(bb)); bb.flip(); chan = new ByteBufferChannel(bb); } return chan; } public static DataReader dataReaderForEntry(BundleEntry entry) throws IOException { return DataReaders.forSeekableByteChannel(BundleUtils.byteChannelForEntry(entry)); } }