Documentation for the JRuby extension.

This commit is contained in:
Yorick Peterse 2014-05-07 10:24:24 +02:00
parent 3afef5f7cc
commit bbdc7966db
2 changed files with 49 additions and 0 deletions

View File

@ -8,6 +8,20 @@ import org.jruby.runtime.load.Library;
public class LibogaService implements BasicLibraryService public class LibogaService implements BasicLibraryService
{ {
/**
* Bootstraps the JRuby extension.
*
* In order to load this extension properly you have to make sure that the
* lib/ directory is in the Ruby load path. If this is the case you can
* load it as following:
*
* require 'liboga'
*
* Using absolute paths (e.g. with `require_relative`) requires you to
* manually call this method:
*
* LibogaService.new.basicLoad(JRuby.runtime)
*/
public boolean basicLoad(final Ruby runtime) throws IOException public boolean basicLoad(final Ruby runtime) throws IOException
{ {
org.liboga.xml.Lexer.load(runtime); org.liboga.xml.Lexer.load(runtime);

View File

@ -18,13 +18,27 @@ import org.jruby.runtime.ThreadContext;
import org.jruby.runtime.ObjectAllocator; import org.jruby.runtime.ObjectAllocator;
import org.jruby.runtime.builtin.IRubyObject; import org.jruby.runtime.builtin.IRubyObject;
/**
* Lexer support class for JRuby.
*
* The Lexer class contains the raw Ragel loop and calls back in to Ruby land
* whenever a Ragel action is needed similar to the C extension setup.
*
* This class requires Ruby land to first define the `Oga::XML` namespace.
*/
@JRubyClass(name="Oga::XML::Lexer", parent="Object") @JRubyClass(name="Oga::XML::Lexer", parent="Object")
public class Lexer extends RubyObject public class Lexer extends RubyObject
{ {
/**
* The current Ruby runtime.
*/
private Ruby runtime; private Ruby runtime;
%% write data; %% write data;
/**
* Sets up the current class in the Ruby runtime.
*/
public static void load(Ruby runtime) public static void load(Ruby runtime)
{ {
RubyModule xml = (RubyModule) runtime.getModule("Oga") RubyModule xml = (RubyModule) runtime.getModule("Oga")
@ -54,6 +68,16 @@ public class Lexer extends RubyObject
this.runtime = runtime; this.runtime = runtime;
} }
/**
* Runs the bulk of the Ragel loop and calls back in to Ruby.
*
* This method pulls its data in from the instance variable `@data`. The
* Ruby side of the Lexer class should set this variable to a String in its
* constructor method. Encodings are passed along to make sure that token
* values share the same encoding as the input.
*
* This method always returns nil.
*/
@JRubyMethod @JRubyMethod
public IRubyObject advance_native(ThreadContext context) public IRubyObject advance_native(ThreadContext context)
{ {
@ -72,6 +96,7 @@ public class Lexer extends RubyObject
int eof = data.length; int eof = data.length;
int top = 0; int top = 0;
// Fixed stack size of 8 should be more than enough.
int[] stack = new int[8]; int[] stack = new int[8];
%% write init; %% write init;
@ -80,6 +105,13 @@ public class Lexer extends RubyObject
return context.nil; return context.nil;
} }
/**
* Calls back in to Ruby land passing the current token value along.
*
* This method calls back in to Ruby land based on the method name
* specified in `name`. The Ruby callback should take one argument. This
* argument will be a String containing the value of the current token.
*/
public void callback(String name, byte[] data, Encoding enc, int ts, int te) public void callback(String name, byte[] data, Encoding enc, int ts, int te)
{ {
ByteList bytelist = new ByteList(data, ts, te - ts, enc, true); ByteList bytelist = new ByteList(data, ts, te - ts, enc, true);
@ -91,6 +123,9 @@ public class Lexer extends RubyObject
this.callMethod(context, name, value); this.callMethod(context, name, value);
} }
/**
* Calls back in to Ruby land without passing any arguments.
*/
public void callback_simple(String name) public void callback_simple(String name)
{ {
ThreadContext context = this.runtime.getCurrentContext(); ThreadContext context = this.runtime.getCurrentContext();