1
0
Fork 0
mirror of https://github.com/puma/puma.git synced 2022-11-09 13:48:40 -05:00

Merge pull request #1691 from kares/jruby-io-buffer

re-implement (native) IOBuffer for JRuby
This commit is contained in:
Evan Phoenix 2019-02-20 09:26:50 -08:00 committed by GitHub
commit 0d52a4b197
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 75 additions and 57 deletions

View file

@ -6,11 +6,13 @@ import org.jruby.Ruby;
import org.jruby.runtime.load.BasicLibraryService;
import org.jruby.puma.Http11;
import org.jruby.puma.IOBuffer;
import org.jruby.puma.MiniSSL;
public class PumaHttp11Service implements BasicLibraryService {
public boolean basicLoad(final Ruby runtime) throws IOException {
Http11.createHttp11(runtime);
IOBuffer.createIOBuffer(runtime);
MiniSSL.createMiniSSL(runtime);
return true;
}

View file

@ -0,0 +1,72 @@
package org.jruby.puma;
import org.jruby.*;
import org.jruby.anno.JRubyMethod;
import org.jruby.runtime.ObjectAllocator;
import org.jruby.runtime.ThreadContext;
import org.jruby.runtime.builtin.IRubyObject;
import org.jruby.util.ByteList;
/**
* @author kares
*/
public class IOBuffer extends RubyObject {
private static final ObjectAllocator ALLOCATOR = new ObjectAllocator() {
public IRubyObject allocate(Ruby runtime, RubyClass klass) {
return new IOBuffer(runtime, klass);
}
};
public static void createIOBuffer(Ruby runtime) {
RubyModule mPuma = runtime.defineModule("Puma");
RubyClass cIOBuffer = mPuma.defineClassUnder("IOBuffer", runtime.getObject(), ALLOCATOR);
cIOBuffer.defineAnnotatedMethods(IOBuffer.class);
}
private static final int DEFAULT_SIZE = 4096;
final ByteList buffer = new ByteList(DEFAULT_SIZE);
IOBuffer(Ruby runtime, RubyClass klass) {
super(runtime, klass);
}
@JRubyMethod
public RubyInteger used(ThreadContext context) {
return context.runtime.newFixnum(buffer.getRealSize());
}
@JRubyMethod
public RubyInteger capacity(ThreadContext context) {
return context.runtime.newFixnum(buffer.unsafeBytes().length);
}
@JRubyMethod
public IRubyObject reset() {
buffer.setRealSize(0);
return this;
}
@JRubyMethod(name = { "to_s", "to_str" })
public RubyString to_s(ThreadContext context) {
return RubyString.newStringShared(context.runtime, buffer.unsafeBytes(), 0, buffer.getRealSize());
}
@JRubyMethod(name = "<<")
public IRubyObject add(IRubyObject str) {
addImpl(str.convertToString());
return this;
}
@JRubyMethod(rest = true)
public IRubyObject append(IRubyObject[] strs) {
for (IRubyObject str : strs) addImpl(str.convertToString());
return this;
}
private void addImpl(RubyString str) {
buffer.append(str.getByteList());
}
}

View file

@ -1,9 +1,4 @@
# frozen_string_literal: true
require 'puma/detect'
if Puma.jruby?
require 'puma/java_io_buffer'
else
require 'puma/puma_http11'
end
require 'puma/puma_http11'

View file

@ -1,47 +0,0 @@
# frozen_string_literal: true
require 'java'
# Conservative native JRuby/Java implementation of IOBuffer
# backed by a ByteArrayOutputStream and conversion between
# Ruby String and Java bytes
module Puma
class JavaIOBuffer < java.io.ByteArrayOutputStream
field_reader :buf
end
class IOBuffer
BUF_DEFAULT_SIZE = 4096
def initialize
@buf = JavaIOBuffer.new(BUF_DEFAULT_SIZE)
end
def reset
@buf.reset
end
def <<(str)
bytes = str.to_java_bytes
@buf.write(bytes, 0, bytes.length)
end
def append(*strs)
strs.each { |s| self << s; }
end
def to_s
String.from_java_bytes @buf.to_byte_array
end
alias_method :to_str, :to_s
def used
@buf.size
end
def capacity
@buf.buf.length
end
end
end

View file

@ -16,10 +16,6 @@ require 'puma/util'
require 'puma/puma_http11'
unless Puma.const_defined? "IOBuffer"
require 'puma/io_buffer'
end
require 'socket'
module Puma