Allow file constructed JarMap getOutputStream

This commit is contained in:
topjohnwu 2018-06-12 02:57:46 +08:00
parent 3f83919e09
commit 6db27c7758

View File

@ -24,10 +24,11 @@ import java.util.zip.ZipFile;
* */ * */
public class JarMap implements Closeable, AutoCloseable { public class JarMap implements Closeable, AutoCloseable {
private JarFile jarFile; private JarFile jarFile;
private JarInputStream jis; private JarInputStream jis;
private boolean isInputStream = false;
private LinkedHashMap<String, JarEntry> bufMap; private LinkedHashMap<String, JarEntry> bufMap;
private Manifest manifest;
public JarMap(File file) throws IOException { public JarMap(File file) throws IOException {
this(file, true); this(file, true);
@ -39,6 +40,7 @@ public class JarMap implements Closeable, AutoCloseable {
public JarMap(File file, boolean verify, int mode) throws IOException { public JarMap(File file, boolean verify, int mode) throws IOException {
jarFile = new JarFile(file, verify, mode); jarFile = new JarFile(file, verify, mode);
manifest = jarFile.getManifest();
} }
public JarMap(String name) throws IOException { public JarMap(String name) throws IOException {
@ -54,48 +56,54 @@ public class JarMap implements Closeable, AutoCloseable {
} }
public JarMap(InputStream is, boolean verify) throws IOException { public JarMap(InputStream is, boolean verify) throws IOException {
isInputStream = true;
bufMap = new LinkedHashMap<>();
jis = new JarInputStream(is, verify); jis = new JarInputStream(is, verify);
bufMap = new LinkedHashMap<>();
JarEntry entry; JarEntry entry;
while ((entry = jis.getNextJarEntry()) != null) { while ((entry = jis.getNextJarEntry()) != null) {
bufMap.put(entry.getName(), new JarMapEntry(entry, jis)); bufMap.put(entry.getName(), new JarMapEntry(entry, jis));
} }
manifest = jis.getManifest();
} }
public File getFile() { public File getFile() {
return isInputStream ? null : new File(jarFile.getName()); return jarFile == null ? null : new File(jarFile.getName());
} }
public Manifest getManifest() throws IOException { public Manifest getManifest() {
return isInputStream ? jis.getManifest() : jarFile.getManifest(); return manifest;
} }
public InputStream getInputStream(ZipEntry ze) throws IOException { public InputStream getInputStream(ZipEntry ze) throws IOException {
return isInputStream ? ((JarMapEntry) bufMap.get(ze.getName())).data.getInputStream() : if (bufMap != null) {
jarFile.getInputStream(ze); JarMapEntry e = (JarMapEntry) bufMap.get(ze.getName());
if (e != null)
return e.data.getInputStream();
}
return jarFile.getInputStream(ze);
} }
public OutputStream getOutputStream(ZipEntry ze) { public OutputStream getOutputStream(ZipEntry ze) {
if (!isInputStream) // Only support InputStream mode manifest = null; /* Invalidate the manifest */
return null; if (bufMap == null)
ByteArrayStream bs = ((JarMapEntry) bufMap.get(ze.getName())).data; bufMap = new LinkedHashMap<>();
bs.reset(); JarMapEntry e = new JarMapEntry(ze.getName());
return bs; bufMap.put(ze.getName(), e);
return e.data;
} }
public byte[] getRawData(ZipEntry ze) throws IOException { public byte[] getRawData(ZipEntry ze) throws IOException {
if (isInputStream) { if (bufMap != null) {
return ((JarMapEntry) bufMap.get(ze.getName())).data.toByteArray(); JarMapEntry e = (JarMapEntry) bufMap.get(ze.getName());
} else { if (e != null)
ByteArrayStream bytes = new ByteArrayStream(); return e.data.toByteArray();
bytes.readFrom(jarFile.getInputStream(ze));
return bytes.toByteArray();
} }
ByteArrayStream bytes = new ByteArrayStream();
bytes.readFrom(jarFile.getInputStream(ze));
return bytes.toByteArray();
} }
public Enumeration<JarEntry> entries() { public Enumeration<JarEntry> entries() {
return isInputStream ? Collections.enumeration(bufMap.values()) : jarFile.entries(); return jarFile == null ? Collections.enumeration(bufMap.values()) : jarFile.entries();
} }
public ZipEntry getEntry(String name) { public ZipEntry getEntry(String name) {
@ -103,20 +111,29 @@ public class JarMap implements Closeable, AutoCloseable {
} }
public JarEntry getJarEntry(String name) { public JarEntry getJarEntry(String name) {
return isInputStream ? bufMap.get(name) : jarFile.getJarEntry(name); JarEntry e = jarFile == null ? bufMap.get(name) : jarFile.getJarEntry(name);
if (e == null && bufMap != null)
return bufMap.get(name);
return e;
} }
@Override @Override
public void close() throws IOException { public void close() throws IOException {
(isInputStream ? jis : jarFile).close(); (jarFile == null ? jis : jarFile).close();
} }
private static class JarMapEntry extends JarEntry { private static class JarMapEntry extends JarEntry {
ByteArrayStream data; ByteArrayStream data;
JarMapEntry(JarEntry je, InputStream is) { JarMapEntry(JarEntry je, InputStream is) {
super(je); super(je);
data = new ByteArrayStream(); data = new ByteArrayStream();
data.readFrom(is); data.readFrom(is);
} }
JarMapEntry(String s) {
super(s);
data = new ByteArrayStream();
}
} }
} }