charlock_holmes-jruby 0.1.0-java
Sign up to get free protection for your applications and to get access to all the features.
- data/.rspec +4 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +29 -0
- data/LICENSE +20 -0
- data/README.md +65 -0
- data/Rakefile +17 -0
- data/charlock_holmes-jruby.gemspec +25 -0
- data/lib/charlock_holmes-jruby.rb +1 -0
- data/lib/charlock_holmes.rb +5 -0
- data/lib/charlock_holmes/charset_match_ext.rb +17 -0
- data/lib/charlock_holmes/converter.rb +12 -0
- data/lib/charlock_holmes/encoding_detector.rb +54 -0
- data/lib/charlock_holmes/string.rb +21 -0
- data/lib/charlock_holmes/version.rb +5 -0
- data/lib/charlock_holmes_jruby.rb +1 -0
- data/spec/converter_spec.rb +57 -0
- data/spec/encoding_detector_spec.rb +97 -0
- data/spec/fixtures/AnsiGraph.psm1 +0 -0
- data/spec/fixtures/TwigExtensionsDate.es.yml +8 -0
- data/spec/fixtures/cl-messagepack.lisp +264 -0
- data/spec/fixtures/core.rkt +254 -0
- data/spec/fixtures/laholator.py +131 -0
- data/spec/fixtures/mingpao.html +455 -0
- data/spec/fixtures/repl2.cljs +109 -0
- data/spec/fixtures/shift_jis.html +1244 -0
- data/spec/spec_helpers.rb +1 -0
- data/spec/string_spec.rb +39 -0
- metadata +144 -0
Binary file
|
@@ -0,0 +1,8 @@
|
|
1
|
+
date.year: '%year% año|%year% años'
|
2
|
+
date.month: '%month% mes|%month% meses'
|
3
|
+
date.day: '%day% día|%day% días'
|
4
|
+
date.hour: '%hour% hora|%hour% horas'
|
5
|
+
date.minute: '%minute% minuto|%minute% minutos'
|
6
|
+
date.second: '%second% segundo|%second% segundos'
|
7
|
+
date.new: 'menos de un minuto'
|
8
|
+
date.and: ' y '
|
@@ -0,0 +1,264 @@
|
|
1
|
+
;;;; cl-messagepack.lisp
|
2
|
+
|
3
|
+
(in-package #:messagepack)
|
4
|
+
|
5
|
+
(declaim (optimize (debug 3)))
|
6
|
+
|
7
|
+
(eval-when (:compile-toplevel :load-toplevel :execute)
|
8
|
+
(defun mkstr (&rest args)
|
9
|
+
(format nil "~{~a~}" args))
|
10
|
+
(defun mksymb (&rest args)
|
11
|
+
(intern (apply #'mkstr args))))
|
12
|
+
|
13
|
+
(defmacro signed-unsigned-convertors (size)
|
14
|
+
(let ((speed (if (< size 32) 3 0)))
|
15
|
+
`(progn
|
16
|
+
(defun ,(mksymb 'sb size '-> 'ub size) (sb)
|
17
|
+
(declare (optimize (debug 0) (safety 0) (speed ,speed))
|
18
|
+
(type (integer ,(- (expt 2 (1- size))) ,(1- (expt 2 (1- size)))) sb))
|
19
|
+
(if (< sb 0)
|
20
|
+
(ldb (byte ,size 0) sb)
|
21
|
+
sb))
|
22
|
+
(defun ,(mksymb 'ub size '-> 'sb size) (sb)
|
23
|
+
(declare (optimize (debug 0) (safety 0) (speed ,speed))
|
24
|
+
(type (mod ,(expt 2 size)) sb))
|
25
|
+
(if (logbitp (1- ,size) sb)
|
26
|
+
(- (1+ (logxor (1- (expt 2 ,size)) sb)))
|
27
|
+
sb)))))
|
28
|
+
|
29
|
+
(signed-unsigned-convertors 8)
|
30
|
+
(signed-unsigned-convertors 16)
|
31
|
+
(signed-unsigned-convertors 32)
|
32
|
+
(signed-unsigned-convertors 64)
|
33
|
+
|
34
|
+
(defun write-hex (data)
|
35
|
+
(let (line)
|
36
|
+
(loop
|
37
|
+
for i from 0 to (1- (length data))
|
38
|
+
do (push (elt data i) line)
|
39
|
+
when (= (length line) 16)
|
40
|
+
do
|
41
|
+
(format t "~{~2,'0x ~}~%" (nreverse line))
|
42
|
+
(setf line nil))
|
43
|
+
(when line
|
44
|
+
(format t "~{~2,'0x ~}~%" (nreverse line)))))
|
45
|
+
|
46
|
+
(defun encode (data)
|
47
|
+
(flexi-streams:with-output-to-sequence (stream)
|
48
|
+
(encode-stream data stream)))
|
49
|
+
|
50
|
+
(defun make-hash (data)
|
51
|
+
(let ((result (make-hash-table)))
|
52
|
+
(dolist (kv data)
|
53
|
+
(cond ((consp (cdr kv))
|
54
|
+
(setf (gethash (first kv) result) (second kv)))
|
55
|
+
(t
|
56
|
+
(setf (gethash (car kv) result) (cdr kv)))))
|
57
|
+
result))
|
58
|
+
|
59
|
+
(defun is-byte-array (data-type)
|
60
|
+
(and (vectorp data-type)
|
61
|
+
(equal '(unsigned-byte 8) (array-element-type data-type))))
|
62
|
+
|
63
|
+
(defun encode-stream (data stream)
|
64
|
+
(cond ((floatp data) (encode-float data stream))
|
65
|
+
((numberp data) (encode-integer data stream))
|
66
|
+
((null data) (write-byte #xc0 stream))
|
67
|
+
((eq data t) (write-byte #xc3 stream))
|
68
|
+
((stringp data)
|
69
|
+
(encode-string data stream))
|
70
|
+
((is-byte-array data)
|
71
|
+
(encode-raw-bytes data stream))
|
72
|
+
((or (consp data) (vectorp data))
|
73
|
+
(encode-array data stream))
|
74
|
+
((hash-table-p data)
|
75
|
+
(encode-hash data stream))
|
76
|
+
((symbolp data)
|
77
|
+
(encode-string (symbol-name data) stream))
|
78
|
+
(t (error "Cannot encode data."))))
|
79
|
+
|
80
|
+
(defun encode-string (data stream)
|
81
|
+
(encode-raw-bytes (babel:string-to-octets data) stream))
|
82
|
+
|
83
|
+
#+sbcl (defun sbcl-encode-float (data stream)
|
84
|
+
(cond ((equal (type-of data) 'single-float)
|
85
|
+
(write-byte #xca stream)
|
86
|
+
(store-big-endian (sb-kernel:single-float-bits data) stream 4))
|
87
|
+
((equal (type-of data) 'double-float)
|
88
|
+
(write-byte #xcb stream)
|
89
|
+
(store-big-endian (sb-kernel:double-float-high-bits data) stream 4)
|
90
|
+
(store-big-endian (sb-kernel:double-float-low-bits data) stream 4)))
|
91
|
+
t)
|
92
|
+
|
93
|
+
(defun encode-float (data stream)
|
94
|
+
(or #+sbcl (sbcl-encode-float data stream)
|
95
|
+
#-(or sbcl) (error "No floating point support yet.")))
|
96
|
+
|
97
|
+
(defun encode-each (data stream &optional (encoder #'encode-stream))
|
98
|
+
(cond ((hash-table-p data)
|
99
|
+
(maphash (lambda (key value)
|
100
|
+
(funcall encoder key stream)
|
101
|
+
(funcall encoder value stream))
|
102
|
+
data))
|
103
|
+
((or (vectorp data) (consp data))
|
104
|
+
(mapc (lambda (subdata)
|
105
|
+
(funcall encoder subdata stream))
|
106
|
+
(coerce data 'list)))
|
107
|
+
(t (error "Not sequence or hash table."))))
|
108
|
+
|
109
|
+
(defun encode-sequence (data stream
|
110
|
+
short-prefix short-length
|
111
|
+
typecode-16 typecode-32
|
112
|
+
&optional (encoder #'encode-stream))
|
113
|
+
(let ((len (if (hash-table-p data)
|
114
|
+
(hash-table-count data)
|
115
|
+
(length data))))
|
116
|
+
(cond ((<= 0 len short-length)
|
117
|
+
(write-byte (+ short-prefix len) stream)
|
118
|
+
(encode-each data stream encoder))
|
119
|
+
((<= 0 len 65535)
|
120
|
+
(write-byte typecode-16 stream)
|
121
|
+
(store-big-endian len stream 2)
|
122
|
+
(encode-each data stream encoder))
|
123
|
+
((<= 0 len (1- (expt 2 32)))
|
124
|
+
(write-byte typecode-32 stream)
|
125
|
+
(store-big-endian len stream 4)
|
126
|
+
(encode-each data stream encoder)))))
|
127
|
+
|
128
|
+
(defun encode-hash (data stream)
|
129
|
+
(encode-sequence data stream #x80 15 #xdc #xdd))
|
130
|
+
|
131
|
+
(defun encode-array (data stream)
|
132
|
+
(encode-sequence data stream #x90 15 #xdc #xdd))
|
133
|
+
|
134
|
+
(defun encode-raw-bytes (data stream)
|
135
|
+
(encode-sequence data stream #xa0 31 #xda #xdb #'write-byte))
|
136
|
+
|
137
|
+
(defun encode-integer (data stream)
|
138
|
+
(cond ((<= 0 data 127) (write-byte data stream))
|
139
|
+
((<= -32 data -1) (write-byte (sb8->ub8 data) stream))
|
140
|
+
((<= 0 data 255)
|
141
|
+
(write-byte #xcc stream)
|
142
|
+
(write-byte data stream))
|
143
|
+
((<= 0 data 65535)
|
144
|
+
(write-byte #xcd stream)
|
145
|
+
(store-big-endian data stream 2))
|
146
|
+
((<= 0 data (1- (expt 2 32)))
|
147
|
+
(write-byte #xce stream)
|
148
|
+
(store-big-endian data stream 4))
|
149
|
+
((<= 0 data (1- (expt 2 64)))
|
150
|
+
(write-byte #xcf stream)
|
151
|
+
(store-big-endian data stream 8))
|
152
|
+
((<= -128 data 127)
|
153
|
+
(write-byte #xd0 stream)
|
154
|
+
(write-byte (sb8->ub8 data) stream))
|
155
|
+
((<= -32768 data 32767)
|
156
|
+
(write-byte #xd1 stream)
|
157
|
+
(write-byte (sb16->ub16 data) stream))
|
158
|
+
((<= (- (expt 2 31)) data (1- (expt 2 31)))
|
159
|
+
(write-byte #xd2 stream)
|
160
|
+
(write-byte (sb32->ub32 data) stream))
|
161
|
+
((<= (- (expt 2 63)) data (1- (expt 2 63)))
|
162
|
+
(write-byte #xd3 stream)
|
163
|
+
(write-byte (sb64->ub64 data) stream))
|
164
|
+
(t (error "Integer too large or too small."))))
|
165
|
+
|
166
|
+
(defun store-big-endian (number stream byte-count)
|
167
|
+
(let (byte-list)
|
168
|
+
(loop
|
169
|
+
while (> number 0)
|
170
|
+
do
|
171
|
+
(push (rem number 256)
|
172
|
+
byte-list)
|
173
|
+
(setf number (ash number -8)))
|
174
|
+
(loop
|
175
|
+
while (< (length byte-list) byte-count)
|
176
|
+
do (push 0 byte-list))
|
177
|
+
(when (> (length byte-list) byte-count)
|
178
|
+
(error "Number too large."))
|
179
|
+
(write-sequence byte-list stream)))
|
180
|
+
|
181
|
+
(defun decode (byte-array)
|
182
|
+
(flexi-streams:with-input-from-sequence (stream byte-array)
|
183
|
+
(decode-stream stream)))
|
184
|
+
|
185
|
+
(defun decode-stream (stream)
|
186
|
+
(let ((byte (read-byte stream)))
|
187
|
+
(cond ((= 0 (ldb (byte 1 7) byte))
|
188
|
+
byte)
|
189
|
+
((= 7 (ldb (byte 3 5) byte))
|
190
|
+
(ub8->sb8 byte))
|
191
|
+
((= #xcc byte)
|
192
|
+
(read-byte stream))
|
193
|
+
((= #xcd byte)
|
194
|
+
(load-big-endian stream 2))
|
195
|
+
((= #xce byte)
|
196
|
+
(load-big-endian stream 4))
|
197
|
+
((= #xcf byte)
|
198
|
+
(load-big-endian stream 8))
|
199
|
+
((= #xd0 byte)
|
200
|
+
(ub8->sb8 (read-byte stream)))
|
201
|
+
((= #xd1 byte)
|
202
|
+
(ub16->sb16 (load-big-endian stream 2)))
|
203
|
+
((= #xd2 byte)
|
204
|
+
(ub32->sb32 (load-big-endian stream 4)))
|
205
|
+
((= #xd3 byte)
|
206
|
+
(ub64->sb64 (load-big-endian stream 8)))
|
207
|
+
((= #xc0 byte)
|
208
|
+
nil)
|
209
|
+
((= #xc3 byte)
|
210
|
+
t)
|
211
|
+
((= #xc2 byte)
|
212
|
+
nil)
|
213
|
+
((= #xca byte)
|
214
|
+
(or #+sbcl (sb-kernel:make-single-float (load-big-endian stream 4))
|
215
|
+
#-(or sbcl) (error "No floating point support yet.")))
|
216
|
+
((= #xcb byte)
|
217
|
+
(or #+sbcl (sb-kernel:make-double-float (load-big-endian stream 4)
|
218
|
+
(load-big-endian stream 4))
|
219
|
+
#-(or sbcl) (error "No floating point support yet.")))
|
220
|
+
((= 5 (ldb (byte 3 5) byte))
|
221
|
+
(decode-raw-sequence (ldb (byte 5 0) byte) stream))
|
222
|
+
((= #xda byte)
|
223
|
+
(decode-raw-sequence (load-big-endian stream 2) stream))
|
224
|
+
((= #xdb byte)
|
225
|
+
(decode-raw-sequence (load-big-endian stream 4) stream))
|
226
|
+
((= 9 (ldb (byte 4 4) byte))
|
227
|
+
(decode-array (- byte #x90) stream))
|
228
|
+
((= #xdc byte)
|
229
|
+
(decode-array (load-big-endian stream 2) stream))
|
230
|
+
((= #xdd byte)
|
231
|
+
(decode-array (load-big-endian stream 4) stream))
|
232
|
+
((= 8 (ldb (byte 4 4) byte))
|
233
|
+
(decode-map (- byte #x80) stream))
|
234
|
+
((= #xde byte)
|
235
|
+
(decode-map (load-big-endian stream 2) stream))
|
236
|
+
((= #xdf byte)
|
237
|
+
(decode-map (load-big-endian stream 4) stream)))))
|
238
|
+
|
239
|
+
(defun decode-map (length stream)
|
240
|
+
(let ((hash-table (make-hash-table :test #'equal)))
|
241
|
+
(loop repeat length
|
242
|
+
do (let ((key (decode-stream stream))
|
243
|
+
(value (decode-stream stream)))
|
244
|
+
(setf (gethash key hash-table) value)))
|
245
|
+
hash-table))
|
246
|
+
|
247
|
+
(defun decode-array (length stream)
|
248
|
+
(let ((array (make-array length)))
|
249
|
+
(dotimes (i length)
|
250
|
+
(setf (aref array i) (decode-stream stream)))
|
251
|
+
array))
|
252
|
+
|
253
|
+
(defun decode-raw-sequence (length stream)
|
254
|
+
(let ((seq (make-array length :element-type '(mod 256))))
|
255
|
+
(read-sequence seq stream)
|
256
|
+
(babel:octets-to-string seq)))
|
257
|
+
|
258
|
+
(defun load-big-endian (stream byte-count)
|
259
|
+
(let ((result 0))
|
260
|
+
(loop
|
261
|
+
repeat byte-count
|
262
|
+
do (setf result (+ (ash result 8)
|
263
|
+
(read-byte stream))))
|
264
|
+
result))
|
@@ -0,0 +1,254 @@
|
|
1
|
+
#lang racket/base
|
2
|
+
|
3
|
+
(require (for-syntax syntax/parse racket/syntax racket)
|
4
|
+
ffi/unsafe racket/function racket/string
|
5
|
+
"start.rkt" "c.rkt")
|
6
|
+
|
7
|
+
(struct jtype (signature tag predicate ctype racket->java java->racket))
|
8
|
+
(struct jtype/object jtype (class))
|
9
|
+
(struct jtype/vector jtype/object (element))
|
10
|
+
(struct jvector (cpointer type length))
|
11
|
+
(struct jprocedure (args return proc))
|
12
|
+
|
13
|
+
(define ((single-compose f1 f2) e) (f1 (f2 e)))
|
14
|
+
|
15
|
+
(define (make-jtype obj racket->java java->racket)
|
16
|
+
(let ([composed-racket->java (single-compose (jtype-racket->java obj) racket->java)]
|
17
|
+
[composed-java->racket (single-compose java->racket (jtype-java->racket obj))])
|
18
|
+
; due to limitation in racket's struct-copy
|
19
|
+
(cond
|
20
|
+
[(jtype/vector? obj)
|
21
|
+
(struct-copy jtype/vector obj
|
22
|
+
[racket->java #:parent jtype composed-racket->java]
|
23
|
+
[java->racket #:parent jtype composed-java->racket])]
|
24
|
+
[(jtype/object? obj)
|
25
|
+
(struct-copy jtype/object obj
|
26
|
+
[racket->java #:parent jtype composed-racket->java]
|
27
|
+
[java->racket #:parent jtype composed-java->racket])]
|
28
|
+
[else
|
29
|
+
(struct-copy jtype obj
|
30
|
+
[racket->java composed-racket->java]
|
31
|
+
[java->racket composed-java->racket])])))
|
32
|
+
|
33
|
+
(define (jtype->ctype obj)
|
34
|
+
(make-ctype (jtype-ctype obj) (jtype-racket->java obj) (jtype-java->racket obj)))
|
35
|
+
|
36
|
+
; --- signature makers ---
|
37
|
+
(define (make-class-signature c) (string-append "L" c ";"))
|
38
|
+
(define (make-vector-signature s) (string-append "[" s))
|
39
|
+
(define (make-signature args return)
|
40
|
+
(let ([args-signature (string-append* (map jtype-signature args))]
|
41
|
+
[return-signature (jtype-signature return)])
|
42
|
+
(string-append "(" args-signature ")" return-signature)))
|
43
|
+
|
44
|
+
; --- predicates for java types on racket ---
|
45
|
+
(require (only-in web-server/dispatch/extend make-coerce-safe?) srfi/26/cut)
|
46
|
+
|
47
|
+
(define jboolean? boolean?)
|
48
|
+
(define jbyte? byte?)
|
49
|
+
(define jchar? char?)
|
50
|
+
(define jshort? (make-coerce-safe? (cut < -32768 <> 32767)))
|
51
|
+
(define jint? (make-coerce-safe? (cut < -2147483648 <> 2147483647)))
|
52
|
+
(define jlong? (make-coerce-safe? (cut < -9223372036854775808 <> 9223372036854775807)))
|
53
|
+
(define jfloat? single-flonum?)
|
54
|
+
(define jdouble? flonum?)
|
55
|
+
(define jstring? string?)
|
56
|
+
(define ((make-jobject-predicate clss) o) (instance-of? o clss))
|
57
|
+
(define ((make-jlist-predicate element?) o) (andmap element? o))
|
58
|
+
|
59
|
+
; --- java types ---
|
60
|
+
(define _jboolean (jtype "Z" 'boolean jboolean? __jboolean #f #f))
|
61
|
+
(define _jbyte (jtype "B" 'byte jbyte? __jbyte #f #f))
|
62
|
+
(define _jchar (jtype "C" 'char jchar? __jchar char->integer integer->char))
|
63
|
+
(define _jshort (jtype "S" 'short jshort? __jshort #f #f))
|
64
|
+
(define _jint (jtype "I" 'int jint? __jint #f #f))
|
65
|
+
(define _jlong (jtype "J" 'long jlong? __jlong #f #f))
|
66
|
+
(define _jfloat (jtype "F" 'float jfloat? __jfloat #f #f))
|
67
|
+
(define _jdouble (jtype "D" 'double jdouble? __jdouble #f #f))
|
68
|
+
(define _jvoid (jtype "V" 'void #f __jvoid #f #f))
|
69
|
+
; hack for _jobject and _jlist so that they dual as a jtype and function
|
70
|
+
(define _jobject
|
71
|
+
((λ ()
|
72
|
+
(struct _jobject jtype/object ()
|
73
|
+
#:property prop:procedure
|
74
|
+
(λ (self class-name [racket->java #f] [java->racket #f] [predicate #f])
|
75
|
+
(let ([class-id (find-class class-name)])
|
76
|
+
(struct-copy jtype/object self
|
77
|
+
[signature #:parent jtype (make-class-signature class-name)]
|
78
|
+
[predicate #:parent jtype (or predicate (make-jobject-predicate class-id))]
|
79
|
+
[racket->java #:parent jtype racket->java]
|
80
|
+
[java->racket #:parent jtype java->racket]
|
81
|
+
[class class-id]))))
|
82
|
+
(let ([class-id (find-class "Ljava/lang/Object;")])
|
83
|
+
(_jobject "Ljava/lang/Object;" 'object (make-jobject-predicate class-id)
|
84
|
+
__jobject #f #f class-id)))))
|
85
|
+
(define _jstring (_jobject "java/lang/String" new-string get-string jstring?))
|
86
|
+
(define _jlist
|
87
|
+
((λ ()
|
88
|
+
(struct _jlist jtype/vector ()
|
89
|
+
#:property prop:procedure
|
90
|
+
(λ (self element)
|
91
|
+
(define-values (make-array array-ref array-set!) (tag->array-info (jtype-tag element)))
|
92
|
+
(when (jtype/object? element)
|
93
|
+
(let ([clss (jtype/object-class element)])
|
94
|
+
(set! make-array (λ (n) (new-object-array n clss #f)))))
|
95
|
+
(let* ([signature (make-vector-signature (jtype-signature element))]
|
96
|
+
[element-racket->java (or (jtype-racket->java element) identity)]
|
97
|
+
[element-java->racket (or (jtype-java->racket element) identity)]
|
98
|
+
[element? (or (jtype-predicate element) (λ (_) #t))])
|
99
|
+
(struct-copy jtype/vector self
|
100
|
+
[signature #:parent jtype signature]
|
101
|
+
[predicate #:parent jtype (make-jlist-predicate element?)]
|
102
|
+
[ctype #:parent jtype __jobject]
|
103
|
+
[racket->java #:parent jtype
|
104
|
+
(λ (c)
|
105
|
+
(let ([array (make-array (length c))])
|
106
|
+
(for ([e (in-list c)] [i (in-naturals)])
|
107
|
+
(array-set! array i (element-racket->java e)))
|
108
|
+
array))]
|
109
|
+
[java->racket #:parent jtype
|
110
|
+
(λ (c)
|
111
|
+
(for/list ([i (in-range (get-array-length c))])
|
112
|
+
(element-java->racket (array-ref c i))))]
|
113
|
+
[class #:parent jtype/object (find-class signature)]
|
114
|
+
[element element]))))
|
115
|
+
(let ([class-id (find-class "[Ljava/lang/Object;")]
|
116
|
+
[element-class-id (jtype/object-class _jobject)])
|
117
|
+
(_jlist "[Ljava/lang/Object;" 'object (make-jobject-predicate element-class-id) __jobject
|
118
|
+
(λ (c)
|
119
|
+
(let ([array (new-object-array (length c) element-class-id #f)])
|
120
|
+
(for ([e (in-list c)]
|
121
|
+
[i (in-naturals)])
|
122
|
+
(set-object-array-element array i e))
|
123
|
+
array))
|
124
|
+
(λ (c)
|
125
|
+
(for/list ([i (in-range (get-array-length c))])
|
126
|
+
(get-object-array-element c i)))
|
127
|
+
class-id
|
128
|
+
_jobject)))))
|
129
|
+
(define-syntax (_jmethod stx)
|
130
|
+
(define-syntax-class type #:literals (->)
|
131
|
+
(pattern (~and x (~not (~or (~literal ...) ->)))))
|
132
|
+
(syntax-parse stx #:literals (->)
|
133
|
+
[(_ arg:type ... (~optional (~seq farg:type (~literal ...))) (~optional (~seq -> return*)))
|
134
|
+
(with-syntax* ([(arg* ...) (generate-temporaries #'(arg ...))]
|
135
|
+
[(larg ... . marg) #`(arg* ... #,@(if (attribute farg) #'arg-rest #`()))]
|
136
|
+
[(aarg ...) #`(arg* ... #,@(if (attribute farg) #'(arg-rest) #`()))]
|
137
|
+
[return (if (attribute return*) #'return* #'_jvoid)])
|
138
|
+
#`(let* ([args (list arg ... #,@(if (attribute farg) #`((_jlist farg)) #`()))])
|
139
|
+
(jprocedure args return
|
140
|
+
(λ (type jnienv clss method func)
|
141
|
+
(case type
|
142
|
+
[(constructor) (λ (larg ... . marg) (func jnienv clss method aarg ...))]
|
143
|
+
[(static-method) (λ (larg ... . marg) (func jnienv clss method aarg ...))]
|
144
|
+
[(method) (λ (o larg ... . marg) (func jnienv o method aarg ...))]
|
145
|
+
[else (error '_jmethod "invalid type provided")])))))]))
|
146
|
+
; dynamic and slower version of _jmethod
|
147
|
+
(define (_jprocedure args return #:repeat-last-arg? [repeat-last-arg? #f])
|
148
|
+
(define (nest-at lst i)
|
149
|
+
(if (null? lst) (list null)
|
150
|
+
(let loop ([lst lst] [i i])
|
151
|
+
(cond [(null? lst) null]
|
152
|
+
[(zero? i) (list lst)]
|
153
|
+
[else (cons (car lst) (loop (cdr lst) (sub1 i)))]))))
|
154
|
+
(jprocedure args return
|
155
|
+
(if repeat-last-arg?
|
156
|
+
(let ([repeat-position (sub1 (length args))])
|
157
|
+
(λ (type jnienv clss method func)
|
158
|
+
(case type
|
159
|
+
[(constructor) (λ larg (apply func jnienv clss method (nest-at larg repeat-position)))]
|
160
|
+
[(static-method) (λ larg (apply func jnienv clss method (nest-at larg repeat-position)))]
|
161
|
+
[(method) (λ (o . larg) (apply func jnienv o method (nest-at larg repeat-position)))])))
|
162
|
+
(λ (type jnienv clss method func)
|
163
|
+
(case type
|
164
|
+
[(constructor) (λ larg (apply func jnienv clss method larg))]
|
165
|
+
[(static-method) (λ larg (apply func jnienv clss method larg))]
|
166
|
+
[(method) (λ (o . larg) (apply func jnienv o method larg))]
|
167
|
+
[else (error '_jprocedure "invalid type provided")])))))
|
168
|
+
; get-jmethod/get-jconstructor pass the following arguments (type jnienv class method func)
|
169
|
+
; to a function created by _jmethod or _jprocedure
|
170
|
+
; according to the type the function returns one of the following functions
|
171
|
+
; | constructor (λ (args ...) ; doesn't need to take in an object and the class is static
|
172
|
+
; | static-method (λ (args ...) ; same reasoning as above
|
173
|
+
; | method (λ (object args ...)
|
174
|
+
|
175
|
+
|
176
|
+
; --- interfacing with java methods ---
|
177
|
+
(define (get-jconstructor class-id type)
|
178
|
+
(let* ([args (jprocedure-args type)]
|
179
|
+
[return (jprocedure-return type)]
|
180
|
+
[proc (jprocedure-proc type)]
|
181
|
+
[signature (make-signature args return)]
|
182
|
+
[method-id (get-method-id class-id "<init>" signature)]
|
183
|
+
[ffi-func (get-jrffi-obj "new-object"
|
184
|
+
(_cprocedure (list* __jnienv __jclass __jmethodID (map jtype->ctype args))
|
185
|
+
__jobject))])
|
186
|
+
(proc 'constructor current-jnienv class-id method-id ffi-func)))
|
187
|
+
|
188
|
+
(define (get-jmethod class-id method-name type #:static? [static? #f])
|
189
|
+
(let* ([args (jprocedure-args type)]
|
190
|
+
[return (jprocedure-return type)]
|
191
|
+
[proc (jprocedure-proc type)]
|
192
|
+
[signature (make-signature args return)]
|
193
|
+
[method-id (get-method-id class-id method-name signature #:static? static?)]
|
194
|
+
[type (if static? 'static-method 'method)]
|
195
|
+
[ffi-func (get-jrffi-obj
|
196
|
+
(format "call-~a~a-method" (if static? "static-" "") (jtype-tag return))
|
197
|
+
(_cprocedure (append (list __jnienv (if static? __jclass __jobject)
|
198
|
+
__jmethodID) (map jtype->ctype args))
|
199
|
+
(jtype->ctype return)))])
|
200
|
+
(proc type current-jnienv class-id method-id ffi-func)))
|
201
|
+
|
202
|
+
|
203
|
+
; --- interfacing with java fields ---
|
204
|
+
(define (get-jaccessor class-id field-name type #:static? [static? #f])
|
205
|
+
(let* ([signature (jtype-signature class-id field-name (jtype-signature type))]
|
206
|
+
[field-id (get-field-id class-id field-name signature #:static? static?)]
|
207
|
+
[ffi-func (get-jrffi-obj
|
208
|
+
(format "get-~a~a-field" (if static? "static-" "") (jtype-tag type))
|
209
|
+
(_cprocedure (list __jnienv (if static? __jclass __jobject) __jfieldID) type))])
|
210
|
+
(if static? (λ () (ffi-func current-jnienv class-id field-id))
|
211
|
+
(λ (obj) (ffi-func current-jnienv obj field-id)))))
|
212
|
+
|
213
|
+
(define (get-jmutator class-id field-name type #:static? [static? #f])
|
214
|
+
(let* ([signature (jtype-signature class-id field-name (jtype-signature type))]
|
215
|
+
[field-id (get-field-id class-id field-name signature #:static? static?)]
|
216
|
+
[ffi-func (get-jrffi-obj
|
217
|
+
(format "set-~a~a-field" (if static? "static-" "") (jtype-tag type))
|
218
|
+
(_cprocedure (list __jnienv (if static? __jclass __jobject) __jfieldID type) type))])
|
219
|
+
(if static? (λ (new-value) (ffi-func current-jnienv class-id field-id new-value))
|
220
|
+
(λ (obj new-value) (ffi-func current-jnienv obj field-id new-value)))))
|
221
|
+
|
222
|
+
(define (get-jparameter class-id field-name type #:static? [static? #f])
|
223
|
+
(let* ([accessor (get-jaccessor class-id field-name type #:static? static?)]
|
224
|
+
[mutator (get-jmutator class-id field-name type #:static? static?)])
|
225
|
+
(if static?
|
226
|
+
(case-lambda
|
227
|
+
[() (accessor)]
|
228
|
+
[(new-value) (mutator new-value)])
|
229
|
+
(case-lambda
|
230
|
+
[(obj) (accessor obj)]
|
231
|
+
[(obj new-value) (mutator obj new-value)]))))
|
232
|
+
|
233
|
+
|
234
|
+
|
235
|
+
(provide _jboolean _jbyte _jchar _jshort _jint _jlong _jfloat _jdouble _jvoid
|
236
|
+
_jobject _jstring _jlist)
|
237
|
+
|
238
|
+
(provide get-jconstructor get-jmethod get-jparameter get-jmutator get-jaccessor)
|
239
|
+
|
240
|
+
;(provide instance-of? (rename-out [find-class find-class]) get-method-id get-field-id)
|
241
|
+
|
242
|
+
|
243
|
+
(provide (all-defined-out) : -> current-jnienv)
|
244
|
+
|
245
|
+
|
246
|
+
|
247
|
+
|
248
|
+
|
249
|
+
|
250
|
+
|
251
|
+
|
252
|
+
|
253
|
+
|
254
|
+
|