Cleanup (I/O ops in java-decompiler)
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2000-2015 JetBrains s.r.o.
|
* Copyright 2000-2016 JetBrains s.r.o.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -150,17 +150,11 @@ public class ConsoleDecompiler implements IBytecodeProvider, IResultSaver {
|
|||||||
return InterpreterUtil.getBytes(file);
|
return InterpreterUtil.getBytes(file);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ZipFile archive = new ZipFile(file);
|
try (ZipFile archive = new ZipFile(file)) {
|
||||||
try {
|
|
||||||
ZipEntry entry = archive.getEntry(internalPath);
|
ZipEntry entry = archive.getEntry(internalPath);
|
||||||
if (entry == null) {
|
if (entry == null) throw new IOException("Entry not found: " + internalPath);
|
||||||
throw new IOException("Entry not found: " + internalPath);
|
|
||||||
}
|
|
||||||
return InterpreterUtil.getBytes(archive, entry);
|
return InterpreterUtil.getBytes(archive, entry);
|
||||||
}
|
}
|
||||||
finally {
|
|
||||||
archive.close();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -193,15 +187,9 @@ public class ConsoleDecompiler implements IBytecodeProvider, IResultSaver {
|
|||||||
@Override
|
@Override
|
||||||
public void saveClassFile(String path, String qualifiedName, String entryName, String content, int[] mapping) {
|
public void saveClassFile(String path, String qualifiedName, String entryName, String content, int[] mapping) {
|
||||||
File file = new File(getAbsolutePath(path), entryName);
|
File file = new File(getAbsolutePath(path), entryName);
|
||||||
try {
|
try (Writer out = new OutputStreamWriter(new FileOutputStream(file), "UTF8")) {
|
||||||
Writer out = new OutputStreamWriter(new FileOutputStream(file), "UTF8");
|
|
||||||
try {
|
|
||||||
out.write(content);
|
out.write(content);
|
||||||
}
|
}
|
||||||
finally {
|
|
||||||
out.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (IOException ex) {
|
catch (IOException ex) {
|
||||||
DecompilerContext.getLogger().writeMessage("Cannot write class file " + file, ex);
|
DecompilerContext.getLogger().writeMessage("Cannot write class file " + file, ex);
|
||||||
}
|
}
|
||||||
@@ -238,21 +226,15 @@ public class ConsoleDecompiler implements IBytecodeProvider, IResultSaver {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try (ZipFile srcArchive = new ZipFile(new File(source))) {
|
||||||
ZipFile srcArchive = new ZipFile(new File(source));
|
|
||||||
try {
|
|
||||||
ZipEntry entry = srcArchive.getEntry(entryName);
|
ZipEntry entry = srcArchive.getEntry(entryName);
|
||||||
if (entry != null) {
|
if (entry != null) {
|
||||||
InputStream in = srcArchive.getInputStream(entry);
|
try (InputStream in = srcArchive.getInputStream(entry)) {
|
||||||
ZipOutputStream out = mapArchiveStreams.get(file);
|
ZipOutputStream out = mapArchiveStreams.get(file);
|
||||||
out.putNextEntry(new ZipEntry(entryName));
|
out.putNextEntry(new ZipEntry(entryName));
|
||||||
InterpreterUtil.copyStream(in, out);
|
InterpreterUtil.copyStream(in, out);
|
||||||
in.close();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
finally {
|
|
||||||
srcArchive.close();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
catch (IOException ex) {
|
catch (IOException ex) {
|
||||||
String message = "Cannot copy entry " + entryName + " from " + source + " to " + file;
|
String message = "Cannot copy entry " + entryName + " from " + source + " to " + file;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2000-2014 JetBrains s.r.o.
|
* Copyright 2000-2016 JetBrains s.r.o.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -78,13 +78,9 @@ public class ContextUnit {
|
|||||||
String oldName = cl.qualifiedName;
|
String oldName = cl.qualifiedName;
|
||||||
|
|
||||||
StructClass newCl;
|
StructClass newCl;
|
||||||
DataInputFullStream in = loader.getClassStream(oldName);
|
try (DataInputFullStream in = loader.getClassStream(oldName)) {
|
||||||
try {
|
|
||||||
newCl = new StructClass(in, cl.isOwn(), loader);
|
newCl = new StructClass(in, cl.isOwn(), loader);
|
||||||
}
|
}
|
||||||
finally {
|
|
||||||
in.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
lstClasses.add(newCl);
|
lstClasses.add(newCl);
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2000-2014 JetBrains s.r.o.
|
* Copyright 2000-2016 JetBrains s.r.o.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -119,18 +119,12 @@ public class StructContext {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (filename.endsWith(".class")) {
|
if (filename.endsWith(".class")) {
|
||||||
try {
|
try (DataInputFullStream in = loader.getClassStream(file.getAbsolutePath(), null)) {
|
||||||
DataInputFullStream in = loader.getClassStream(file.getAbsolutePath(), null);
|
|
||||||
try {
|
|
||||||
StructClass cl = new StructClass(in, isOwn, loader);
|
StructClass cl = new StructClass(in, isOwn, loader);
|
||||||
classes.put(cl.qualifiedName, cl);
|
classes.put(cl.qualifiedName, cl);
|
||||||
unit.addClass(cl, filename);
|
unit.addClass(cl, filename);
|
||||||
loader.addClassLink(cl.qualifiedName, new LazyLoader.Link(LazyLoader.Link.CLASS, file.getAbsolutePath(), null));
|
loader.addClassLink(cl.qualifiedName, new LazyLoader.Link(LazyLoader.Link.CLASS, file.getAbsolutePath(), null));
|
||||||
}
|
}
|
||||||
finally {
|
|
||||||
in.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (IOException ex) {
|
catch (IOException ex) {
|
||||||
String message = "Corrupted class file: " + file;
|
String message = "Corrupted class file: " + file;
|
||||||
DecompilerContext.getLogger().writeMessage(message, ex);
|
DecompilerContext.getLogger().writeMessage(message, ex);
|
||||||
@@ -143,10 +137,8 @@ public class StructContext {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void addArchive(String path, File file, int type, boolean isOwn) throws IOException {
|
private void addArchive(String path, File file, int type, boolean isOwn) throws IOException {
|
||||||
@SuppressWarnings("IOResourceOpenedButNotSafelyClosed")
|
//noinspection IOResourceOpenedButNotSafelyClosed
|
||||||
ZipFile archive = type == ContextUnit.TYPE_JAR ? new JarFile(file) : new ZipFile(file);
|
try (ZipFile archive = type == ContextUnit.TYPE_JAR ? new JarFile(file) : new ZipFile(file)) {
|
||||||
|
|
||||||
try {
|
|
||||||
Enumeration<? extends ZipEntry> entries = archive.entries();
|
Enumeration<? extends ZipEntry> entries = archive.entries();
|
||||||
while (entries.hasMoreElements()) {
|
while (entries.hasMoreElements()) {
|
||||||
ZipEntry entry = entries.nextElement();
|
ZipEntry entry = entries.nextElement();
|
||||||
@@ -178,9 +170,6 @@ public class StructContext {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
finally {
|
|
||||||
archive.close();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<String, StructClass> getClasses() {
|
public Map<String, StructClass> getClasses() {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2000-2014 JetBrains s.r.o.
|
* Copyright 2000-2016 JetBrains s.r.o.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -73,12 +73,12 @@ public class StructMember {
|
|||||||
|
|
||||||
protected StructGeneralAttribute readAttribute(DataInputFullStream in, ConstantPool pool, String name) throws IOException {
|
protected StructGeneralAttribute readAttribute(DataInputFullStream in, ConstantPool pool, String name) throws IOException {
|
||||||
StructGeneralAttribute attribute = StructGeneralAttribute.createAttribute(name);
|
StructGeneralAttribute attribute = StructGeneralAttribute.createAttribute(name);
|
||||||
|
int length = in.readInt();
|
||||||
if (attribute == null) {
|
if (attribute == null) {
|
||||||
in.discard(in.readInt());
|
in.discard(length);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
byte[] data = new byte[in.readInt()];
|
byte[] data = in.read(length);
|
||||||
in.readFull(data);
|
|
||||||
attribute.setInfo(data);
|
attribute.setInfo(data);
|
||||||
attribute.initContent(pool);
|
attribute.initContent(pool);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2000-2015 JetBrains s.r.o.
|
* Copyright 2000-2016 JetBrains s.r.o.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -47,17 +47,13 @@ public class LazyLoader {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public ConstantPool loadPool(String classname) {
|
public ConstantPool loadPool(String classname) {
|
||||||
try {
|
try (DataInputFullStream in = getClassStream(classname)) {
|
||||||
DataInputFullStream in = getClassStream(classname);
|
if (in != null) {
|
||||||
if (in == null) return null;
|
|
||||||
|
|
||||||
try {
|
|
||||||
in.discard(8);
|
in.discard(8);
|
||||||
return new ConstantPool(in);
|
return new ConstantPool(in);
|
||||||
}
|
}
|
||||||
finally {
|
|
||||||
in.close();
|
return null;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
catch (IOException ex) {
|
catch (IOException ex) {
|
||||||
throw new RuntimeException(ex);
|
throw new RuntimeException(ex);
|
||||||
@@ -67,11 +63,8 @@ public class LazyLoader {
|
|||||||
public byte[] loadBytecode(StructMethod mt, int codeFullLength) {
|
public byte[] loadBytecode(StructMethod mt, int codeFullLength) {
|
||||||
String className = mt.getClassStruct().qualifiedName;
|
String className = mt.getClassStruct().qualifiedName;
|
||||||
|
|
||||||
try {
|
try (DataInputFullStream in = getClassStream(className)) {
|
||||||
DataInputFullStream in = getClassStream(className);
|
if (in != null) {
|
||||||
if (in == null) return null;
|
|
||||||
|
|
||||||
try {
|
|
||||||
in.discard(8);
|
in.discard(8);
|
||||||
|
|
||||||
ConstantPool pool = mt.getClassStruct().getPool();
|
ConstantPool pool = mt.getClassStruct().getPool();
|
||||||
@@ -118,17 +111,13 @@ public class LazyLoader {
|
|||||||
}
|
}
|
||||||
|
|
||||||
in.discard(12);
|
in.discard(12);
|
||||||
byte[] code = new byte[codeFullLength];
|
|
||||||
in.readFull(code);
|
return in.read(codeFullLength);
|
||||||
return code;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
finally {
|
|
||||||
in.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2000-2014 JetBrains s.r.o.
|
* Copyright 2000-2016 JetBrains s.r.o.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -20,36 +20,15 @@ import java.io.DataInputStream;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
public class DataInputFullStream extends DataInputStream {
|
public class DataInputFullStream extends DataInputStream {
|
||||||
|
|
||||||
public DataInputFullStream(byte[] bytes) {
|
public DataInputFullStream(byte[] bytes) {
|
||||||
super(new ByteArrayInputStream(bytes));
|
super(new ByteArrayInputStream(bytes));
|
||||||
}
|
}
|
||||||
|
|
||||||
public int readFull(byte[] b) throws IOException {
|
public byte[] read(int n) throws IOException {
|
||||||
int length = b.length;
|
return InterpreterUtil.readBytes(this, n);
|
||||||
byte[] temp = new byte[length];
|
|
||||||
int pos = 0;
|
|
||||||
|
|
||||||
int bytes_read;
|
|
||||||
while (true) {
|
|
||||||
bytes_read = read(temp, 0, length - pos);
|
|
||||||
if (bytes_read == -1) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
System.arraycopy(temp, 0, b, pos, bytes_read);
|
|
||||||
pos += bytes_read;
|
|
||||||
if (pos == length) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return length;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void discard(int n) throws IOException {
|
public void discard(int n) throws IOException {
|
||||||
if (super.skip(n) != n) {
|
InterpreterUtil.discardBytes(this, n);
|
||||||
throw new IOException("Skip failed");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2000-2015 JetBrains s.r.o.
|
* Copyright 2000-2016 JetBrains s.r.o.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -19,7 +19,6 @@ import org.jetbrains.java.decompiler.main.DecompilerContext;
|
|||||||
import org.jetbrains.java.decompiler.main.extern.IFernflowerPreferences;
|
import org.jetbrains.java.decompiler.main.extern.IFernflowerPreferences;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.nio.channels.FileChannel;
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -31,27 +30,11 @@ public class InterpreterUtil {
|
|||||||
|
|
||||||
public static final int[] EMPTY_INT_ARRAY = new int[0];
|
public static final int[] EMPTY_INT_ARRAY = new int[0];
|
||||||
|
|
||||||
private static final int CHANNEL_WINDOW_SIZE = IS_WINDOWS ? 64 * 1024 * 1024 - (32 * 1024) : 64 * 1024 * 1024; // magic number for Windows
|
|
||||||
private static final int BUFFER_SIZE = 16 * 1024;
|
private static final int BUFFER_SIZE = 16 * 1024;
|
||||||
|
|
||||||
public static void copyFile(File in, File out) throws IOException {
|
public static void copyFile(File source, File target) throws IOException {
|
||||||
FileInputStream inStream = new FileInputStream(in);
|
try (FileInputStream in = new FileInputStream(source); FileOutputStream out = new FileOutputStream(target)) {
|
||||||
try {
|
copyStream(in, out);
|
||||||
FileOutputStream outStream = new FileOutputStream(out);
|
|
||||||
try {
|
|
||||||
FileChannel inChannel = inStream.getChannel();
|
|
||||||
FileChannel outChannel = outStream.getChannel();
|
|
||||||
long size = inChannel.size(), position = 0;
|
|
||||||
while (position < size) {
|
|
||||||
position += inChannel.transferTo(position, CHANNEL_WINDOW_SIZE, outChannel);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
finally {
|
|
||||||
outStream.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
finally {
|
|
||||||
inStream.close();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -64,16 +47,20 @@ public class InterpreterUtil {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static byte[] getBytes(ZipFile archive, ZipEntry entry) throws IOException {
|
public static byte[] getBytes(ZipFile archive, ZipEntry entry) throws IOException {
|
||||||
return readAndClose(archive.getInputStream(entry), (int)entry.getSize());
|
try (InputStream stream = archive.getInputStream(entry)) {
|
||||||
|
return readBytes(stream, (int)entry.getSize());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static byte[] getBytes(File file) throws IOException {
|
public static byte[] getBytes(File file) throws IOException {
|
||||||
return readAndClose(new FileInputStream(file), (int)file.length());
|
try (FileInputStream stream = new FileInputStream(file)) {
|
||||||
|
return readBytes(stream, (int)file.length());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static byte[] readAndClose(InputStream stream, int length) throws IOException {
|
public static byte[] readBytes(InputStream stream, int length) throws IOException {
|
||||||
try {
|
|
||||||
byte[] bytes = new byte[length];
|
byte[] bytes = new byte[length];
|
||||||
|
|
||||||
int n = 0, off = 0;
|
int n = 0, off = 0;
|
||||||
while (n < length) {
|
while (n < length) {
|
||||||
int count = stream.read(bytes, off + n, length - n);
|
int count = stream.read(bytes, off + n, length - n);
|
||||||
@@ -82,10 +69,13 @@ public class InterpreterUtil {
|
|||||||
}
|
}
|
||||||
n += count;
|
n += count;
|
||||||
}
|
}
|
||||||
|
|
||||||
return bytes;
|
return bytes;
|
||||||
}
|
}
|
||||||
finally {
|
|
||||||
stream.close();
|
public static void discardBytes(InputStream stream, int length) throws IOException {
|
||||||
|
if (stream.skip(length) != length) {
|
||||||
|
throw new IOException("premature end of stream");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2000-2015 JetBrains s.r.o.
|
* Copyright 2000-2016 JetBrains s.r.o.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -69,26 +69,18 @@ public class BulkDecompilationTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static void unpack(File archive, File targetDir) {
|
private static void unpack(File archive, File targetDir) {
|
||||||
try {
|
try (ZipFile zip = new ZipFile(archive)) {
|
||||||
ZipFile zip = new ZipFile(archive);
|
|
||||||
try {
|
|
||||||
Enumeration<? extends ZipEntry> entries = zip.entries();
|
Enumeration<? extends ZipEntry> entries = zip.entries();
|
||||||
while (entries.hasMoreElements()) {
|
while (entries.hasMoreElements()) {
|
||||||
ZipEntry entry = entries.nextElement();
|
ZipEntry entry = entries.nextElement();
|
||||||
if (!entry.isDirectory()) {
|
if (!entry.isDirectory()) {
|
||||||
File file = new File(targetDir, entry.getName());
|
File file = new File(targetDir, entry.getName());
|
||||||
assertTrue(file.getParentFile().mkdirs() || file.getParentFile().isDirectory());
|
assertTrue(file.getParentFile().mkdirs() || file.getParentFile().isDirectory());
|
||||||
InputStream in = zip.getInputStream(entry);
|
try (InputStream in = zip.getInputStream(entry); OutputStream out = new FileOutputStream(file)) {
|
||||||
OutputStream out = new FileOutputStream(file);
|
|
||||||
InterpreterUtil.copyStream(in, out);
|
InterpreterUtil.copyStream(in, out);
|
||||||
out.close();
|
|
||||||
in.close();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
finally {
|
|
||||||
zip.close();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
catch (IOException e) {
|
catch (IOException e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
|
|||||||
Reference in New Issue
Block a user