Skip to content

Commit

Permalink
[Truffle] All of Digest::MD5
Browse files Browse the repository at this point in the history
  • Loading branch information
chrisseaton committed May 18, 2015
1 parent 08e75ac commit 7cf5793
Show file tree
Hide file tree
Showing 13 changed files with 88 additions and 27 deletions.
61 changes: 55 additions & 6 deletions lib/ruby/truffle/truffle/digest.rb
Expand Up @@ -8,6 +8,8 @@

module Digest

NO_MESSAGE = Object.new

class Base

def update(message)
Expand All @@ -20,33 +22,80 @@ def reset
Truffle::Digest.reset @digest
end

def digest(message=nil)
# TODO CS 18-May-15 need to properly handle missing argument, not pretend it's nil
if message.nil?
def digest(message=NO_MESSAGE)
if NO_MESSAGE == message
Truffle::Digest.digest @digest
else
reset
update message
digested = digest
reset
digested
digest!
end
end

def hexdigest(message=NO_MESSAGE)
digest(message).unpack('H*').first
end

alias_method :to_s, :hexdigest
alias_method :to_str, :hexdigest

def digest!
digested = digest
reset
digested
end

def hexdigest!
digested = hexdigest
reset
digested
end

def digest_length
Truffle::Digest.digest_length @digest
end

alias_method :size, :digest_length
alias_method :length, :digest_length

def ==(other)
hexdigest == other.to_str
end

def inspect
"#<#{self.class.name}: #{hexdigest}>"
end

end

class MD5 < Base

def self.file(file)
digest = new
digest.update File.read(file)
digest
end

def self.digest(message)
digest = new
digest.update message
digest.digest
end

def self.hexdigest(message)
digest = new
digest.update message
digest.hexdigest
end

def initialize
@digest = Truffle::Digest.md5
end

def block_length
64
end

end

end
1 change: 0 additions & 1 deletion spec/truffle/tags/library/digest/md5/block_length_tags.txt

This file was deleted.

1 change: 0 additions & 1 deletion spec/truffle/tags/library/digest/md5/digest_bang_tags.txt

This file was deleted.

This file was deleted.

3 changes: 0 additions & 3 deletions spec/truffle/tags/library/digest/md5/equal_tags.txt

This file was deleted.

6 changes: 0 additions & 6 deletions spec/truffle/tags/library/digest/md5/file_tags.txt

This file was deleted.

This file was deleted.

2 changes: 0 additions & 2 deletions spec/truffle/tags/library/digest/md5/hexdigest_tags.txt

This file was deleted.

1 change: 0 additions & 1 deletion spec/truffle/tags/library/digest/md5/inspect_tags.txt

This file was deleted.

1 change: 0 additions & 1 deletion spec/truffle/tags/library/digest/md5/length_tags.txt

This file was deleted.

1 change: 0 additions & 1 deletion spec/truffle/tags/library/digest/md5/size_tags.txt

This file was deleted.

2 changes: 0 additions & 2 deletions spec/truffle/tags/library/digest/md5/to_s_tags.txt

This file was deleted.

Expand Up @@ -9,6 +9,7 @@
*/
package org.jruby.truffle.nodes.ext;

import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.object.*;
import com.oracle.truffle.api.source.SourceSection;
Expand Down Expand Up @@ -65,6 +66,7 @@ public MD5Node(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
}

@CompilerDirectives.TruffleBoundary
@Specialization
public RubyBasicObject md5() {
return createDigest(getContext(), Algorithm.MD5);
Expand All @@ -79,6 +81,7 @@ public UpdateNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
}

@CompilerDirectives.TruffleBoundary
@Specialization
public RubyBasicObject update(RubyBasicObject digestObject, RubyString message) {
final ByteList bytes = message.getByteList();
Expand All @@ -95,6 +98,7 @@ public ResetNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
}

@CompilerDirectives.TruffleBoundary
@Specialization
public RubyBasicObject reset(RubyBasicObject digestObject) {
getDigest(digestObject).reset();
Expand All @@ -110,9 +114,37 @@ public DigestNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
}

@CompilerDirectives.TruffleBoundary
@Specialization
public RubyString digest(RubyBasicObject digestObject) {
return getContext().makeString(getDigest(digestObject).digest());
final MessageDigest digest = getDigest(digestObject);

// TODO CS 18-May-15 this cloning isn't ideal for the key operation

final MessageDigest clonedDigest;

try {
clonedDigest = (MessageDigest) digest.clone();
} catch (CloneNotSupportedException e) {
throw new RuntimeException(e);
}

return getContext().makeString(clonedDigest.digest());
}

}

@CoreMethod(names = "digest_length", isModuleFunction = true, required = 1)
public abstract static class DigestLengthNode extends CoreMethodArrayArgumentsNode {

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

@CompilerDirectives.TruffleBoundary
@Specialization
public int digestLength(RubyBasicObject digestObject) {
return getDigest(digestObject).getDigestLength();
}

}
Expand Down

0 comments on commit 7cf5793

Please sign in to comment.