Skip to content

Commit

Permalink
jruby support
Browse files Browse the repository at this point in the history
  • Loading branch information
ahorek authored and knu committed Sep 14, 2021
1 parent d39db59 commit 2e9dc14
Show file tree
Hide file tree
Showing 19 changed files with 926 additions and 16 deletions.
1 change: 1 addition & 0 deletions .github/workflows/ci.yml
Expand Up @@ -30,6 +30,7 @@ jobs:
- { os: ubuntu-20.04, ruby: head, ignore-pkg-error: true }
- { os: windows-latest, ruby: mingw, ignore-pkg-error: true }
- { os: windows-latest, ruby: mswin, ignore-pkg-error: true }
- { os: ubuntu-20.04, ruby: jruby-head, ignore-pkg-error: true }
exclude:
- { os: windows-latest, ruby: debug }

Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Expand Up @@ -7,6 +7,9 @@
/pkg/
/spec/reports/
/tmp/
lib/*.jar
lib/digest
lib/digest/*.rb
*.bundle
*.so
*.o
2 changes: 2 additions & 0 deletions README.md
Expand Up @@ -95,3 +95,5 @@ Bug reports and pull requests are welcome on GitHub at https://github.com/ruby/d
## License

The gem is available as open source under the terms of the [2-Clause BSD License](https://opensource.org/licenses/BSD-2-Clause).

Files under ext/java (JRuby's digest) are licensed under [Eclipse Public License version 2.0](https://opensource.org/licenses/EPL-2.0), [GNU General Public License version 2](https://opensource.org/licenses/GPL-2.0), [GNU Lesser General Public License version 2.1](https://opensource.org/licenses/LGPL-2.1).
24 changes: 20 additions & 4 deletions Rakefile
Expand Up @@ -7,10 +7,26 @@ Rake::TestTask.new(:test) do |t|
t.test_files = FileList["test/**/test_*.rb"]
end

require 'rake/extensiontask'
Rake::ExtensionTask.new("digest")
%w(bubblebabble md5 rmd160 sha1 sha2).each do |ext|
Rake::ExtensionTask.new("digest/#{ext}")
if RUBY_ENGINE == 'jruby'
require 'rake/javaextensiontask'
Rake::JavaExtensionTask.new("digest") do |ext|
ext.source_version = '1.8'
ext.target_version = '1.8'
ext.ext_dir = 'ext/java'
end

# copy library loaders
require 'fileutils'
%w(bubblebabble md5 rmd160 sha1 sha2).each do |ext|
FileUtils.mkdir "./lib/digest" unless File.exist?("./lib/digest")
FileUtils.cp "./ext/digest/#{ext}/lib/#{ext}.rb", "./lib/digest/#{ext}.rb"
end
else
require 'rake/extensiontask'
Rake::ExtensionTask.new("digest")
%w(bubblebabble md5 rmd160 sha1 sha2).each do |ext|
Rake::ExtensionTask.new("digest/#{ext}")
end
end

task :sync_tool do
Expand Down
36 changes: 27 additions & 9 deletions digest.gemspec
Expand Up @@ -10,7 +10,11 @@ Gem::Specification.new do |spec|
spec.summary = %q{Provides a framework for message digest libraries.}
spec.description = %q{Provides a framework for message digest libraries.}
spec.homepage = "https://github.com/ruby/digest"
spec.licenses = ["Ruby", "BSD-2-Clause"]
if Gem::Platform === spec.platform and spec.platform =~ 'java' or RUBY_ENGINE == 'jruby'
spec.licenses = ["Ruby", "BSD-2-Clause", "EPL-2.0", "GPL-2.0", "LGPL-2.1"]
else
spec.licenses = ["Ruby", "BSD-2-Clause"]
end

spec.files = [
"LICENSE.txt", "README.md",
Expand Down Expand Up @@ -46,13 +50,27 @@ Gem::Specification.new do |spec|
spec.bindir = "exe"
spec.executables = []
spec.require_paths = ["lib"]
spec.extensions = %w[
ext/digest/extconf.rb
ext/digest/bubblebabble/extconf.rb
ext/digest/md5/extconf.rb
ext/digest/rmd160/extconf.rb
ext/digest/sha1/extconf.rb
ext/digest/sha2/extconf.rb
]

if Gem::Platform === spec.platform and spec.platform =~ 'java' or RUBY_ENGINE == 'jruby'
spec.platform = 'java'
spec.files.concat [
"lib/digest.jar",
"lib/digest/md5.rb",
"lib/digest/sha1.rb",
"lib/digest/sha2.rb",
"lib/digest/rmd160.rb",
"lib/digest/bubblebabble.rb"
]
else
spec.extensions = %w[
ext/digest/extconf.rb
ext/digest/bubblebabble/extconf.rb
ext/digest/md5/extconf.rb
ext/digest/rmd160/extconf.rb
ext/digest/sha1/extconf.rb
ext/digest/sha2/extconf.rb
]
end

spec.metadata["msys2_mingw_dependencies"] = "openssl"
end
9 changes: 9 additions & 0 deletions ext/digest/bubblebabble/lib/bubblebabble.rb
@@ -0,0 +1,9 @@
# frozen_string_literal: false

require 'digest'

if RUBY_ENGINE == 'jruby'
JRuby::Util.load_ext("org.jruby.ext.digest.BubbleBabble")
else
require 'digest/bubblebabble.so'
end
8 changes: 6 additions & 2 deletions ext/digest/lib/digest.rb
@@ -1,5 +1,9 @@
# frozen_string_literal: false
require 'digest.so'
if RUBY_ENGINE == 'jruby'
JRuby::Util.load_ext("org.jruby.ext.digest.DigestLibrary")
else
require 'digest.so'
end

module Digest
# A mutex for Digest().
Expand All @@ -8,7 +12,7 @@ module Digest
def self.const_missing(name) # :nodoc:
case name
when :SHA256, :SHA384, :SHA512
lib = 'digest/sha2.so'
lib = 'digest/sha2'
else
lib = File.join('digest', name.to_s.downcase)
end
Expand Down
9 changes: 9 additions & 0 deletions ext/digest/md5/lib/md5.rb
@@ -0,0 +1,9 @@
# frozen_string_literal: false

require 'digest'

if RUBY_ENGINE == 'jruby'
JRuby::Util.load_ext("org.jruby.ext.digest.MD5")
else
require 'digest/md5.so'
end
9 changes: 9 additions & 0 deletions ext/digest/rmd160/lib/rmd160.rb
@@ -0,0 +1,9 @@
# frozen_string_literal: false

require 'digest'

if RUBY_ENGINE == 'jruby'
JRuby::Util.load_ext("org.jruby.ext.digest.RMD160")
else
require 'digest/rmd160.so'
end
9 changes: 9 additions & 0 deletions ext/digest/sha1/lib/sha1.rb
@@ -0,0 +1,9 @@
# frozen_string_literal: false

require 'digest'

if RUBY_ENGINE == 'jruby'
JRuby::Util.load_ext("org.jruby.ext.digest.SHA1")
else
require 'digest/sha1.so'
end
7 changes: 6 additions & 1 deletion ext/digest/sha2/lib/sha2.rb
Expand Up @@ -11,7 +11,12 @@
# $Id$

require 'digest'
require 'digest/sha2.so'

if RUBY_ENGINE == 'jruby'
JRuby::Util.load_ext("org.jruby.ext.digest.SHA2")
else
require 'digest/sha2.so'
end

module Digest
#
Expand Down
119 changes: 119 additions & 0 deletions ext/java/org/jruby/ext/digest/BubbleBabble.java
@@ -0,0 +1,119 @@
/*
**** BEGIN LICENSE BLOCK *****
* Version: EPL 2.0/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Eclipse Public
* License Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.eclipse.org/legal/epl-v20.html
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* Copyright (C) 2010 Charles Oliver Nutter <headius@headius.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the EPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the EPL, the GPL or the LGPL.
***** END LICENSE BLOCK *****/

package org.jruby.ext.digest;

import org.jruby.Ruby;
import org.jruby.runtime.load.Library;
import org.jruby.util.ByteList;

import java.io.IOException;

public class BubbleBabble implements Library {

public void load(final Ruby runtime, boolean wrap) throws IOException {
RubyDigest.createDigestBubbleBabble(runtime);
}

/**
* Ported from OpenSSH (https://github.com/openssh/openssh-portable/blob/957fbceb0f3166e41b76fdb54075ab3b9cc84cba/sshkey.c#L942-L987)
*
* OpenSSH License Notice
*
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
* Copyright (c) 2008 Alexander von Gernler. All rights reserved.
* Copyright (c) 2010,2011 Damien Miller. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
public static ByteList bubblebabble(byte[] message, int begin, int length) {
char[] vowels = new char[]{'a', 'e', 'i', 'o', 'u', 'y'};
char[] consonants = new char[]{'b', 'c', 'd', 'f', 'g', 'h', 'k', 'l', 'm',
'n', 'p', 'r', 's', 't', 'v', 'z', 'x'};

long seed = 1;

ByteList retval = new ByteList();

int rounds = (length / 2) + 1;
retval.append('x');
for (int i = 0; i < rounds; i++) {
int idx0, idx1, idx2, idx3, idx4;

if ((i + 1 < rounds) || (length % 2 != 0)) {
long b = message[begin + 2 * i] & 0xFF;
idx0 = (int) ((((b >> 6) & 3) + seed) % 6) & 0xFFFFFFFF;
idx1 = (int) (((b) >> 2) & 15) & 0xFFFFFFFF;
idx2 = (int) (((b & 3) + (seed / 6)) % 6) & 0xFFFFFFFF;
retval.append(vowels[idx0]);
retval.append(consonants[idx1]);
retval.append(vowels[idx2]);
if ((i + 1) < rounds) {
long b2 = message[begin + (2 * i) + 1] & 0xFF;
idx3 = (int) ((b2 >> 4) & 15) & 0xFFFFFFFF;
idx4 = (int) ((b2) & 15) & 0xFFFFFFFF;
retval.append(consonants[idx3]);
retval.append('-');
retval.append(consonants[idx4]);
seed = ((seed * 5) +
((b * 7) +
b2)) % 36;
}
} else {
idx0 = (int) (seed % 6) & 0xFFFFFFFF;
idx1 = 16;
idx2 = (int) (seed / 6) & 0xFFFFFFFF;
retval.append(vowels[idx0]);
retval.append(consonants[idx1]);
retval.append(vowels[idx2]);
}
}
retval.append('x');

return retval;
}
}
43 changes: 43 additions & 0 deletions ext/java/org/jruby/ext/digest/DigestLibrary.java
@@ -0,0 +1,43 @@
/***** BEGIN LICENSE BLOCK *****
* Version: EPL 2.0/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Eclipse Public
* License Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.eclipse.org/legal/epl-v20.html
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* Copyright (C) 2006 Ola Bini <ola@ologix.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the EPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the EPL, the GPL or the LGPL.
***** END LICENSE BLOCK *****/

package org.jruby.ext.digest;

import java.io.IOException;

import org.jruby.Ruby;
import org.jruby.runtime.load.Library;

/**
* @author <a href="mailto:ola.bini@ki.se">Ola Bini</a>
*/
public class DigestLibrary implements Library {
public void load(final Ruby runtime, boolean wrap) throws IOException {
org.jruby.ext.digest.RubyDigest.createDigest(runtime);
}
}// DigestLibrary
41 changes: 41 additions & 0 deletions ext/java/org/jruby/ext/digest/MD5.java
@@ -0,0 +1,41 @@
/*
**** BEGIN LICENSE BLOCK *****
* Version: EPL 2.0/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Eclipse Public
* License Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.eclipse.org/legal/epl-v20.html
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* Copyright (C) 2010 Charles Oliver Nutter <headius@headius.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the EPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the EPL, the GPL or the LGPL.
***** END LICENSE BLOCK *****/

package org.jruby.ext.digest;

import java.io.IOException;
import org.jruby.Ruby;
import org.jruby.runtime.load.Library;

public class MD5 implements Library {

public void load(final Ruby runtime, boolean wrap) throws IOException {
org.jruby.ext.digest.RubyDigest.createDigestMD5(runtime);
}
}

0 comments on commit 2e9dc14

Please sign in to comment.