public class writer { int fd; public writer(int num) { fd = num; } public int write(String str) { byte[] data = new byte[str.length()]; str.getBytes(0, str.length(), data, 0); return write(data); } public native int write(byte[] data); public static void main(String[] args) { writer w = new writer(1); w.write("Hello World!\n"); } }The method write is a native function which we will implement to do the actual writing. The src code above compiles to the class file writer.class. Running toba on this class file generates a header file writer.h with the following content:
% toba -C writer.java % cat writer.h /* writer.h -- from Java class writer */ /* created by Toba */ #ifndef h_writer #define h_writer #define init_writer() (void)0 Void init_i_rfxGD(Object,Int); Int write_S_kG3VC(Object,Object); Int write_ab_LJfqP(Object,Object); Void main_aS_0Tfn5(Object); struct mt_writer { struct {int s; Object(*f)(Object);} getClass__zh19H; struct {int s; Int(*f)(Object);} hashCode__8wJNW; struct {int s; Boolean(*f)(Object,Object);} equals_O_Ba6e0; struct {int s; Object(*f)(Object);} clone__dslwm; struct {int s; Object(*f)(Object);} toString__4d9OF; struct {int s; Void(*f)(Object);} notify__ne4bk; struct {int s; Void(*f)(Object);} notifyAll__iTnlk; struct {int s; Void(*f)(Object,Long);} wait_l_1Iito; struct {int s; Void(*f)(Object,Long,Int);} wait_li_07Ea2; struct {int s; Void(*f)(Object);} wait__Zlr2b; struct {int s; Void(*f)(Object);} finalize__UKxhs; struct {int s; Void(*f)(Object);} init__AAyKx; struct {int s; Void(*f)(Object,Int);} init_i_rfxGD; struct {int s; Int(*f)(Object,Object);} write_S_kG3VC; struct {int s; Int(*f)(Object,Object);} write_ab_LJfqP; }; extern struct cl_writer { struct class C; struct mt_writer M; } cl_writer; struct in_writer { struct cl_writer *class; struct monitor *monitor; Int fd; }; #endif /* h_writer */The native function we have to implement is Int write_ab_LJfqP(Object,Object);. As a first test we generate a native C file that does nothing:
#include "toba.h" #include "writer.h" /* writer write ([B)I */ Int write_ab_LJfqP(Object Harg1, Object Harg2) { struct in_writer *this = (struct in_writer *)Harg1; printf("writer/write not implemented yet\n"); exit(1); }All that is left now is to fill in the necessary functionality in place of the current body:
#include <errno.h> #include "toba.h" #include "runtime.h" #include "writer.h" /* writer write ([B)I */ Int write_ab_LJfqP(Object Harg1, Object Harg2) { struct in_writer *this = (struct in_writer *)Harg1; struct barray *buf = (struct barray *)Harg2; int res; extern int errno; if(!buf) throwNullPointerException("null argument to write"); res = write(this->fd, buf->data, buf->length); if(res == -1) throwIOException("error writing", errno); return res; }The native routine can be compiled along with the generated code for the class:
% toba -I../sumatra/runtime native.c writer.class % a.out Hello World! %The include path directive was needed to get the runtime/runtime.h include file which has the prototypes for the throw routines.