Skip to content

Commit

Permalink
Showing 3 changed files with 66 additions and 7 deletions.
6 changes: 5 additions & 1 deletion lib/ruby/truffle/truffle/zlib.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved. This
# code is released under a tri EPL/GPL/LGPL license. You can use it,
# redistribute it and/or modify it under the terms of the:
#
#
# Eclipse Public License version 1.0
# GNU General Public License version 2
# GNU Lesser General Public License version 2.1
@@ -53,6 +53,10 @@ def self.crc32(*args)
Truffle::Zlib.crc32(*args)
end

def self.adler32(*args)
Truffle::Zlib.adler32(*args)
end

module Deflate

def self.deflate(message, level=DEFAULT_COMPRESSION)
5 changes: 0 additions & 5 deletions spec/truffle/tags/library/zlib/adler32_tags.txt

This file was deleted.

62 changes: 61 additions & 1 deletion truffle/src/main/java/org/jruby/truffle/nodes/ext/ZlibNodes.java
Original file line number Diff line number Diff line change
@@ -25,10 +25,12 @@
import org.jruby.util.ByteList;
import org.jruby.util.StringSupport;

import java.lang.reflect.Field;
import java.util.zip.CRC32;
import java.util.zip.DataFormatException;
import java.util.zip.Deflater;
import java.util.zip.Inflater;
import java.util.zip.Adler32;

@CoreClass(name = "Truffle::Zlib")
public abstract class ZlibNodes {
@@ -69,7 +71,7 @@ public long crc32(DynamicObject message, long initial) {
}

@TruffleBoundary
@Specialization(guards = {"isRubyString(message)", "isRubyBignum(initial)"})
@Specialization(guards = { "isRubyString(message)", "isRubyBignum(initial)" })
public long crc32(DynamicObject message, DynamicObject initial) {
throw new RaiseException(getContext().getCoreLibrary().rangeError("bignum too big to convert into `unsigned long'", this));
}
@@ -148,4 +150,62 @@ public DynamicObject inflate(DynamicObject message) {

}

@CoreMethod(names = "adler32", isModuleFunction = true, required = 0, optional = 2, lowerFixnumParameters = 1)
public abstract static class Adler32Node extends CoreMethodArrayArgumentsNode {

private static final Field ADLER_PRIVATE_FIELD;

static {
try {
ADLER_PRIVATE_FIELD = Adler32.class.getDeclaredField("adler");
} catch (NoSuchFieldException e) {
throw new RuntimeException(e);
}
ADLER_PRIVATE_FIELD.setAccessible(true);
}

public Adler32Node(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
}

@Specialization
public long adler32(NotProvided string, NotProvided adler) {
return new Adler32().getValue();
}

@Specialization
@TruffleBoundary
public long adler32(DynamicObject string, NotProvided adler) {
final ByteList bytes = Layouts.STRING.getByteList(string);
final Adler32 adler32 = new Adler32();
adler32.update(bytes.unsafeBytes());

This comment has been minimized.

Copy link
@nirvdrum

nirvdrum Oct 6, 2015

Contributor

This isn't quite right. The backing ByteList's byte[] might have garbage at the beginning or the end. If you can't provide a head and tail index, you'll need to make a copy by using bytes.bytes().

This comment has been minimized.

Copy link
@pitr-ch

pitr-ch Oct 10, 2015

Author Member

Good catch! Thanks for the fix.

return adler32.getValue();
}

@Specialization
@TruffleBoundary
public long adler32(DynamicObject string, int adler) {
final ByteList bytes = Layouts.STRING.getByteList(string);
final Adler32 adler32 = new Adler32();

try {
ADLER_PRIVATE_FIELD.setInt(adler32, adler);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}

adler32.update(bytes.unsafeBytes());
return adler32.getValue();
}

@Specialization(guards = "isRubyBignum(adler)")
@TruffleBoundary
public long adler32(DynamicObject string, DynamicObject adler) {
throw new RaiseException(
getContext().getCoreLibrary().rangeError("bignum too big to convert into `unsigned long'", this));

}

}

}

0 comments on commit dce5d91

Please sign in to comment.