1mod perceptron_tagger;
2pub use self::perceptron_tagger::PerceptronTagger;
3
4mod c_binding {
5
6 use std::ffi::{ CStr , c_char , c_float , CString } ;
7 use crate::perceptron_tagger::PerceptronTagger;
8
9 #[repr(C)]
10 pub struct CTag {
11 word: *const u8 ,
12 tag: *const u8 ,
13 conf: c_float ,
14 }
15
16 #[repr(C)]
17 pub struct TagResults {
18 tags: *const CTag ,
19 num_tags: usize
20 }
21
22 unsafe fn get_str(
23 c_char_buffer: *const c_char
24 ) -> String {
25 CStr::from_ptr( c_char_buffer )
26 .to_str()
27 .expect( "Could not convert weights_filepath to &str" )
28 .to_owned()
29 }
30
31 #[no_mangle]
32 pub extern "C" fn tagger_create(
33 weights_filepath: *const c_char ,
34 classes_filepath: *const c_char ,
35 tags_filepath: *const c_char
36 ) -> *mut PerceptronTagger {
37 unsafe {
38 let fp_weights = get_str( weights_filepath ) ;
39 let fp_tags = get_str( tags_filepath ) ;
40 let fp_classes = get_str( classes_filepath ) ;
41 Box::into_raw(
42 Box::new(
43 PerceptronTagger::new( fp_weights.as_str() , fp_classes.as_str() , fp_tags.as_str() )
44 )
45 )
46 }
47 }
48
49 #[no_mangle]
50 pub extern "C" fn tagger_annotate(
51 tagger_ptr: *mut PerceptronTagger ,
52 sentence: *const c_char
53 ) -> *const TagResults {
54 unsafe {
55 let tagger = &*tagger_ptr ;
56 let sentence = get_str( sentence ) ;
57 let tags: Vec<CTag> = tagger.tag( sentence.as_str() )
58 .iter()
59 .map( |x| {
60 let word = CString::new( x.word ).expect( "Could not create CString") ;
61 let word_ptr = word.as_ptr() ;
62 let tag = CString::new( x.tag.as_str() ).expect( "Could not create CString" ) ;
63 let tag_ptr = tag.as_ptr() ;
64 std::mem::forget( word ) ;
65 std::mem::forget( tag ) ;
66 CTag{
67 word: word_ptr.cast::<u8>() ,
68 tag: tag_ptr.cast::<u8>() ,
69 conf: x.conf
70 }
71 }
72 ).collect() ;
73 let num_tags = tags.len() ;
74 let tags_ptr = tags.as_ptr() ;
75 std::mem::forget( tags ) ;
76 Box::into_raw( Box::new( TagResults {
77 tags: tags_ptr,
78 num_tags
79 } ) )
80 }
81 }
82
83 #[no_mangle]
84 pub extern "C" fn tagger_release(
85 tagger_ptr: *mut PerceptronTagger
86 ) {
87 if tagger_ptr.is_null() {
88 return;
89 }
90 unsafe {
91 let _ptr = Box::from_raw( tagger_ptr ) ;
92 }
93 }
94
95}
96
97#[cfg(feature="java")]
98mod java_binding {
99
100 extern crate jni ;
101 use jni::objects::{JClass, JString};
102 use jni::sys::{jfloat,jlong, jstring};
103 use jni::JNIEnv;
104 use crate::perceptron_tagger::PerceptronTagger;
105 use serde_json ;
106
107 #[no_mangle]
108 pub extern "C" fn Java_pos_tagger_POSTagger_create<'a>(
109 mut env: JNIEnv<'a> ,
110 _: JClass<'a> ,
111 weights_filepath: JString<'a> ,
112 classes_filepath: JString<'a> ,
113 tags_filepath: JString<'a>
114 ) -> jlong {
115 let fp_weights: String = env.get_string( &weights_filepath )
116 .expect( "Could not convert weights_filepath to Rust String" )
117 .into() ;
118 let fp_classes: String = env.get_string( &classes_filepath )
119 .expect( "Could not convert classes_filepath to Rust String" )
120 .into() ;
121 let fp_tags: String = env.get_string( &tags_filepath )
122 .expect( "Could not convert tags_filepath to Rust String" )
123 .into() ;
124 Box::into_raw(
125 Box::new(
126 PerceptronTagger::new( fp_weights.as_str() , fp_classes.as_str() , fp_tags.as_str() )
127 )
128 ) as jlong
129 }
130
131 #[no_mangle]
132 pub extern "C" fn Java_pos_tagger_POSTagger_annotate<'a>(
133 mut env: JNIEnv<'a>,
134 _: JClass<'a>,
135 instance_ptr: jlong,
136 sentence: JString<'a>
137 ) -> JString<'a> {
138 let instance = unsafe { &mut *(instance_ptr as *mut PerceptronTagger) } ;
139 let sentence: String = env.get_string( &sentence )
140 .expect( "Could not convert sentence to Rust String" )
141 .into() ;
142 let tags = instance.tag( sentence.as_str() ) ;
143 let tags_json_str = serde_json::to_string( &tags ).expect( "Could not convert tags to JSON" ) ;
144 env.new_string( tags_json_str ).expect( "Could not convert tags_json_str to jstring" )
145 }
146
147 #[no_mangle]
148 pub extern "C" fn Java_pos_tagger_POSTagger_release(
149 _: JNIEnv,
150 _: JClass,
151 instance_ptr: jlong,
152 ) {
153 let _ptr = unsafe { Box::from_raw( instance_ptr as *mut PerceptronTagger) };
154 }
155
156}