package com.technofovea.hllib; import com.sun.jna.Memory; import com.sun.jna.Pointer; import com.technofovea.hllib.enums.DirectoryItemType; import com.technofovea.hllib.masks.FileMode; import com.technofovea.hllib.methods.ManagedLibrary; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.util.ArrayList; import java.util.List; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * * @author Darien Hager */ public class DirectoryItem { static final int COPY_BUFFER_LEN = 4192; private static final Logger logger = LoggerFactory.getLogger(DirectoryItem.class); Pointer pointer = null; HlPackage parentPackage = null; DirectoryItem(HlPackage parent, Pointer p) { pointer = p; parentPackage = parent; } public Pointer getPointer() { return pointer; } public HlPackage getParentPackage() { return parentPackage; } public boolean isClosed() { return (parentPackage.isClosed()); } @Override public boolean equals(Object obj) { if (!(obj instanceof DirectoryItem)) { return false; } DirectoryItem other = (DirectoryItem) obj; if (!parentPackage.equals(other.parentPackage)) { return false; } if (!pointer.equals(other.pointer)) { return false; } return true; } @Override public int hashCode() { return pointer.hashCode() + parentPackage.hashCode(); } public List<DirectoryItem> getChildren() { ManagedLibrary lib = HlLib.getLibrary(); List<DirectoryItem> children = new ArrayList<DirectoryItem>(); if (isFolder()) { for (int i = 0; i < HlLib.getLibrary().folderGetCount(this); i++) { DirectoryItem child = lib.folderGetItem(this, i); children.add(child); } } return children; } public boolean isFile() { return (HlLib.getLibrary().itemGetType(this) == DirectoryItemType.FILE); } public boolean isFolder() { return (HlLib.getLibrary().itemGetType(this) == DirectoryItemType.FOLDER); } public String getName() { return (HlLib.getLibrary().itemGetName(this)); } public String getPath() { return (HlLib.getLibrary().itemGetPath(this)); } public Memory getData() { logger.debug("Getting data to memory for file {}", this.getName()); if (!isFile()) { return null; } ManagedLibrary lib = HlLib.getLibrary(); long actual_size = lib.itemGetSizeEx(this); HlStream stream = lib.fileCreateStream(this); try { FileMode streamMode = new FileMode(); streamMode.set(FileMode.INDEX_MODE_READ); lib.streamOpen(stream, streamMode); Memory m = new Memory(actual_size); // Stream only works in smaller int-sized increments, so we need // multiple calls. long remaining = m.getSize(); while (remaining > 0) { int chunk = (int) Math.min(Integer.MAX_VALUE, remaining); int numRead = lib.streamRead(stream, m, chunk); if (numRead < 0) { logger.error("Stream reading result was unexpectedly {} when getting data for DirectoryItem", numRead); break; } remaining -= numRead; } return m; } finally { lib.streamClose(stream); } } public void extractToFile(File target) throws IOException { logger.debug("Extracting data to filesystem for file {}, dest: {}", this.getPath(), target.getAbsolutePath()); if (!isFile()) { throw new IOException("This DirectoryItem is not a file."); } ManagedLibrary lib = HlLib.getLibrary(); long actual_size = lib.itemGetSizeEx(this); HlStream stream = lib.fileCreateStream(this); try { FileMode streamMode = new FileMode(); streamMode.set(FileMode.INDEX_MODE_READ); lib.streamOpen(stream, streamMode); FileOutputStream fos = new FileOutputStream(target, false); try { Memory buffer = new Memory(COPY_BUFFER_LEN); while (true) { int numRead = lib.streamRead(stream, buffer, (int) buffer.getSize()); if (numRead <= 0) { break; } fos.write(buffer.getByteArray(0, numRead)); } } finally { fos.close(); } } finally { lib.streamClose(stream); } } }