clucumber 0.1.1 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/LICENSE +1 -1
- data/README.md +4 -9
- data/lib/clucumber/clucumber-bootstrap.lisp +32 -0
- data/lib/clucumber/vendor/cl-interpol/alias.lisp +55 -0
- data/lib/clucumber/vendor/cl-interpol/cl-interpol.asd +56 -0
- data/lib/clucumber/vendor/cl-interpol/load.lisp +53 -0
- data/lib/clucumber/vendor/cl-interpol/packages.lisp +40 -0
- data/lib/clucumber/vendor/cl-interpol/read.lisp +716 -0
- data/lib/clucumber/vendor/cl-interpol/specials.lisp +113 -0
- data/lib/clucumber/vendor/cl-interpol/test/packages.lisp +34 -0
- data/lib/clucumber/vendor/cl-interpol/test/tests.lisp +128 -0
- data/lib/clucumber/vendor/cl-interpol/test.lisp +177 -0
- data/lib/clucumber/vendor/cl-interpol/test2.lisp +6254 -0
- data/lib/clucumber/vendor/cl-interpol/unicode.lisp +13912 -0
- data/lib/clucumber/vendor/cl-interpol/util.lisp +122 -0
- data/lib/clucumber/vendor/cl-ppcre/api.lisp +1262 -0
- data/lib/clucumber/vendor/cl-ppcre/charmap.lisp +152 -0
- data/lib/clucumber/vendor/cl-ppcre/charset.lisp +242 -0
- data/lib/clucumber/vendor/cl-ppcre/chartest.lisp +98 -0
- data/lib/clucumber/vendor/cl-ppcre/cl-ppcre-test.asd +34 -0
- data/lib/clucumber/vendor/cl-ppcre/cl-ppcre-unicode/packages.lisp +38 -0
- data/lib/clucumber/vendor/cl-ppcre/cl-ppcre-unicode/resolver.lisp +61 -0
- data/lib/clucumber/vendor/cl-ppcre/cl-ppcre-unicode.asd +58 -0
- data/lib/clucumber/vendor/cl-ppcre/cl-ppcre.asd +79 -0
- data/lib/clucumber/vendor/cl-ppcre/closures.lisp +471 -0
- data/lib/clucumber/vendor/cl-ppcre/convert.lisp +875 -0
- data/lib/clucumber/vendor/cl-ppcre/errors.lisp +84 -0
- data/lib/clucumber/vendor/cl-ppcre/lexer.lisp +737 -0
- data/lib/clucumber/vendor/cl-ppcre/lispworks-defsystem.lisp +57 -0
- data/lib/clucumber/vendor/cl-ppcre/load.lisp +67 -0
- data/lib/clucumber/vendor/cl-ppcre/optimize.lisp +578 -0
- data/lib/clucumber/vendor/cl-ppcre/packages.lisp +68 -0
- data/lib/clucumber/vendor/cl-ppcre/parser.lisp +319 -0
- data/lib/clucumber/vendor/cl-ppcre/ppcre-tests.lisp +269 -0
- data/lib/clucumber/vendor/cl-ppcre/regex-class-util.lisp +555 -0
- data/lib/clucumber/vendor/cl-ppcre/regex-class.lisp +259 -0
- data/lib/clucumber/vendor/cl-ppcre/repetition-closures.lisp +833 -0
- data/lib/clucumber/vendor/cl-ppcre/scanner.lisp +506 -0
- data/lib/clucumber/vendor/cl-ppcre/specials.lisp +172 -0
- data/lib/clucumber/vendor/cl-ppcre/test/packages.lisp +37 -0
- data/lib/clucumber/vendor/cl-ppcre/test/perl-tests.lisp +150 -0
- data/lib/clucumber/vendor/cl-ppcre/test/tests.lisp +159 -0
- data/lib/clucumber/vendor/cl-ppcre/test/unicode-tests.lisp +80 -0
- data/lib/clucumber/vendor/cl-ppcre/util.lisp +201 -0
- data/lib/clucumber/vendor/cl-unicode/alias.lisp +135 -0
- data/lib/clucumber/vendor/cl-unicode/api.lisp +412 -0
- data/lib/clucumber/vendor/cl-unicode/build/char-info.lisp +133 -0
- data/lib/clucumber/vendor/cl-unicode/build/dump.lisp +239 -0
- data/lib/clucumber/vendor/cl-unicode/build/read.lisp +280 -0
- data/lib/clucumber/vendor/cl-unicode/build/util.lisp +182 -0
- data/lib/clucumber/vendor/cl-unicode/cl-unicode.asd +90 -0
- data/lib/clucumber/vendor/cl-unicode/conditions.lisp +54 -0
- data/lib/clucumber/vendor/cl-unicode/derived.lisp +120 -0
- data/lib/clucumber/vendor/cl-unicode/hash-tables.lisp +20 -0
- data/lib/clucumber/vendor/cl-unicode/lists.lisp +10 -0
- data/lib/clucumber/vendor/cl-unicode/methods.lisp +15 -0
- data/lib/clucumber/vendor/cl-unicode/packages.lisp +76 -0
- data/lib/clucumber/vendor/cl-unicode/specials.lisp +135 -0
- data/lib/clucumber/vendor/cl-unicode/test/packages.lisp +34 -0
- data/lib/clucumber/vendor/cl-unicode/test/tests.lisp +150 -0
- data/lib/clucumber/vendor/cl-unicode/test-functions.lisp +94 -0
- data/lib/clucumber/vendor/cl-unicode/util.lisp +274 -0
- data/lib/clucumber/vendor/lift/compare/fiveam-tests.lisp +14 -0
- data/lib/clucumber/vendor/lift/compare/lift-tests.lisp +13 -0
- data/lib/clucumber/vendor/lift/compare/rt-tests.lisp +16 -0
- data/lib/clucumber/vendor/lift/compare/xlunit-tests.lisp +15 -0
- data/lib/clucumber/vendor/lift/dev/changes.lisp +61 -0
- data/lib/clucumber/vendor/lift/dev/config.lisp +354 -0
- data/lib/clucumber/vendor/lift/dev/copy-file.lisp +117 -0
- data/lib/clucumber/vendor/lift/dev/introspection.lisp +232 -0
- data/lib/clucumber/vendor/lift/dev/lift-interface.lisp +56 -0
- data/lib/clucumber/vendor/lift/dev/lift-notes.lisp +202 -0
- data/lib/clucumber/vendor/lift/dev/lift-randomized.lisp +45 -0
- data/lib/clucumber/vendor/lift/dev/lift.lisp +2383 -0
- data/lib/clucumber/vendor/lift/dev/macros.lisp +229 -0
- data/lib/clucumber/vendor/lift/dev/measuring.lisp +156 -0
- data/lib/clucumber/vendor/lift/dev/packages.lisp +161 -0
- data/lib/clucumber/vendor/lift/dev/port.lisp +151 -0
- data/lib/clucumber/vendor/lift/dev/prototypes.lisp +282 -0
- data/lib/clucumber/vendor/lift/dev/random-testing.lisp +124 -0
- data/lib/clucumber/vendor/lift/dev/report-locations.lisp +13 -0
- data/lib/clucumber/vendor/lift/dev/reports.lisp +916 -0
- data/lib/clucumber/vendor/lift/dev/utilities.lisp +242 -0
- data/lib/clucumber/vendor/lift/docs/package.lisp +6 -0
- data/lib/clucumber/vendor/lift/docs/setup.lisp +17 -0
- data/lib/clucumber/vendor/lift/examples/basic-examples.lisp +289 -0
- data/lib/clucumber/vendor/lift/examples/random-testing.lisp +32 -0
- data/lib/clucumber/vendor/lift/lift-documentation.asd +28 -0
- data/lib/clucumber/vendor/lift/lift-test.asd +35 -0
- data/lib/clucumber/vendor/lift/lift.asd +77 -0
- data/lib/clucumber/vendor/lift/test/equality-tests.lisp +40 -0
- data/lib/clucumber/vendor/lift/test/finding-tests.lisp +32 -0
- data/lib/clucumber/vendor/lift/test/lift-test.lisp +783 -0
- data/lib/clucumber/vendor/lift/test/order-of-operations.lisp +54 -0
- data/lib/clucumber/vendor/lift/test/packages.lisp +17 -0
- data/lib/clucumber/vendor/lift/test/test-config-files.lisp +20 -0
- data/lib/clucumber/vendor/lift/test/test-dynamic-variables.lisp +57 -0
- data/lib/clucumber/vendor/lift/test/test-maximum-problems.lisp +74 -0
- data/lib/clucumber/vendor/lift/test/test-prototypes.lisp +278 -0
- data/lib/clucumber/vendor/lift/test/test-timeout.lisp +37 -0
- data/lib/clucumber/vendor/lift/test/tests-in-progress.lisp +62 -0
- data/lib/clucumber/vendor/lift/test/testsuite-expects.lisp +60 -0
- data/lib/clucumber/vendor/lift/timeout/package.lisp +13 -0
- data/lib/clucumber/vendor/lift/timeout/with-timeout.lisp +123 -0
- data/lib/clucumber/vendor/lift/website/stuff/Temp.lisp +34 -0
- data/lib/clucumber/vendor/st-json/st-json.asd +3 -0
- data/lib/clucumber/vendor/st-json/st-json.lisp +310 -0
- data/lib/clucumber/vendor/trivial-backtrace/dev/backtrace.lisp +127 -0
- data/lib/clucumber/vendor/trivial-backtrace/dev/fallback.lisp +10 -0
- data/lib/clucumber/vendor/trivial-backtrace/dev/map-backtrace.lisp +103 -0
- data/lib/clucumber/vendor/trivial-backtrace/dev/mucking.lisp +75 -0
- data/lib/clucumber/vendor/trivial-backtrace/dev/packages.lisp +13 -0
- data/lib/clucumber/vendor/trivial-backtrace/dev/utilities.lisp +104 -0
- data/lib/clucumber/vendor/trivial-backtrace/test/packages.lisp +5 -0
- data/lib/clucumber/vendor/trivial-backtrace/test/test-setup.lisp +4 -0
- data/lib/clucumber/vendor/trivial-backtrace/test/tests.lisp +16 -0
- data/lib/clucumber/vendor/trivial-backtrace/trivial-backtrace-test.asd +22 -0
- data/lib/clucumber/vendor/trivial-backtrace/trivial-backtrace.asd +35 -0
- data/lib/clucumber/vendor/usocket/backend/allegro.lisp +199 -0
- data/lib/clucumber/vendor/usocket/backend/armedbear.lisp +491 -0
- data/lib/clucumber/vendor/usocket/backend/clisp.lisp +260 -0
- data/lib/clucumber/vendor/usocket/backend/cmucl.lisp +266 -0
- data/lib/clucumber/vendor/usocket/backend/lispworks.lisp +741 -0
- data/lib/clucumber/vendor/usocket/backend/mcl.lisp +369 -0
- data/lib/clucumber/vendor/usocket/backend/openmcl.lisp +206 -0
- data/lib/clucumber/vendor/usocket/backend/sbcl.lisp +424 -0
- data/lib/clucumber/vendor/usocket/backend/scl.lisp +261 -0
- data/lib/clucumber/vendor/usocket/condition.lisp +227 -0
- data/lib/clucumber/vendor/usocket/package.lisp +82 -0
- data/lib/clucumber/vendor/usocket/server.lisp +45 -0
- data/lib/clucumber/vendor/usocket/test/package.lisp +13 -0
- data/lib/clucumber/vendor/usocket/test/test-usocket.lisp +166 -0
- data/lib/clucumber/vendor/usocket/usocket-test.asd +26 -0
- data/lib/clucumber/vendor/usocket/usocket.asd +37 -0
- data/lib/clucumber/vendor/usocket/usocket.lisp +542 -0
- data/lib/clucumber/vendor/usocket/vendor/kqueue.lisp +1 -0
- data/lib/clucumber/vendor/usocket/vendor/split-sequence.lisp +245 -0
- data/lib/clucumber.rb +29 -7
- metadata +151 -5
|
@@ -0,0 +1,491 @@
|
|
|
1
|
+
;;;; $Id: armedbear.lisp 515 2010-01-07 18:26:06Z ctian $
|
|
2
|
+
;;;; $URL: svn://common-lisp.net/project/usocket/svn/usocket/trunk/backend/armedbear.lisp $
|
|
3
|
+
|
|
4
|
+
;;;; See LICENSE for licensing information.
|
|
5
|
+
|
|
6
|
+
(in-package :usocket)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
;;; Proposed contribution to the JAVA package
|
|
10
|
+
|
|
11
|
+
(defpackage :jdi
|
|
12
|
+
(:use :cl)
|
|
13
|
+
(:export #:jcoerce
|
|
14
|
+
#:jop-deref
|
|
15
|
+
#:do-jmethod-call
|
|
16
|
+
#:do-jmethod
|
|
17
|
+
#:do-jstatic-call
|
|
18
|
+
#:do-jstatic
|
|
19
|
+
#:do-jnew-call
|
|
20
|
+
#:do-jfield
|
|
21
|
+
#:jequals))
|
|
22
|
+
;; but still requires the :java package.
|
|
23
|
+
|
|
24
|
+
(in-package :jdi)
|
|
25
|
+
|
|
26
|
+
(defstruct (java-object-proxy (:conc-name :jop-)
|
|
27
|
+
:copier)
|
|
28
|
+
value
|
|
29
|
+
class)
|
|
30
|
+
|
|
31
|
+
(defvar *jm-get-return-type*
|
|
32
|
+
(java:jmethod "java.lang.reflect.Method" "getReturnType"))
|
|
33
|
+
|
|
34
|
+
(defvar *jf-get-type*
|
|
35
|
+
(java:jmethod "java.lang.reflect.Field" "getType"))
|
|
36
|
+
|
|
37
|
+
(defvar *jc-get-declaring-class*
|
|
38
|
+
(java:jmethod "java.lang.reflect.Constructor" "getDeclaringClass"))
|
|
39
|
+
|
|
40
|
+
(declaim (inline make-return-type-proxy))
|
|
41
|
+
(defun make-return-type-proxy (jmethod jreturned-value)
|
|
42
|
+
(if (java:java-object-p jreturned-value)
|
|
43
|
+
(let ((rt (java:jcall *jm-get-return-type* jmethod)))
|
|
44
|
+
(make-java-object-proxy :value jreturned-value
|
|
45
|
+
:class rt))
|
|
46
|
+
jreturned-value))
|
|
47
|
+
|
|
48
|
+
(defun make-field-type-proxy (jfield jreturned-value)
|
|
49
|
+
(if (java:java-object-p jreturned-value)
|
|
50
|
+
(let ((rt (java:jcall *jf-get-type* jfield)))
|
|
51
|
+
(make-java-object-proxy :value jreturned-value
|
|
52
|
+
:class rt))
|
|
53
|
+
jreturned-value))
|
|
54
|
+
|
|
55
|
+
(defun make-constructor-type-proxy (jconstructor jreturned-value)
|
|
56
|
+
(if (java:java-object-p jreturned-value)
|
|
57
|
+
(let ((rt (java:jcall *jc-get-declaring-class* jconstructor)))
|
|
58
|
+
(make-java-object-proxy :value jreturned-value
|
|
59
|
+
:class rt))
|
|
60
|
+
jreturned-value))
|
|
61
|
+
|
|
62
|
+
(defun jcoerce (instance &optional output-type-spec)
|
|
63
|
+
(cond
|
|
64
|
+
((java-object-proxy-p instance)
|
|
65
|
+
(let ((new-instance (copy-structure (the java-object-proxy instance))))
|
|
66
|
+
(setf (jop-class new-instance)
|
|
67
|
+
(java:jclass output-type-spec))
|
|
68
|
+
new-instance))
|
|
69
|
+
((java:java-object-p instance)
|
|
70
|
+
(make-java-object-proxy :class (java:jclass output-type-spec)
|
|
71
|
+
:value instance))
|
|
72
|
+
((stringp instance)
|
|
73
|
+
(make-java-object-proxy :class "java.lang.String"
|
|
74
|
+
:value instance))
|
|
75
|
+
((keywordp output-type-spec)
|
|
76
|
+
;; all that remains is creating an immediate type...
|
|
77
|
+
(let ((jval (java:make-immediate-object instance output-type-spec)))
|
|
78
|
+
(make-java-object-proxy :class output-type-spec
|
|
79
|
+
:value jval)))
|
|
80
|
+
))
|
|
81
|
+
|
|
82
|
+
(defun jtype-of (instance) ;;instance must be a jop
|
|
83
|
+
(cond
|
|
84
|
+
((stringp instance)
|
|
85
|
+
"java.lang.String")
|
|
86
|
+
((keywordp (jop-class instance))
|
|
87
|
+
(string-downcase (symbol-name (jop-class instance))))
|
|
88
|
+
(t
|
|
89
|
+
(java:jclass-name (jop-class instance)))))
|
|
90
|
+
|
|
91
|
+
(declaim (inline jop-deref))
|
|
92
|
+
(defun jop-deref (instance)
|
|
93
|
+
(if (java-object-proxy-p instance)
|
|
94
|
+
(jop-value instance)
|
|
95
|
+
instance))
|
|
96
|
+
|
|
97
|
+
(defun java-value-and-class (object)
|
|
98
|
+
(values (jop-deref object)
|
|
99
|
+
(jtype-of object)))
|
|
100
|
+
|
|
101
|
+
(defun do-jmethod-call (object method-name &rest arguments)
|
|
102
|
+
(multiple-value-bind
|
|
103
|
+
(instance class-name)
|
|
104
|
+
(java-value-and-class object)
|
|
105
|
+
(let* ((argument-types (mapcar #'jtype-of arguments))
|
|
106
|
+
(jm (apply #'java:jmethod class-name method-name argument-types))
|
|
107
|
+
(rv (apply #'java:jcall jm instance
|
|
108
|
+
(mapcar #'jop-deref arguments))))
|
|
109
|
+
(make-return-type-proxy jm rv))))
|
|
110
|
+
|
|
111
|
+
(defun do-jstatic-call (class-name method-name &rest arguments)
|
|
112
|
+
(let* ((argument-types (mapcar #'jtype-of arguments))
|
|
113
|
+
(jm (apply #'java:jmethod class-name method-name argument-types))
|
|
114
|
+
(rv (apply #'java:jstatic jm (java:jclass class-name)
|
|
115
|
+
(mapcar #'jop-deref arguments))))
|
|
116
|
+
(make-return-type-proxy jm rv)))
|
|
117
|
+
|
|
118
|
+
(defun do-jnew-call (class-name &rest arguments)
|
|
119
|
+
(let* ((argument-types (mapcar #'jtype-of arguments))
|
|
120
|
+
(jm (apply #'java:jconstructor class-name argument-types))
|
|
121
|
+
(rv (apply #'java:jnew jm (mapcar #'jop-deref arguments))))
|
|
122
|
+
(make-constructor-type-proxy jm rv)))
|
|
123
|
+
|
|
124
|
+
(defun do-jfield (class-or-instance-or-name field-name)
|
|
125
|
+
(let* ((class (cond
|
|
126
|
+
((stringp class-or-instance-or-name)
|
|
127
|
+
(java:jclass class-or-instance-or-name))
|
|
128
|
+
((java:java-object-p class-or-instance-or-name)
|
|
129
|
+
(java:jclass-of class-or-instance-or-name))
|
|
130
|
+
((java-object-proxy-p class-or-instance-or-name)
|
|
131
|
+
(java:jclass (jtype-of class-or-instance-or-name)))))
|
|
132
|
+
(jf (java:jcall (java:jmethod "java.lang.Class" "getField"
|
|
133
|
+
"java.lang.String")
|
|
134
|
+
class field-name)))
|
|
135
|
+
(make-field-type-proxy jf
|
|
136
|
+
(java:jfield class field-name)))) ;;class))))
|
|
137
|
+
|
|
138
|
+
(defmacro do-jstatic (&rest arguments)
|
|
139
|
+
`(do-jstatic-call ,@arguments))
|
|
140
|
+
|
|
141
|
+
(defmacro do-jmethod (&rest arguments)
|
|
142
|
+
`(do-jmethod-call ,@arguments))
|
|
143
|
+
|
|
144
|
+
;;
|
|
145
|
+
|
|
146
|
+
(defmacro jstatic-call (class-name (method-name &rest arg-spec)
|
|
147
|
+
&rest args)
|
|
148
|
+
(let ((class-sym (gensym)))
|
|
149
|
+
`(let ((,class-sym ,class-name))
|
|
150
|
+
(java:jstatic
|
|
151
|
+
(java:jmethod ,class-sym ,method-name ,@arg-spec)
|
|
152
|
+
(java:jclass ,class-sym) ,@args))))
|
|
153
|
+
|
|
154
|
+
(defmacro jmethod-call (instance-and-class (method &rest arg-spec) &rest args)
|
|
155
|
+
(let ((isym (gensym)))
|
|
156
|
+
(multiple-value-bind
|
|
157
|
+
(instance class-name)
|
|
158
|
+
(if (listp instance-and-class)
|
|
159
|
+
(values (first instance-and-class)
|
|
160
|
+
(second instance-and-class))
|
|
161
|
+
(values instance-and-class))
|
|
162
|
+
(when (null class-name)
|
|
163
|
+
(setf class-name `(java:jclass-name (java:jclass-of ,isym))))
|
|
164
|
+
`(let* ((,isym ,instance))
|
|
165
|
+
(java:jcall (java:jmethod ,class-name ,method ,@arg-spec)
|
|
166
|
+
,isym ,@args)))))
|
|
167
|
+
|
|
168
|
+
(defun jequals (x y)
|
|
169
|
+
(do-jmethod-call (jcoerce x "java.lang.Object") "equals"
|
|
170
|
+
(jcoerce y "java.lang.Object")))
|
|
171
|
+
|
|
172
|
+
(defmacro jnew-call ((class &rest arg-spec) &rest args)
|
|
173
|
+
`(java:jnew (java:jconstructor ,class ,@arg-spec)
|
|
174
|
+
,@args))
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
(in-package :usocket)
|
|
179
|
+
|
|
180
|
+
(defun get-host-name ()
|
|
181
|
+
(jdi:do-jmethod-call (jdi:do-jstatic-call "java.net.InetAddress"
|
|
182
|
+
"getLocalHost")
|
|
183
|
+
"getHostName"))
|
|
184
|
+
|
|
185
|
+
(defun handle-condition (condition &optional socket)
|
|
186
|
+
(typecase condition
|
|
187
|
+
(error (error 'unknown-error :socket socket :real-error condition))))
|
|
188
|
+
|
|
189
|
+
(defun socket-connect (host port &key (protocol :stream) (element-type 'character)
|
|
190
|
+
timeout deadline (nodelay nil nodelay-specified)
|
|
191
|
+
local-host local-port)
|
|
192
|
+
(when deadline (unsupported 'deadline 'socket-connect))
|
|
193
|
+
|
|
194
|
+
(let ((usock))
|
|
195
|
+
(with-mapped-conditions (usock)
|
|
196
|
+
(let* ((sock-addr (when (and host port)
|
|
197
|
+
(jdi:jcoerce
|
|
198
|
+
(jdi:do-jnew-call "java.net.InetSocketAddress"
|
|
199
|
+
(host-to-hostname host)
|
|
200
|
+
(jdi:jcoerce port :int))
|
|
201
|
+
"java.net.SocketAddress")))
|
|
202
|
+
(local-addr (when (or local-host local-port)
|
|
203
|
+
(jdi:jcoerce
|
|
204
|
+
(jdi:do-jnew-call "java.net.InetSocketAddress"
|
|
205
|
+
(host-to-hostname (or host *wildcard-host*))
|
|
206
|
+
(jdi:jcoerce (or port *auto-port*) :int))
|
|
207
|
+
"java.net.SocketAddress")))
|
|
208
|
+
(jchan (jdi:do-jstatic-call (ecase protocol
|
|
209
|
+
(:stream "java.nio.channels.SocketChannel")
|
|
210
|
+
(:datagram "java.nio.channels.DatagramChannel"))
|
|
211
|
+
"open"))
|
|
212
|
+
(sock (jdi:do-jmethod-call jchan "socket")))
|
|
213
|
+
;; TODO: Fix it
|
|
214
|
+
(when (or local-host local-port)
|
|
215
|
+
(jdi:do-jmethod-call sock "bind" local-addr))
|
|
216
|
+
(when (and host port)
|
|
217
|
+
(jdi:do-jmethod-call jchan "connect" sock-addr))
|
|
218
|
+
(when (and (eq protocol 'stream) nodelay-specified)
|
|
219
|
+
(jdi:do-jmethod-call sock "setTcpNoDelay"
|
|
220
|
+
(if nodelay
|
|
221
|
+
(java:make-immediate-object t :boolean)
|
|
222
|
+
(java:make-immediate-object nil :boolean))))
|
|
223
|
+
(when timeout
|
|
224
|
+
(jdi:do-jmethod-call sock "setSoTimeout"
|
|
225
|
+
(truncate (* 1000 timeout))))
|
|
226
|
+
(setf usock
|
|
227
|
+
(ecase protocol
|
|
228
|
+
(:stream
|
|
229
|
+
(make-stream-socket
|
|
230
|
+
:socket jchan
|
|
231
|
+
:stream (ext:get-socket-stream (jdi:jop-deref sock)
|
|
232
|
+
:element-type element-type)))
|
|
233
|
+
(:datagram
|
|
234
|
+
(make-datagram-socket jchan))))))))
|
|
235
|
+
|
|
236
|
+
(defun socket-listen (host port
|
|
237
|
+
&key reuseaddress
|
|
238
|
+
(reuse-address nil reuse-address-supplied-p)
|
|
239
|
+
(backlog 5)
|
|
240
|
+
(element-type 'character))
|
|
241
|
+
(let* ((reuseaddress (if reuse-address-supplied-p reuse-address reuseaddress))
|
|
242
|
+
(sock-addr (jdi:do-jnew-call "java.net.InetSocketAddress"
|
|
243
|
+
(host-to-hostname host)
|
|
244
|
+
(jdi:jcoerce port :int)))
|
|
245
|
+
(chan (jdi:do-jstatic-call "java.nio.channels.ServerSocketChannel"
|
|
246
|
+
"open"))
|
|
247
|
+
(sock (jdi:do-jmethod-call chan "socket")))
|
|
248
|
+
(when reuseaddress
|
|
249
|
+
(with-mapped-conditions ()
|
|
250
|
+
(jdi:do-jmethod-call sock
|
|
251
|
+
"setReuseAddress"
|
|
252
|
+
(jdi:jcoerce reuseaddress :boolean))))
|
|
253
|
+
(with-mapped-conditions ()
|
|
254
|
+
(jdi:do-jmethod-call sock
|
|
255
|
+
"bind"
|
|
256
|
+
(jdi:jcoerce sock-addr
|
|
257
|
+
"java.net.SocketAddress")
|
|
258
|
+
(jdi:jcoerce backlog :int)))
|
|
259
|
+
(make-stream-server-socket chan :element-type element-type)))
|
|
260
|
+
|
|
261
|
+
(defmethod socket-accept ((socket stream-server-usocket) &key element-type)
|
|
262
|
+
(let* ((jsock (socket socket))
|
|
263
|
+
(jacc-chan (with-mapped-conditions (socket)
|
|
264
|
+
(jdi:do-jmethod-call jsock "accept")))
|
|
265
|
+
(jacc-stream
|
|
266
|
+
(ext:get-socket-stream (jdi:jop-deref
|
|
267
|
+
(jdi:do-jmethod-call jacc-chan "socket"))
|
|
268
|
+
:element-type (or element-type
|
|
269
|
+
(element-type socket)))))
|
|
270
|
+
(make-stream-socket :socket jacc-chan
|
|
271
|
+
:stream jacc-stream)))
|
|
272
|
+
|
|
273
|
+
;;(defun print-java-exception (e)
|
|
274
|
+
;; (let* ((native-exception (java-exception-cause e)))
|
|
275
|
+
;; (print (jcall (jmethod "java.net.BindException" "getMessage") native-exception))))
|
|
276
|
+
|
|
277
|
+
(defmethod socket-close ((usocket usocket))
|
|
278
|
+
(when (wait-list usocket)
|
|
279
|
+
(remove-waiter (wait-list usocket) usocket))
|
|
280
|
+
(with-mapped-conditions (usocket)
|
|
281
|
+
(jdi:do-jmethod (socket usocket) "close")))
|
|
282
|
+
|
|
283
|
+
;; Socket streams are different objects than
|
|
284
|
+
;; socket streams. Closing the stream flushes
|
|
285
|
+
;; its buffers *and* closes the socket.
|
|
286
|
+
(defmethod socket-close ((usocket stream-usocket))
|
|
287
|
+
(when (wait-list usocket)
|
|
288
|
+
(remove-waiter (wait-list usocket) usocket))
|
|
289
|
+
(with-mapped-conditions (usocket)
|
|
290
|
+
(close (socket-stream usocket))))
|
|
291
|
+
|
|
292
|
+
(defmethod get-local-address ((usocket usocket))
|
|
293
|
+
(dotted-quad-to-vector-quad (ext:socket-local-address
|
|
294
|
+
(jdi:jop-deref
|
|
295
|
+
(jdi:do-jmethod-call (socket usocket)
|
|
296
|
+
"socket")))))
|
|
297
|
+
|
|
298
|
+
(defmethod get-peer-address ((usocket stream-usocket))
|
|
299
|
+
(dotted-quad-to-vector-quad (ext:socket-peer-address
|
|
300
|
+
(jdi:jop-deref
|
|
301
|
+
(jdi:do-jmethod-call (socket usocket)
|
|
302
|
+
"socket")))))
|
|
303
|
+
|
|
304
|
+
(defmethod get-local-port ((usocket usocket))
|
|
305
|
+
(ext:socket-local-port (jdi:jop-deref
|
|
306
|
+
(jdi:do-jmethod-call (socket usocket) "socket"))))
|
|
307
|
+
|
|
308
|
+
(defmethod get-peer-port ((usocket stream-usocket))
|
|
309
|
+
(ext:socket-peer-port (jdi:jop-deref
|
|
310
|
+
(jdi:do-jmethod-call (socket usocket) "socket"))))
|
|
311
|
+
|
|
312
|
+
(defmethod get-local-name ((usocket usocket))
|
|
313
|
+
(values (get-local-address usocket)
|
|
314
|
+
(get-local-port usocket)))
|
|
315
|
+
|
|
316
|
+
(defmethod get-peer-name ((usocket stream-usocket))
|
|
317
|
+
(values (get-peer-address usocket)
|
|
318
|
+
(get-peer-port usocket)))
|
|
319
|
+
|
|
320
|
+
|
|
321
|
+
#|
|
|
322
|
+
Pseudo code version of what we're trying to do:
|
|
323
|
+
|
|
324
|
+
We're being called with 2 args:
|
|
325
|
+
|
|
326
|
+
- sockets (list)
|
|
327
|
+
- timeout (non-negative real)
|
|
328
|
+
|
|
329
|
+
Selector := java.nio.channels.Selector.open()
|
|
330
|
+
|
|
331
|
+
For all usockets
|
|
332
|
+
get the java socket
|
|
333
|
+
get its channel
|
|
334
|
+
register the channel with the selector
|
|
335
|
+
with ops (operations) OP_READ and OP_ACCEPT
|
|
336
|
+
|
|
337
|
+
make the selector wait trunc(timeout*1000) miliseconds,
|
|
338
|
+
unless (null timeout), because then:
|
|
339
|
+
selectNow()
|
|
340
|
+
|
|
341
|
+
retrieve the selectedKeys() set from the selector
|
|
342
|
+
unless select() returned 0 selected keys.
|
|
343
|
+
|
|
344
|
+
for set-iterator.hasNextKey()
|
|
345
|
+
with that key
|
|
346
|
+
retrieve the channel
|
|
347
|
+
retrieve the channel's socket
|
|
348
|
+
add the retrieved socket to the list of ready sockets
|
|
349
|
+
|
|
350
|
+
for all usockets
|
|
351
|
+
check if the associated java object
|
|
352
|
+
is in the list of ready sockets
|
|
353
|
+
it is? add it to the function result list
|
|
354
|
+
|
|
355
|
+
close() the selector
|
|
356
|
+
|
|
357
|
+
return the function result list.
|
|
358
|
+
|
|
359
|
+
|#
|
|
360
|
+
|
|
361
|
+
(defun op-read ()
|
|
362
|
+
(jdi:do-jfield "java.nio.channels.SelectionKey"
|
|
363
|
+
"OP_READ"))
|
|
364
|
+
|
|
365
|
+
(defun op-accept ()
|
|
366
|
+
(jdi:do-jfield "java.nio.channels.SelectionKey"
|
|
367
|
+
"OP_ACCEPT"))
|
|
368
|
+
|
|
369
|
+
(defun op-connect ()
|
|
370
|
+
(jdi:do-jfield "java.nio.channels.SelectionKey"
|
|
371
|
+
"OP_CONNECT"))
|
|
372
|
+
|
|
373
|
+
(defun valid-ops (jchannel)
|
|
374
|
+
(jdi:do-jmethod-call jchannel "validOps"))
|
|
375
|
+
|
|
376
|
+
(defun channel-class (jchannel)
|
|
377
|
+
(let ((valid-ops (valid-ops jchannel)))
|
|
378
|
+
(cond ((/= 0 (logand valid-ops (op-connect)))
|
|
379
|
+
"java.nio.channels.SocketChannel")
|
|
380
|
+
((/= 0 (logand valid-ops (op-accept)))
|
|
381
|
+
"java.nio.channels.ServerSocketChannel")
|
|
382
|
+
(t
|
|
383
|
+
"java.nio.channels.DatagramChannel"))))
|
|
384
|
+
|
|
385
|
+
(defun socket-channel-class (socket)
|
|
386
|
+
(cond
|
|
387
|
+
((stream-usocket-p socket)
|
|
388
|
+
"java.nio.channels.SocketChannel")
|
|
389
|
+
((stream-server-usocket-p socket)
|
|
390
|
+
"java.nio.channels.ServerSocketChannel")
|
|
391
|
+
((datagram-usocket-p socket)
|
|
392
|
+
"java.nio.channels.DatagramChannel")))
|
|
393
|
+
|
|
394
|
+
(defun wait-for-input-internal (wait-list &key timeout)
|
|
395
|
+
(let* ((sockets (wait-list-waiters wait-list))
|
|
396
|
+
(ops (logior (op-read) (op-accept)))
|
|
397
|
+
(selector (jdi:do-jstatic "java.nio.channels.Selector" "open"))
|
|
398
|
+
(channels (mapcar #'socket sockets)))
|
|
399
|
+
(unwind-protect
|
|
400
|
+
(with-mapped-conditions ()
|
|
401
|
+
(let ((sel (jdi:jop-deref selector)))
|
|
402
|
+
(dolist (channel channels)
|
|
403
|
+
(let ((chan (jdi:jop-deref channel)))
|
|
404
|
+
(java:jcall (java:jmethod "java.nio.channels.SelectableChannel"
|
|
405
|
+
"configureBlocking"
|
|
406
|
+
"boolean")
|
|
407
|
+
chan (java:make-immediate-object nil :boolean))
|
|
408
|
+
(java:jcall (java:jmethod "java.nio.channels.SelectableChannel"
|
|
409
|
+
"register"
|
|
410
|
+
"java.nio.channels.Selector" "int")
|
|
411
|
+
chan sel (logand ops (valid-ops channel)))))
|
|
412
|
+
(let ((ready-count
|
|
413
|
+
(java:jcall (java:jmethod "java.nio.channels.Selector"
|
|
414
|
+
"select"
|
|
415
|
+
"long")
|
|
416
|
+
sel (truncate (* timeout 1000)))))
|
|
417
|
+
(when (< 0 ready-count)
|
|
418
|
+
;; we actually have work to do
|
|
419
|
+
(let* ((selkeys (jdi:do-jmethod selector "selectedKeys"))
|
|
420
|
+
(selkey-iterator (jdi:do-jmethod selkeys "iterator"))
|
|
421
|
+
(%wait (wait-list-%wait wait-list)))
|
|
422
|
+
(loop while (java:jcall
|
|
423
|
+
(java:jmethod "java.util.Iterator" "hasNext")
|
|
424
|
+
(jdi:jop-deref selkey-iterator))
|
|
425
|
+
do (let* ((key (jdi:jcoerce
|
|
426
|
+
(jdi:do-jmethod selkey-iterator "next")
|
|
427
|
+
"java.nio.channels.SelectionKey"))
|
|
428
|
+
(chan (jdi:jop-deref
|
|
429
|
+
(jdi:do-jmethod key "channel"))))
|
|
430
|
+
(setf (state (gethash chan %wait))
|
|
431
|
+
:READ))))))))
|
|
432
|
+
;; close the selector: all keys will be deregistered
|
|
433
|
+
(java:jcall (java:jmethod "java.nio.channels.Selector" "close")
|
|
434
|
+
(jdi:jop-deref selector))
|
|
435
|
+
;; make all sockets blocking again.
|
|
436
|
+
(dolist (channel channels)
|
|
437
|
+
(java:jcall (java:jmethod "java.nio.channels.SelectableChannel"
|
|
438
|
+
"configureBlocking"
|
|
439
|
+
"boolean")
|
|
440
|
+
(jdi:jop-deref channel)
|
|
441
|
+
(java:make-immediate-object t :boolean))))))
|
|
442
|
+
|
|
443
|
+
|
|
444
|
+
;;
|
|
445
|
+
;;
|
|
446
|
+
;;
|
|
447
|
+
;; The WAIT-LIST part
|
|
448
|
+
;;
|
|
449
|
+
|
|
450
|
+
;;
|
|
451
|
+
;; Note that even though Java has the concept of the Selector class, which
|
|
452
|
+
;; remotely looks like a wait-list, it requires the sockets to be non-blocking.
|
|
453
|
+
;; usocket however doesn't make any such guarantees and is therefore unable to
|
|
454
|
+
;; use the concept outside of the waiting routine itself (blergh!).
|
|
455
|
+
;;
|
|
456
|
+
|
|
457
|
+
(defun %setup-wait-list (wl)
|
|
458
|
+
(setf (wait-list-%wait wl)
|
|
459
|
+
(make-hash-table :test #'equal :rehash-size 1.3d0)))
|
|
460
|
+
|
|
461
|
+
(defun %add-waiter (wl w)
|
|
462
|
+
(setf (gethash (jdi:jop-deref (socket w)) (wait-list-%wait wl))
|
|
463
|
+
w))
|
|
464
|
+
|
|
465
|
+
(defun %remove-waiter (wl w)
|
|
466
|
+
(remhash (socket w) (wait-list-%wait wl)))
|
|
467
|
+
|
|
468
|
+
;;
|
|
469
|
+
;; UDP support
|
|
470
|
+
;;
|
|
471
|
+
|
|
472
|
+
(defmethod socket-send ((socket datagram-usocket) buffer length &key host port)
|
|
473
|
+
(let ((jchan (socket socket)))
|
|
474
|
+
(let ((srcs (jdi:jcoerce buffer "java.nio.ByteBuffer"))
|
|
475
|
+
(offset (jdi:jcoerce 0 :int))
|
|
476
|
+
(length (jdi:jcoerce length :int)))
|
|
477
|
+
(if (and host port)
|
|
478
|
+
(let ((target (jdi:jcoerce
|
|
479
|
+
(jdi:do-jnew-call "java.net.InetSocketAddress"
|
|
480
|
+
(host-to-hostname host)
|
|
481
|
+
(jdi:jcoerce port :int))
|
|
482
|
+
"java.net.SocketAddress")))
|
|
483
|
+
;; how to use "length" argument here? --binghe, 2009/12/12
|
|
484
|
+
(jdi:do-jmethod-call jchan "send" buffer target))
|
|
485
|
+
(jdi:do-jmethod-call jchan "write" srcs offset length)))))
|
|
486
|
+
|
|
487
|
+
(defmethod socket-receive ((socket datagram-usocket) buffer length &key)
|
|
488
|
+
(let ((jchan (socket socket)))
|
|
489
|
+
(multiple-value-bind (buffer size host port)
|
|
490
|
+
0
|
|
491
|
+
(values buffer size host port))))
|