diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RCompression.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RCompression.java index e284889c96d2f6c18bc37080a943b0e89a4666e2..48f915a75aa80d1c987ff58395aa36534cbf8a6f 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RCompression.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RCompression.java @@ -22,24 +22,19 @@ */ package com.oracle.truffle.r.runtime; -import java.io.ByteArrayInputStream; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.lang.ProcessBuilder.Redirect; -import java.nio.file.Files; -import java.nio.file.Paths; import java.util.zip.GZIPInputStream; import com.oracle.truffle.r.runtime.conn.GZIPConnections.GZIPRConnection; import com.oracle.truffle.r.runtime.ffi.RFFIFactory; -import org.tukaani.xz.LZMA2InputStream; -import org.tukaani.xz.XZInputStream; - /** - * Abstracts the implementation of the various forms of compression used in R. + * Abstracts the implementation of the various forms of compression used in R. Since the C API for + * LZMA is very complex (as used by GnuR), we use an 'xz' subprocess to do the work. */ public class RCompression { public enum Type { @@ -103,7 +98,7 @@ public class RCompression { case BZIP2: throw RInternalError.unimplemented("BZIP2 compression"); case LZMA: - return lzmaUncompressInternal(udata, cdata); + return lzmaUncompress(udata, cdata); default: assert false; return false; @@ -165,46 +160,36 @@ public class RCompression { } - private static boolean lzmaUncompressInternal(byte[] udata, byte[] data) { - int dictSize = udata.length < LZMA2InputStream.DICT_SIZE_MIN ? LZMA2InputStream.DICT_SIZE_MIN : udata.length; - try (LZMA2InputStream lzmaStream = new LZMA2InputStream(new ByteArrayInputStream(data), dictSize)) { - int totalRead = 0; - int n; - while ((n = lzmaStream.read(udata, totalRead, udata.length - totalRead)) > 0) { - totalRead += n; + private static boolean lzmaUncompress(byte[] udata, byte[] data) { + int rc; + ProcessBuilder pb = new ProcessBuilder("xz", "--decompress", "--format=raw", "--lzma2", "--stdout"); + pb.redirectError(Redirect.INHERIT); + try { + Process p = pb.start(); + OutputStream os = p.getOutputStream(); + InputStream is = p.getInputStream(); + ProcessOutputManager.OutputThread readThread = new ProcessOutputManager.OutputThreadFixed("xz", is, udata); + readThread.start(); + os.write(data); + os.close(); + rc = p.waitFor(); + if (rc == 0) { + readThread.join(); + if (readThread.totalRead != udata.length) { + return false; + } } - return totalRead == udata.length; - } catch (IOException ex) { + } catch (InterruptedException | IOException ex) { return false; } + return rc == 0; } /** * This is used by {@link GZIPRConnection}. */ public static byte[] lzmaUncompressFromFile(String path) { - try { - byte[] data = Files.readAllBytes(Paths.get(path)); - byte[] buffer = new byte[data.length * 4]; - try (XZInputStream lzmaStream = new XZInputStream(new ByteArrayInputStream(data))) { - int totalRead = 0; - int n; - while ((n = lzmaStream.read(buffer, totalRead, buffer.length - totalRead)) > 0) { - totalRead += n; - if (totalRead == buffer.length) { - byte[] newbuffer = new byte[buffer.length * 2]; - System.arraycopy(buffer, 0, newbuffer, 0, buffer.length); - buffer = newbuffer; - } - } - byte[] result = new byte[totalRead]; - System.arraycopy(buffer, 0, result, 0, totalRead); - return result; - } - - } catch (IOException ex) { - throw RInternalError.shouldNotReachHere(ex); - } + return genericUncompressFromFile(new String[]{"xz", "--decompress", "--lzma2", "--stdout", path}); } public static byte[] bzipUncompressFromFile(String path) { diff --git a/mx.fastr/suite.py b/mx.fastr/suite.py index 7d7a63cc62dd0c4019cb88f278468654749b55a8..ce81b0b2cf17024c81bac57e7754702a520a4153 100644 --- a/mx.fastr/suite.py +++ b/mx.fastr/suite.py @@ -73,16 +73,6 @@ suite = { "resource" : "true" }, - "APACHE_COMMONS_COMPRESS" : { - "urls" : ["http://central.maven.org/maven2/org/apache/commons/commons-compress/1.12/commons-compress-1.12.jar"], - "sha1" : "84caa68576e345eb5e7ae61a0e5a9229eb100d7b" - }, - - "TUKAANI_XZ" : { - "urls" : ["http://central.maven.org/maven2/org/tukaani/xz/1.5/xz-1.5.jar"], - "sha1" : "9c64274b7dbb65288237216e3fae7877fd3f2bee", - }, - "ANTLR-3.5" : { "path" : "libdownloads/antlr-runtime-3.5.jar", "urls" : ["http://central.maven.org/maven2/org/antlr/antlr-runtime/3.5/antlr-runtime-3.5.jar"], @@ -325,8 +315,6 @@ suite = { "dependencies" : [ "truffle:TRUFFLE_API", "truffle:TRUFFLE_DEBUG", - "APACHE_COMMONS_COMPRESS", - "TUKAANI_XZ", ], "checkstyle" : "com.oracle.truffle.r.runtime", "javaCompliance" : "1.8", @@ -439,8 +427,6 @@ suite = { "ANTLR-3.5", "GNUR", "GNU_ICONV", - "APACHE_COMMONS_COMPRESS", - "TUKAANI_XZ", ], "distDependencies" : [ "truffle:TRUFFLE_API",