diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/BasePackage.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/BasePackage.java index b808d98b94ced2e7e52e284aca02c8cac50f6ae0..36c96b5347205ba7bf2190b46df1e87ec2aae17b 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/BasePackage.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/BasePackage.java @@ -571,6 +571,7 @@ public class BasePackage extends RBuiltinPackage { add(SysFunctions.SysInfo.class, SysFunctionsFactory.SysInfoNodeGen::create); add(SysFunctions.SysReadlink.class, SysFunctionsFactory.SysReadlinkNodeGen::create); add(SysFunctions.SysSetEnv.class, SysFunctionsFactory.SysSetEnvNodeGen::create); + add(SysFunctions.SysSetFileTime.class, SysFunctionsFactory.SysSetFileTimeNodeGen::create); add(SysFunctions.SysSleep.class, SysFunctionsFactory.SysSleepNodeGen::create); add(SysFunctions.SysTime.class, SysFunctionsFactory.SysTimeNodeGen::create); add(SysFunctions.SysUmask.class, SysFunctionsFactory.SysUmaskNodeGen::create); diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Internal.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Internal.java index 70c4b5fc8a83da31212e59bb0a3142756f4f6a41..23a2a3bc064f3b8ce1c8608eeab0b9f7b682918f 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Internal.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Internal.java @@ -113,8 +113,9 @@ public abstract class Internal extends RBuiltinNode { return false; } + // TODO check this; it is out of date private static final String[] NOT_IMPLEMENTED = new String[]{ - ".addTryHandlers", "interruptsSuspended", "restart", "backsolve", "max.col", "row", "all.names", "comment", "`comment<-`", "list2env", "tcrossprod", "setFileTime", "lbeta", + ".addTryHandlers", "interruptsSuspended", "restart", "backsolve", "max.col", "row", "all.names", "comment", "`comment<-`", "list2env", "tcrossprod", "lbeta", "beta", "lchoose", "choose", "dchisq", "pchisq", "qchisq", "dexp", "pexp", "qexp", "dgeom", "pgeom", "qgeom", "dpois", "ppois", "qpois", "dt", "pt", "qt", "dsignrank", "psignrank", "qsignrank", "besselJ", "besselY", "psigamma", "dbeta", "pbeta", "qbeta", "dbinom", "pbinom", "qbinom", "dcauchy", "pcauchy", "qcauchy", "df", "pf", "qf", "dgamma", "pgamma", "qgamma", "dlnorm", "plnorm", "qlnorm", "dlogis", "plogis", "qlogis", "dnbinom", "pnbinom", "qnbinom", "dnorm", "pnorm", "qnorm", "dunif", "punif", "qunif", "dweibull", diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Match.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Match.java index bbb1f2bc9bffa1cc9b8065a6ac566e44bb48c950..cb6bdc74d7327e7ab2d8b90e399cdb1ee7bad5b7 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Match.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Match.java @@ -22,6 +22,8 @@ */ package com.oracle.truffle.r.nodes.builtin.base; +import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.instanceOf; +import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.nullValue; import static com.oracle.truffle.r.runtime.builtins.RBehavior.PURE; import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.INTERNAL; @@ -52,6 +54,7 @@ import com.oracle.truffle.r.runtime.data.model.RAbstractDoubleVector; import com.oracle.truffle.r.runtime.data.model.RAbstractIntVector; import com.oracle.truffle.r.runtime.data.model.RAbstractListVector; import com.oracle.truffle.r.runtime.data.model.RAbstractLogicalVector; +import com.oracle.truffle.r.runtime.data.model.RAbstractRawVector; import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector; import com.oracle.truffle.r.runtime.data.model.RAbstractVector; import com.oracle.truffle.r.runtime.ops.na.NACheck; @@ -74,7 +77,11 @@ public abstract class Match extends RBuiltinNode { @Override protected void createCasts(CastBuilder casts) { - casts.toInteger(2); + // TODO these pipelines do not allow scalars, i.e., the RAbstractVector isn't right. + // casts.arg("x").mustBe(instanceOf(RAbstractVector.class).or(nullValue())).asVector(true); + // casts.arg("table").mustBe(instanceOf(RAbstractVector.class).or(nullValue())).asVector(true); + casts.arg("nomatch").asIntegerVector().findFirst(); + // casts.arg("incomparables").mustBe(instanceOf(RAbstractVector.class).or(nullValue())).asVector(true); } private RAbstractStringVector castString(RAbstractVector operand) { @@ -97,21 +104,20 @@ public abstract class Match extends RBuiltinNode { @Specialization @SuppressWarnings("unused") - protected RIntVector match(RNull x, RNull table, RAbstractIntVector nomatchObj, Object incomparables) { + protected RIntVector match(RNull x, RNull table, int nomatch, Object incomparables) { return RDataFactory.createIntVector(0); } @Specialization @SuppressWarnings("unused") - protected RIntVector match(RNull x, RAbstractVector table, RAbstractIntVector nomatchObj, Object incomparables) { + protected RIntVector match(RNull x, RAbstractVector table, int nomatch, Object incomparables) { return RDataFactory.createIntVector(0); } @Specialization @SuppressWarnings("unused") - protected RIntVector match(RAbstractVector x, RNull table, RAbstractIntVector nomatchVec, Object incomparables) { + protected RIntVector match(RAbstractVector x, RNull table, int nomatch, Object incomparables) { int[] data = new int[x.getLength()]; - int nomatch = nomatchVec.getLength() == 0 ? RRuntime.INT_NA : nomatchVec.getDataAt(0); Arrays.fill(data, nomatch); naCheck.enable(nomatch); naCheck.check(nomatch); @@ -119,22 +125,22 @@ public abstract class Match extends RBuiltinNode { } @Specialization(guards = {"isFactor(x)", "isFactor(table)"}) - protected Object matchFactor(RAbstractIntVector x, RAbstractIntVector table, RAbstractIntVector nomatchObj, Object incomparables) { + protected Object matchFactor(RAbstractIntVector x, RAbstractIntVector table, int nomatch, Object incomparables) { naCheck.enable(x); naCheck.enable(table); - return matchRecursive(RClosures.createFactorToVector(x, true, attrProfiles), RClosures.createFactorToVector(table, true, attrProfiles), nomatchObj, incomparables); + return matchRecursive(RClosures.createFactorToVector(x, true, attrProfiles), RClosures.createFactorToVector(table, true, attrProfiles), nomatch, incomparables); } @Specialization(guards = {"isFactor(x)", "!isFactor(table)"}) - protected Object matchFactor(RAbstractIntVector x, RAbstractVector table, RAbstractIntVector nomatchObj, Object incomparables) { + protected Object matchFactor(RAbstractIntVector x, RAbstractVector table, int nomatch, Object incomparables) { naCheck.enable(x); - return matchRecursive(RClosures.createFactorToVector(x, true, attrProfiles), table, nomatchObj, incomparables); + return matchRecursive(RClosures.createFactorToVector(x, true, attrProfiles), table, nomatch, incomparables); } @Specialization(guards = {"!isFactor(x)", "isFactor(table)"}) - protected Object matchFactor(RAbstractVector x, RAbstractIntVector table, RAbstractIntVector nomatchObj, Object incomparables) { + protected Object matchFactor(RAbstractVector x, RAbstractIntVector table, int nomatch, Object incomparables) { naCheck.enable(table); - return matchRecursive(x, RClosures.createFactorToVector(table, true, attrProfiles), nomatchObj, incomparables); + return matchRecursive(x, RClosures.createFactorToVector(table, true, attrProfiles), nomatch, incomparables); } @Specialization @@ -144,8 +150,7 @@ public abstract class Match extends RBuiltinNode { } @Specialization - protected RIntVector match(RAbstractIntVector x, RAbstractIntVector table, RAbstractIntVector nomatchVec, @SuppressWarnings("unused") Object incomparables) { - int nomatch = nomatchVec.getLength() == 0 ? RRuntime.INT_NA : nomatchVec.getDataAt(0); + protected RIntVector match(RAbstractIntVector x, RAbstractIntVector table, int nomatch, @SuppressWarnings("unused") Object incomparables) { int[] result = initResult(x.getLength(), nomatch); boolean matchAll = true; NonRecursiveHashMapInt hashTable; @@ -180,8 +185,7 @@ public abstract class Match extends RBuiltinNode { } @Specialization - protected RIntVector match(RAbstractDoubleVector x, RAbstractIntVector table, RAbstractIntVector nomatchVec, @SuppressWarnings("unused") Object incomparables) { - int nomatch = nomatchVec.getLength() == 0 ? RRuntime.INT_NA : nomatchVec.getDataAt(0); + protected RIntVector match(RAbstractDoubleVector x, RAbstractIntVector table, int nomatch, @SuppressWarnings("unused") Object incomparables) { int[] result = initResult(x.getLength(), nomatch); boolean matchAll = true; NonRecursiveHashMapDouble hashTable; @@ -216,8 +220,7 @@ public abstract class Match extends RBuiltinNode { } @Specialization - protected RIntVector match(RAbstractIntVector x, RAbstractDoubleVector table, RAbstractIntVector nomatchVec, @SuppressWarnings("unused") Object incomparables) { - int nomatch = nomatchVec.getLength() == 0 ? RRuntime.INT_NA : nomatchVec.getDataAt(0); + protected RIntVector match(RAbstractIntVector x, RAbstractDoubleVector table, int nomatch, @SuppressWarnings("unused") Object incomparables) { int[] result = initResult(x.getLength(), nomatch); boolean matchAll = true; NonRecursiveHashMapInt hashTable; @@ -259,8 +262,7 @@ public abstract class Match extends RBuiltinNode { } @Specialization - protected RIntVector match(RAbstractDoubleVector x, RAbstractDoubleVector table, RAbstractIntVector nomatchVec, @SuppressWarnings("unused") Object incomparables) { - int nomatch = nomatchVec.getLength() == 0 ? RRuntime.INT_NA : nomatchVec.getDataAt(0); + protected RIntVector match(RAbstractDoubleVector x, RAbstractDoubleVector table, int nomatch, @SuppressWarnings("unused") Object incomparables) { int[] result = initResult(x.getLength(), nomatch); boolean matchAll = true; NonRecursiveHashMapDouble hashTable; @@ -295,8 +297,7 @@ public abstract class Match extends RBuiltinNode { } @Specialization - protected RIntVector match(RAbstractIntVector x, RAbstractLogicalVector table, RAbstractIntVector nomatchVec, @SuppressWarnings("unused") Object incomparables) { - int nomatch = nomatchVec.getLength() == 0 ? RRuntime.INT_NA : nomatchVec.getDataAt(0); + protected RIntVector match(RAbstractIntVector x, RAbstractLogicalVector table, int nomatch, @SuppressWarnings("unused") Object incomparables) { int[] result = initResult(x.getLength(), nomatch); boolean matchAll = true; int[] values = {RRuntime.LOGICAL_TRUE, RRuntime.LOGICAL_FALSE, RRuntime.LOGICAL_NA}; @@ -327,7 +328,7 @@ public abstract class Match extends RBuiltinNode { } @Specialization(guards = "x.getLength() == 1") - protected int matchSizeOne(RAbstractStringVector x, RAbstractStringVector table, RAbstractIntVector nomatchVec, @SuppressWarnings("unused") Object incomparables, // + protected int matchSizeOne(RAbstractStringVector x, RAbstractStringVector table, int nomatch, @SuppressWarnings("unused") Object incomparables, // @Cached("create()") NAProfile naProfile, // @Cached("create()") BranchProfile foundProfile, // @Cached("create()") BranchProfile notFoundProfile) { @@ -349,13 +350,11 @@ public abstract class Match extends RBuiltinNode { } } notFoundProfile.enter(); - return nomatchVec.getLength() == 0 ? RRuntime.INT_NA : nomatchVec.getDataAt(0); - + return nomatch; } @Specialization - protected RIntVector match(RAbstractStringVector x, RAbstractStringVector table, RAbstractIntVector nomatchVec, @SuppressWarnings("unused") Object incomparables) { - int nomatch = nomatchVec.getLength() == 0 ? RRuntime.INT_NA : nomatchVec.getDataAt(0); + protected RIntVector match(RAbstractStringVector x, RAbstractStringVector table, int nomatch, @SuppressWarnings("unused") Object incomparables) { int[] result = initResult(x.getLength(), nomatch); boolean matchAll = true; NonRecursiveHashMapCharacter hashTable; @@ -390,21 +389,27 @@ public abstract class Match extends RBuiltinNode { } @Specialization - protected RIntVector match(RAbstractLogicalVector x, RAbstractStringVector table, RAbstractIntVector nomatchObj, Object incomparables) { + protected RIntVector match(RAbstractLogicalVector x, RAbstractStringVector table, int nomatch, Object incomparables) { + naCheck.enable(x); + return match(RClosures.createLogicalToStringVector(x), table, nomatch, incomparables); + } + + @Specialization + protected RIntVector match(RAbstractRawVector x, RAbstractIntVector table, int nomatch, Object incomparables) { naCheck.enable(x); - return match(RClosures.createLogicalToStringVector(x), table, nomatchObj, incomparables); + return match(RClosures.createRawToStringVector(x), RClosures.createIntToStringVector(table), nomatch, incomparables); } @Specialization - protected RIntVector match(RAbstractIntVector x, RAbstractStringVector table, RAbstractIntVector nomatchObj, Object incomparables) { + protected RIntVector match(RAbstractIntVector x, RAbstractStringVector table, int nomatch, Object incomparables) { naCheck.enable(x); - return match(RClosures.createIntToStringVector(x), table, nomatchObj, incomparables); + return match(RClosures.createIntToStringVector(x), table, nomatch, incomparables); } @Specialization - protected RIntVector match(RAbstractDoubleVector x, RAbstractStringVector table, RAbstractIntVector nomatchObj, Object incomparables) { + protected RIntVector match(RAbstractDoubleVector x, RAbstractStringVector table, int nomatch, Object incomparables) { naCheck.enable(x); - return match(RClosures.createDoubleToStringVector(x), table, nomatchObj, incomparables); + return match(RClosures.createDoubleToStringVector(x), table, nomatch, incomparables); } @Specialization @@ -498,13 +503,13 @@ public abstract class Match extends RBuiltinNode { @Specialization @SuppressWarnings("unused") - protected RIntVector match(RFunction x, Object table, RAbstractIntVector nomatchObj, Object incomparables) { + protected RIntVector match(RFunction x, Object table, int nomatch, Object incomparables) { throw RError.error(this, RError.Message.MATCH_VECTOR_ARGS); } @Specialization @SuppressWarnings("unused") - protected RIntVector match(Object x, RFunction table, RAbstractIntVector nomatchObj, Object incomparables) { + protected RIntVector match(Object x, RFunction table, int nomatch, Object incomparables) { throw RError.error(this, RError.Message.MATCH_VECTOR_ARGS); } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/SysFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/SysFunctions.java index 27809328cf707804677a8a357b7ffb30a240fab6..90d8b1ed1819259eb3d2d1854ad7bd92c1c41422 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/SysFunctions.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/SysFunctions.java @@ -32,8 +32,12 @@ import static com.oracle.truffle.r.runtime.builtins.RBehavior.READS_STATE; import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.INTERNAL; import java.io.IOException; +import java.nio.file.FileSystems; +import java.nio.file.Files; +import java.nio.file.attribute.FileTime; import java.util.ArrayList; import java.util.Map; +import java.util.concurrent.TimeUnit; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.dsl.Specialization; @@ -371,4 +375,24 @@ public class SysFunctions { return RDataFactory.createStringVector(data, RDataFactory.COMPLETE_VECTOR); } } + + @RBuiltin(name = "setFileTime", kind = INTERNAL, parameterNames = {"path", "time"}, behavior = IO) + public abstract static class SysSetFileTime extends RBuiltinNode { + @Override + protected void createCasts(CastBuilder casts) { + casts.arg("path").mustBe(stringValue()).asStringVector().findFirst(); + casts.arg("time").asIntegerVector().findFirst().notNA(); + } + + @Specialization + @TruffleBoundary + protected byte sysSetFileTime(String path, int time) { + try { + Files.setLastModifiedTime(FileSystems.getDefault().getPath(path), FileTime.from(time, TimeUnit.SECONDS)); + return RRuntime.LOGICAL_TRUE; + } catch (IOException ex) { + return RRuntime.LOGICAL_FALSE; + } + } + } } 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 d3b6c90962ba3b6b1cf9f4f20bc53aa7626f5d9d..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,10 +22,12 @@ */ package com.oracle.truffle.r.runtime; +import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.lang.ProcessBuilder.Redirect; +import java.util.zip.GZIPInputStream; import com.oracle.truffle.r.runtime.conn.GZIPConnections.GZIPRConnection; import com.oracle.truffle.r.runtime.ffi.RFFIFactory; @@ -56,11 +58,16 @@ public class RCompression { return null; } + private static final byte GZIP_MAGIC1 = GZIPInputStream.GZIP_MAGIC & 0xFF; + private static final byte GZIP_MAGIC2 = (byte) ((GZIPInputStream.GZIP_MAGIC >> 8) & 0xFF); + /** * Decode the compression type from the bytes in buf (which must be at least length 5). */ - public static Type decodeBuf(byte[] buf) { - if (buf[0] == 'B' && buf[1] == 'Z' && buf[2] == 'h') { + private static Type decodeBuf(byte[] buf) { + if (buf[0] == GZIP_MAGIC1 && buf[1] == GZIP_MAGIC2) { + return RCompression.Type.GZIP; + } else if (buf[0] == 'B' && buf[1] == 'Z' && buf[2] == 'h') { return RCompression.Type.BZIP2; } else if (buf[0] == (byte) 0xFD && buf[1] == '7' && buf[2] == 'z' && buf[3] == 'X' && buf[4] == 'Z') { return RCompression.Type.LZMA; @@ -70,6 +77,17 @@ public class RCompression { } } + public static Type getCompressionType(String path) throws IOException { + try (InputStream is = new FileInputStream(path)) { + byte[] buf = new byte[5]; + int count = is.read(buf); + if (count == 5) { + return RCompression.Type.decodeBuf(buf); + } + } + return RCompression.Type.NONE; + } + public static boolean uncompress(Type type, byte[] udata, byte[] cdata) { switch (type) { case NONE: diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/conn/FileConnections.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/conn/FileConnections.java index 050f147d9f1ecb0eb7bd7afd8d6cc057746b6506..c4eb346b86a2cca0350bbe63a901c244642c0ed6 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/conn/FileConnections.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/conn/FileConnections.java @@ -34,6 +34,7 @@ import java.nio.ByteBuffer; import java.util.zip.GZIPInputStream; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; +import com.oracle.truffle.r.runtime.RCompression; import com.oracle.truffle.r.runtime.RError; import com.oracle.truffle.r.runtime.RInternalError; import com.oracle.truffle.r.runtime.TempPathName; @@ -102,24 +103,17 @@ public class FileConnections { FileReadTextRConnection(BasePathRConnection base) throws IOException { super(base); - inputStream = new BufferedInputStream(new FileInputStream(base.path)); // can be compressed - check for it - inputStream.mark(2); - int byte1 = inputStream.read(); - if (byte1 == -1) { - inputStream.reset(); - } else { - int byte2 = inputStream.read(); - if (byte2 == -1) { - inputStream.reset(); - } else { - if (byte1 == (GZIPInputStream.GZIP_MAGIC & 0x000000FF) && byte2 == (GZIPInputStream.GZIP_MAGIC >> 8)) { - inputStream.close(); - inputStream = new GZIPInputStream(new FileInputStream(base.path), GZIPConnections.GZIP_BUFFER_SIZE); - } else { - inputStream.reset(); - } - } + RCompression.Type cType = RCompression.getCompressionType(base.path); + switch (cType) { + case NONE: + inputStream = new BufferedInputStream(new FileInputStream(base.path)); + break; + case GZIP: + inputStream = new GZIPInputStream(new FileInputStream(base.path), GZIPConnections.GZIP_BUFFER_SIZE); + break; + default: + throw RError.nyi(RError.SHOW_CALLER2, "compression type: " + cType.name()); } } @@ -212,10 +206,10 @@ public class FileConnections { } } - private static class FileReadBinaryRConnection extends DelegateReadRConnection implements ReadWriteHelper { + static class FileReadBinaryRConnection extends DelegateReadRConnection implements ReadWriteHelper { private FileInputStream inputStream; - FileReadBinaryRConnection(FileRConnection base) throws IOException { + FileReadBinaryRConnection(BasePathRConnection base) throws IOException { super(base); inputStream = new FileInputStream(base.path); } @@ -316,7 +310,7 @@ public class FileConnections { private static class FileReadWriteConnection extends DelegateReadWriteRConnection implements ReadWriteHelper { /* * This is a minimal implementation to support one specific use in package installation. - * + * * N.B. R mandates separate "position" offsets for reading and writing (pain). This code is * pessimistic and assumes interleaved reads and writes, so does a lot of probably redundant * seeking. It could be optimized. diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/conn/GZIPConnections.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/conn/GZIPConnections.java index 66fcbb33a01d59c5967f7114ada79141440d2efa..0928fe7df3d31e81432526ff5988f60fb0eebb83 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/conn/GZIPConnections.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/conn/GZIPConnections.java @@ -60,20 +60,18 @@ public class GZIPConnections { @Override protected void createDelegateConnection() throws IOException { DelegateRConnection delegate = null; - switch (getOpenMode().abstractOpenMode) { + AbstractOpenMode openMode = getOpenMode().abstractOpenMode; + switch (openMode) { case Read: case ReadBinary: - RCompression.Type cType = RCompression.Type.NONE; - try (InputStream is = new FileInputStream(path)) { - byte[] buf = new byte[5]; - int count = is.read(buf); - if (count == 5) { - cType = RCompression.Type.decodeBuf(buf); - } - } + RCompression.Type cType = RCompression.getCompressionType(path); switch (cType) { case NONE: - delegate = new FileConnections.FileReadTextRConnection(this); + if (openMode == AbstractOpenMode.ReadBinary) { + delegate = new FileConnections.FileReadBinaryRConnection(this); + } else { + delegate = new FileConnections.FileReadTextRConnection(this); + } break; case GZIP: delegate = new GZIPInputRConnection(this);