diff --git a/build.gradle b/build.gradle index d32874a..62f8729 100644 --- a/build.gradle +++ b/build.gradle @@ -106,7 +106,7 @@ task sandbox(dependsOn: proguard, type: Jar) { "**/modules/socket/**", "io/**", "**/modules/aimp/**", "aimpremote/**", "**/modules/downloader/**", - "**/modules/zip/**", + "**/modules/zip/**", "**/modules/gzip/**", "jline/**", "org/fusesource/**", "META-INF/native/**" manifest { diff --git a/src/main/java/com/annimon/ownlang/modules/gzip/gzip.java b/src/main/java/com/annimon/ownlang/modules/gzip/gzip.java new file mode 100644 index 0000000..86523f6 --- /dev/null +++ b/src/main/java/com/annimon/ownlang/modules/gzip/gzip.java @@ -0,0 +1,114 @@ +package com.annimon.ownlang.modules.gzip; + +import com.annimon.ownlang.exceptions.TypeException; +import com.annimon.ownlang.lib.*; +import com.annimon.ownlang.modules.Module; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.zip.GZIPInputStream; +import java.util.zip.GZIPOutputStream; + +public class gzip implements Module { + + @Override + public void init() { + Functions.set("gzip", this::gzipFile); + Functions.set("gzipBytes", this::gzipBytes); + Functions.set("ungzip", this::ungzipFile); + Functions.set("ungzipBytes", this::ungzipBytes); + } + + private Value gzipFile(Value[] args) { + Arguments.check(2, args.length); + + final File input = new File(args[0].asString()); + if (!input.exists() || !input.canRead() || input.isDirectory()) { + return NumberValue.MINUS_ONE; + } + final File output = new File(args[1].asString()); + if (output.isDirectory()) { + return NumberValue.MINUS_ONE; + } + + try (InputStream is = new FileInputStream(input); + OutputStream os = new FileOutputStream(output); + GZIPOutputStream gzos = new GZIPOutputStream(os)) { + copy(is, gzos); + gzos.finish(); + return NumberValue.ONE; + } catch (IOException ex) { + throw new RuntimeException("gzipFile", ex); + } + } + + private Value gzipBytes(Value[] args) { + Arguments.check(1, args.length); + + if (args[0].type() != Types.ARRAY) { + throw new TypeException("Byte array expected at first argument"); + } + final byte[] input = ValueUtils.toByteArray(((ArrayValue) args[0])); + try (InputStream is = new ByteArrayInputStream(input); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + GZIPOutputStream gzos = new GZIPOutputStream(baos)) { + copy(is, gzos); + gzos.finish(); + return ArrayValue.of(baos.toByteArray()); + } catch (IOException ex) { + throw new RuntimeException("gzipBytes", ex); + } + } + + private Value ungzipFile(Value[] args) { + Arguments.check(2, args.length); + + final File input = new File(args[0].asString()); + if (!input.exists() || !input.canRead() || input.isDirectory()) { + return NumberValue.MINUS_ONE; + } + final File output = new File(args[1].asString()); + if (output.isDirectory()) { + return NumberValue.MINUS_ONE; + } + + try (InputStream is = new FileInputStream(input); + GZIPInputStream gzis = new GZIPInputStream(is); + OutputStream os = new FileOutputStream(output)) { + copy(gzis, os); + return NumberValue.ONE; + } catch (IOException ex) { + throw new RuntimeException("ungzipFile", ex); + } + } + + private Value ungzipBytes(Value[] args) { + Arguments.check(1, args.length); + + if (args[0].type() != Types.ARRAY) { + throw new TypeException("Byte array expected at first argument"); + } + final byte[] input = ValueUtils.toByteArray(((ArrayValue) args[0])); + try (InputStream is = new ByteArrayInputStream(input); + GZIPInputStream gzis = new GZIPInputStream(is); + ByteArrayOutputStream baos = new ByteArrayOutputStream()) { + copy(gzis, baos); + return ArrayValue.of(baos.toByteArray()); + } catch (IOException ex) { + throw new RuntimeException("ungzipBytes", ex); + } + } + + private void copy(InputStream is, OutputStream os) throws IOException { + final byte[] buffer = new byte[8192]; + int read; + while ((read = is.read(buffer)) != -1) { + os.write(buffer, 0, read); + } + } +}