jruby-stdin-channel 0.1.0-java
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/jruby-stdin-channel.gemspec +26 -0
- data/lib/jruby-stdin-channel.rb +3 -0
- data/lib/jruby_stdin_channel.rb +3 -0
- data/lib/jruby_stdin_channel/jruby_stdin_channel.jar +0 -0
- data/lib/jruby_stdin_channel/jruby_stdin_channel.rb +17 -0
- data/lib/jruby_stdin_channel/version.rb +5 -0
- data/src/main/java/StdinChannelService.java +10 -0
- data/src/main/java/com/jrubystdinchannel/StdinChannelLibrary.java +130 -0
- metadata +80 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: a28a8e1211996e36c03df35752494e098a5e0cce
|
4
|
+
data.tar.gz: 338f1d8ad70d88df8a8f94579acf8943799a7592
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 7e4f0a8b6ba5c8ff73990732b70d97313b9529377470e3d6a3549065c3cd5cd99cd0e10bae80bd6336063cb6c047d6c1656f37613b55a1463f2c04a08c8e1990
|
7
|
+
data.tar.gz: 3893950157ba0128fbd23797de78df31854ed851cd7d0f3c935999bbe173161a136d6c961f25e3e0c8da04836084e62cee6aa6319da894e15e28df092ec65dc1
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
raise("JRuby required") unless defined?(JRUBY_VERSION)
|
4
|
+
|
5
|
+
lib = File.expand_path('../lib', __FILE__)
|
6
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
7
|
+
require 'jruby_stdin_channel/version'
|
8
|
+
|
9
|
+
Gem::Specification.new do |s|
|
10
|
+
s.name = "jruby-stdin-channel"
|
11
|
+
s.version = StdinChannel::VERSION
|
12
|
+
s.authors = ["Colin Surprenant"]
|
13
|
+
s.date = Time.now.strftime('%Y-%m-%d')
|
14
|
+
s.summary = "JRuby extension to expose an interruptible NIO FileChannel for STDIN"
|
15
|
+
s.description = s.summary
|
16
|
+
s.email = ["colin.surprenant@gmail.com"]
|
17
|
+
s.homepage = "http://github.com/colinsurprenant/jruby-stdin-channel"
|
18
|
+
s.require_paths = ["lib"]
|
19
|
+
s.licenses = ["Apache-2.0"]
|
20
|
+
s.platform = "java"
|
21
|
+
|
22
|
+
s.files = Dir.glob(["jruby-stdin-channel.gemspec", "lib/**/*.{rb,jar}", "src/**/*.java"])
|
23
|
+
|
24
|
+
s.add_development_dependency "rspec", ">= 2.0.0"
|
25
|
+
s.add_development_dependency "rake", ">= 10.0.0"
|
26
|
+
end
|
Binary file
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require "java"
|
4
|
+
|
5
|
+
# local dev setup
|
6
|
+
classes_dir = File.expand_path("../../../out/production/main", __FILE__)
|
7
|
+
|
8
|
+
if File.directory?(classes_dir)
|
9
|
+
# if in local dev setup, add to classpath
|
10
|
+
$CLASSPATH << classes_dir unless $CLASSPATH.include?(classes_dir)
|
11
|
+
else
|
12
|
+
# otherwise use included jar
|
13
|
+
require "jruby_stdin_channel/jruby_stdin_channel.jar"
|
14
|
+
end
|
15
|
+
|
16
|
+
require "stdin_channel"
|
17
|
+
require "jruby_stdin_channel/version"
|
@@ -0,0 +1,10 @@
|
|
1
|
+
import java.io.IOException;
|
2
|
+
import org.jruby.Ruby;
|
3
|
+
import org.jruby.runtime.load.BasicLibraryService;
|
4
|
+
|
5
|
+
public class StdinChannelService implements BasicLibraryService {
|
6
|
+
public boolean basicLoad(final Ruby runtime) throws IOException {
|
7
|
+
new com.jrubystdinchannel.StdinChannelLibrary().load(runtime, false);
|
8
|
+
return true;
|
9
|
+
}
|
10
|
+
}
|
@@ -0,0 +1,130 @@
|
|
1
|
+
package com.jrubystdinchannel;
|
2
|
+
|
3
|
+
import java.io.*;
|
4
|
+
import java.lang.reflect.Field;
|
5
|
+
import java.nio.ByteBuffer;
|
6
|
+
import java.nio.channels.FileChannel;
|
7
|
+
|
8
|
+
import org.jruby.Ruby;
|
9
|
+
import org.jruby.RubyClass;
|
10
|
+
import org.jruby.RubyModule;
|
11
|
+
import org.jruby.RubyNumeric;
|
12
|
+
import org.jruby.RubyObject;
|
13
|
+
import org.jruby.RubyString;
|
14
|
+
import org.jruby.exceptions.RaiseException;
|
15
|
+
import org.jruby.anno.JRubyClass;
|
16
|
+
import org.jruby.anno.JRubyMethod;
|
17
|
+
import org.jruby.javasupport.JavaObject;
|
18
|
+
import org.jruby.runtime.ObjectAllocator;
|
19
|
+
import org.jruby.runtime.ThreadContext;
|
20
|
+
import org.jruby.runtime.builtin.IRubyObject;
|
21
|
+
import org.jruby.runtime.load.Library;
|
22
|
+
import org.jruby.javasupport.JavaUtil;
|
23
|
+
|
24
|
+
public class StdinChannelLibrary implements Library {
|
25
|
+
public void load(Ruby runtime, boolean wrap) throws IOException {
|
26
|
+
RubyModule mmapModule = runtime.defineModule("StdinChannel");
|
27
|
+
RubyClass byteBufferClass = runtime.defineClassUnder("Reader", runtime.getObject(), new ObjectAllocator() {
|
28
|
+
public IRubyObject allocate(Ruby runtime, RubyClass rubyClass) {
|
29
|
+
return new Reader(runtime, rubyClass);
|
30
|
+
}
|
31
|
+
}, mmapModule);
|
32
|
+
byteBufferClass.defineAnnotatedMethods(Reader.class);
|
33
|
+
}
|
34
|
+
|
35
|
+
@JRubyClass(name = "Reader", parent = "Object")
|
36
|
+
public static class Reader extends RubyObject {
|
37
|
+
|
38
|
+
private FileInputStream in;
|
39
|
+
private FileChannel channel;
|
40
|
+
|
41
|
+
public Reader(Ruby runtime, RubyClass klass) {
|
42
|
+
super(runtime, klass);
|
43
|
+
}
|
44
|
+
|
45
|
+
// def initialize
|
46
|
+
@JRubyMethod(name = "initialize")
|
47
|
+
public IRubyObject initialize(ThreadContext context)
|
48
|
+
{
|
49
|
+
this.in = interruptibleStdin(context);
|
50
|
+
this.channel = in.getChannel();
|
51
|
+
return context.nil;
|
52
|
+
}
|
53
|
+
|
54
|
+
|
55
|
+
private static FileInputStream interruptibleStdin(ThreadContext context)
|
56
|
+
{
|
57
|
+
final RaiseException EXTRACT_ERROR = context.runtime.newRuntimeError("cannot find underlying FileInputStream in System.in");
|
58
|
+
|
59
|
+
try {
|
60
|
+
InputStream stdin = System.in;
|
61
|
+
|
62
|
+
// we expect System.in to be a FilterInputStream, let's setup access to its "in" field
|
63
|
+
Field inField = FilterInputStream.class.getDeclaredField("in");
|
64
|
+
inField.setAccessible(true);
|
65
|
+
|
66
|
+
// normally the underlying FileInputStream is directly in the "in" field but
|
67
|
+
// let's make sure it's not hidden in another inner FilterInputStream
|
68
|
+
while (stdin instanceof FilterInputStream) {
|
69
|
+
stdin = (InputStream) inField.get(stdin);
|
70
|
+
}
|
71
|
+
|
72
|
+
// no luck discovering inner FileInputStream ?
|
73
|
+
if (!(stdin instanceof FileInputStream)) {
|
74
|
+
throw EXTRACT_ERROR;
|
75
|
+
}
|
76
|
+
|
77
|
+
return (FileInputStream) stdin;
|
78
|
+
} catch (NoSuchFieldException|IllegalAccessException e) {
|
79
|
+
throw EXTRACT_ERROR;
|
80
|
+
}
|
81
|
+
}
|
82
|
+
|
83
|
+
|
84
|
+
// def read(size)
|
85
|
+
@JRubyMethod(name = "read", required = 1)
|
86
|
+
public IRubyObject read(ThreadContext context, IRubyObject _size)
|
87
|
+
throws IOException
|
88
|
+
{
|
89
|
+
int size = RubyNumeric.num2int(_size);
|
90
|
+
|
91
|
+
// not sure if we should not reuse a global ByteBuffer here instead of
|
92
|
+
// reallocating a new one at each read call
|
93
|
+
ByteBuffer data = ByteBuffer.allocate(size);
|
94
|
+
int n;
|
95
|
+
|
96
|
+
try {
|
97
|
+
n = this.channel.read(data);
|
98
|
+
} catch (IOException e) {
|
99
|
+
throw context.runtime.newIOErrorFromException(e);
|
100
|
+
}
|
101
|
+
|
102
|
+
if (n > 0) {
|
103
|
+
byte[] bytes = new byte[n];
|
104
|
+
// what is the difference with using data.array() ?
|
105
|
+
data.position(0);
|
106
|
+
data.get(bytes, 0, n);
|
107
|
+
return RubyString.newString(context.runtime, bytes);
|
108
|
+
} else if (n == 0) {
|
109
|
+
// return new empty String
|
110
|
+
return new RubyString(context.runtime, context.runtime.getString());
|
111
|
+
} else {
|
112
|
+
throw context.runtime.newEOFError();
|
113
|
+
}
|
114
|
+
}
|
115
|
+
|
116
|
+
// @return [FileChannel] retrieve native Java FileChannel
|
117
|
+
@JRubyMethod(name = "channel")
|
118
|
+
public IRubyObject channel(ThreadContext context)
|
119
|
+
{
|
120
|
+
return JavaUtil.convertJavaToUsableRubyObject(context.runtime, this.channel);
|
121
|
+
}
|
122
|
+
|
123
|
+
@JRubyMethod(name = "close")
|
124
|
+
public void close()
|
125
|
+
throws IOException
|
126
|
+
{
|
127
|
+
this.channel.close();
|
128
|
+
}
|
129
|
+
}
|
130
|
+
}
|
metadata
ADDED
@@ -0,0 +1,80 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: jruby-stdin-channel
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: java
|
6
|
+
authors:
|
7
|
+
- Colin Surprenant
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-05-15 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
15
|
+
requirements:
|
16
|
+
- - '>='
|
17
|
+
- !ruby/object:Gem::Version
|
18
|
+
version: 2.0.0
|
19
|
+
name: rspec
|
20
|
+
prerelease: false
|
21
|
+
type: :development
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - '>='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 2.0.0
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
requirement: !ruby/object:Gem::Requirement
|
29
|
+
requirements:
|
30
|
+
- - '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 10.0.0
|
33
|
+
name: rake
|
34
|
+
prerelease: false
|
35
|
+
type: :development
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 10.0.0
|
41
|
+
description: JRuby extension to expose an interruptible NIO FileChannel for STDIN
|
42
|
+
email:
|
43
|
+
- colin.surprenant@gmail.com
|
44
|
+
executables: []
|
45
|
+
extensions: []
|
46
|
+
extra_rdoc_files: []
|
47
|
+
files:
|
48
|
+
- jruby-stdin-channel.gemspec
|
49
|
+
- lib/jruby-stdin-channel.rb
|
50
|
+
- lib/jruby_stdin_channel.rb
|
51
|
+
- lib/jruby_stdin_channel/jruby_stdin_channel.jar
|
52
|
+
- lib/jruby_stdin_channel/jruby_stdin_channel.rb
|
53
|
+
- lib/jruby_stdin_channel/version.rb
|
54
|
+
- src/main/java/StdinChannelService.java
|
55
|
+
- src/main/java/com/jrubystdinchannel/StdinChannelLibrary.java
|
56
|
+
homepage: http://github.com/colinsurprenant/jruby-stdin-channel
|
57
|
+
licenses:
|
58
|
+
- Apache-2.0
|
59
|
+
metadata: {}
|
60
|
+
post_install_message:
|
61
|
+
rdoc_options: []
|
62
|
+
require_paths:
|
63
|
+
- lib
|
64
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - '>='
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
70
|
+
requirements:
|
71
|
+
- - '>='
|
72
|
+
- !ruby/object:Gem::Version
|
73
|
+
version: '0'
|
74
|
+
requirements: []
|
75
|
+
rubyforge_project:
|
76
|
+
rubygems_version: 2.4.6
|
77
|
+
signing_key:
|
78
|
+
specification_version: 4
|
79
|
+
summary: JRuby extension to expose an interruptible NIO FileChannel for STDIN
|
80
|
+
test_files: []
|