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.
Files changed (139) hide show
  1. data/LICENSE +1 -1
  2. data/README.md +4 -9
  3. data/lib/clucumber/clucumber-bootstrap.lisp +32 -0
  4. data/lib/clucumber/vendor/cl-interpol/alias.lisp +55 -0
  5. data/lib/clucumber/vendor/cl-interpol/cl-interpol.asd +56 -0
  6. data/lib/clucumber/vendor/cl-interpol/load.lisp +53 -0
  7. data/lib/clucumber/vendor/cl-interpol/packages.lisp +40 -0
  8. data/lib/clucumber/vendor/cl-interpol/read.lisp +716 -0
  9. data/lib/clucumber/vendor/cl-interpol/specials.lisp +113 -0
  10. data/lib/clucumber/vendor/cl-interpol/test/packages.lisp +34 -0
  11. data/lib/clucumber/vendor/cl-interpol/test/tests.lisp +128 -0
  12. data/lib/clucumber/vendor/cl-interpol/test.lisp +177 -0
  13. data/lib/clucumber/vendor/cl-interpol/test2.lisp +6254 -0
  14. data/lib/clucumber/vendor/cl-interpol/unicode.lisp +13912 -0
  15. data/lib/clucumber/vendor/cl-interpol/util.lisp +122 -0
  16. data/lib/clucumber/vendor/cl-ppcre/api.lisp +1262 -0
  17. data/lib/clucumber/vendor/cl-ppcre/charmap.lisp +152 -0
  18. data/lib/clucumber/vendor/cl-ppcre/charset.lisp +242 -0
  19. data/lib/clucumber/vendor/cl-ppcre/chartest.lisp +98 -0
  20. data/lib/clucumber/vendor/cl-ppcre/cl-ppcre-test.asd +34 -0
  21. data/lib/clucumber/vendor/cl-ppcre/cl-ppcre-unicode/packages.lisp +38 -0
  22. data/lib/clucumber/vendor/cl-ppcre/cl-ppcre-unicode/resolver.lisp +61 -0
  23. data/lib/clucumber/vendor/cl-ppcre/cl-ppcre-unicode.asd +58 -0
  24. data/lib/clucumber/vendor/cl-ppcre/cl-ppcre.asd +79 -0
  25. data/lib/clucumber/vendor/cl-ppcre/closures.lisp +471 -0
  26. data/lib/clucumber/vendor/cl-ppcre/convert.lisp +875 -0
  27. data/lib/clucumber/vendor/cl-ppcre/errors.lisp +84 -0
  28. data/lib/clucumber/vendor/cl-ppcre/lexer.lisp +737 -0
  29. data/lib/clucumber/vendor/cl-ppcre/lispworks-defsystem.lisp +57 -0
  30. data/lib/clucumber/vendor/cl-ppcre/load.lisp +67 -0
  31. data/lib/clucumber/vendor/cl-ppcre/optimize.lisp +578 -0
  32. data/lib/clucumber/vendor/cl-ppcre/packages.lisp +68 -0
  33. data/lib/clucumber/vendor/cl-ppcre/parser.lisp +319 -0
  34. data/lib/clucumber/vendor/cl-ppcre/ppcre-tests.lisp +269 -0
  35. data/lib/clucumber/vendor/cl-ppcre/regex-class-util.lisp +555 -0
  36. data/lib/clucumber/vendor/cl-ppcre/regex-class.lisp +259 -0
  37. data/lib/clucumber/vendor/cl-ppcre/repetition-closures.lisp +833 -0
  38. data/lib/clucumber/vendor/cl-ppcre/scanner.lisp +506 -0
  39. data/lib/clucumber/vendor/cl-ppcre/specials.lisp +172 -0
  40. data/lib/clucumber/vendor/cl-ppcre/test/packages.lisp +37 -0
  41. data/lib/clucumber/vendor/cl-ppcre/test/perl-tests.lisp +150 -0
  42. data/lib/clucumber/vendor/cl-ppcre/test/tests.lisp +159 -0
  43. data/lib/clucumber/vendor/cl-ppcre/test/unicode-tests.lisp +80 -0
  44. data/lib/clucumber/vendor/cl-ppcre/util.lisp +201 -0
  45. data/lib/clucumber/vendor/cl-unicode/alias.lisp +135 -0
  46. data/lib/clucumber/vendor/cl-unicode/api.lisp +412 -0
  47. data/lib/clucumber/vendor/cl-unicode/build/char-info.lisp +133 -0
  48. data/lib/clucumber/vendor/cl-unicode/build/dump.lisp +239 -0
  49. data/lib/clucumber/vendor/cl-unicode/build/read.lisp +280 -0
  50. data/lib/clucumber/vendor/cl-unicode/build/util.lisp +182 -0
  51. data/lib/clucumber/vendor/cl-unicode/cl-unicode.asd +90 -0
  52. data/lib/clucumber/vendor/cl-unicode/conditions.lisp +54 -0
  53. data/lib/clucumber/vendor/cl-unicode/derived.lisp +120 -0
  54. data/lib/clucumber/vendor/cl-unicode/hash-tables.lisp +20 -0
  55. data/lib/clucumber/vendor/cl-unicode/lists.lisp +10 -0
  56. data/lib/clucumber/vendor/cl-unicode/methods.lisp +15 -0
  57. data/lib/clucumber/vendor/cl-unicode/packages.lisp +76 -0
  58. data/lib/clucumber/vendor/cl-unicode/specials.lisp +135 -0
  59. data/lib/clucumber/vendor/cl-unicode/test/packages.lisp +34 -0
  60. data/lib/clucumber/vendor/cl-unicode/test/tests.lisp +150 -0
  61. data/lib/clucumber/vendor/cl-unicode/test-functions.lisp +94 -0
  62. data/lib/clucumber/vendor/cl-unicode/util.lisp +274 -0
  63. data/lib/clucumber/vendor/lift/compare/fiveam-tests.lisp +14 -0
  64. data/lib/clucumber/vendor/lift/compare/lift-tests.lisp +13 -0
  65. data/lib/clucumber/vendor/lift/compare/rt-tests.lisp +16 -0
  66. data/lib/clucumber/vendor/lift/compare/xlunit-tests.lisp +15 -0
  67. data/lib/clucumber/vendor/lift/dev/changes.lisp +61 -0
  68. data/lib/clucumber/vendor/lift/dev/config.lisp +354 -0
  69. data/lib/clucumber/vendor/lift/dev/copy-file.lisp +117 -0
  70. data/lib/clucumber/vendor/lift/dev/introspection.lisp +232 -0
  71. data/lib/clucumber/vendor/lift/dev/lift-interface.lisp +56 -0
  72. data/lib/clucumber/vendor/lift/dev/lift-notes.lisp +202 -0
  73. data/lib/clucumber/vendor/lift/dev/lift-randomized.lisp +45 -0
  74. data/lib/clucumber/vendor/lift/dev/lift.lisp +2383 -0
  75. data/lib/clucumber/vendor/lift/dev/macros.lisp +229 -0
  76. data/lib/clucumber/vendor/lift/dev/measuring.lisp +156 -0
  77. data/lib/clucumber/vendor/lift/dev/packages.lisp +161 -0
  78. data/lib/clucumber/vendor/lift/dev/port.lisp +151 -0
  79. data/lib/clucumber/vendor/lift/dev/prototypes.lisp +282 -0
  80. data/lib/clucumber/vendor/lift/dev/random-testing.lisp +124 -0
  81. data/lib/clucumber/vendor/lift/dev/report-locations.lisp +13 -0
  82. data/lib/clucumber/vendor/lift/dev/reports.lisp +916 -0
  83. data/lib/clucumber/vendor/lift/dev/utilities.lisp +242 -0
  84. data/lib/clucumber/vendor/lift/docs/package.lisp +6 -0
  85. data/lib/clucumber/vendor/lift/docs/setup.lisp +17 -0
  86. data/lib/clucumber/vendor/lift/examples/basic-examples.lisp +289 -0
  87. data/lib/clucumber/vendor/lift/examples/random-testing.lisp +32 -0
  88. data/lib/clucumber/vendor/lift/lift-documentation.asd +28 -0
  89. data/lib/clucumber/vendor/lift/lift-test.asd +35 -0
  90. data/lib/clucumber/vendor/lift/lift.asd +77 -0
  91. data/lib/clucumber/vendor/lift/test/equality-tests.lisp +40 -0
  92. data/lib/clucumber/vendor/lift/test/finding-tests.lisp +32 -0
  93. data/lib/clucumber/vendor/lift/test/lift-test.lisp +783 -0
  94. data/lib/clucumber/vendor/lift/test/order-of-operations.lisp +54 -0
  95. data/lib/clucumber/vendor/lift/test/packages.lisp +17 -0
  96. data/lib/clucumber/vendor/lift/test/test-config-files.lisp +20 -0
  97. data/lib/clucumber/vendor/lift/test/test-dynamic-variables.lisp +57 -0
  98. data/lib/clucumber/vendor/lift/test/test-maximum-problems.lisp +74 -0
  99. data/lib/clucumber/vendor/lift/test/test-prototypes.lisp +278 -0
  100. data/lib/clucumber/vendor/lift/test/test-timeout.lisp +37 -0
  101. data/lib/clucumber/vendor/lift/test/tests-in-progress.lisp +62 -0
  102. data/lib/clucumber/vendor/lift/test/testsuite-expects.lisp +60 -0
  103. data/lib/clucumber/vendor/lift/timeout/package.lisp +13 -0
  104. data/lib/clucumber/vendor/lift/timeout/with-timeout.lisp +123 -0
  105. data/lib/clucumber/vendor/lift/website/stuff/Temp.lisp +34 -0
  106. data/lib/clucumber/vendor/st-json/st-json.asd +3 -0
  107. data/lib/clucumber/vendor/st-json/st-json.lisp +310 -0
  108. data/lib/clucumber/vendor/trivial-backtrace/dev/backtrace.lisp +127 -0
  109. data/lib/clucumber/vendor/trivial-backtrace/dev/fallback.lisp +10 -0
  110. data/lib/clucumber/vendor/trivial-backtrace/dev/map-backtrace.lisp +103 -0
  111. data/lib/clucumber/vendor/trivial-backtrace/dev/mucking.lisp +75 -0
  112. data/lib/clucumber/vendor/trivial-backtrace/dev/packages.lisp +13 -0
  113. data/lib/clucumber/vendor/trivial-backtrace/dev/utilities.lisp +104 -0
  114. data/lib/clucumber/vendor/trivial-backtrace/test/packages.lisp +5 -0
  115. data/lib/clucumber/vendor/trivial-backtrace/test/test-setup.lisp +4 -0
  116. data/lib/clucumber/vendor/trivial-backtrace/test/tests.lisp +16 -0
  117. data/lib/clucumber/vendor/trivial-backtrace/trivial-backtrace-test.asd +22 -0
  118. data/lib/clucumber/vendor/trivial-backtrace/trivial-backtrace.asd +35 -0
  119. data/lib/clucumber/vendor/usocket/backend/allegro.lisp +199 -0
  120. data/lib/clucumber/vendor/usocket/backend/armedbear.lisp +491 -0
  121. data/lib/clucumber/vendor/usocket/backend/clisp.lisp +260 -0
  122. data/lib/clucumber/vendor/usocket/backend/cmucl.lisp +266 -0
  123. data/lib/clucumber/vendor/usocket/backend/lispworks.lisp +741 -0
  124. data/lib/clucumber/vendor/usocket/backend/mcl.lisp +369 -0
  125. data/lib/clucumber/vendor/usocket/backend/openmcl.lisp +206 -0
  126. data/lib/clucumber/vendor/usocket/backend/sbcl.lisp +424 -0
  127. data/lib/clucumber/vendor/usocket/backend/scl.lisp +261 -0
  128. data/lib/clucumber/vendor/usocket/condition.lisp +227 -0
  129. data/lib/clucumber/vendor/usocket/package.lisp +82 -0
  130. data/lib/clucumber/vendor/usocket/server.lisp +45 -0
  131. data/lib/clucumber/vendor/usocket/test/package.lisp +13 -0
  132. data/lib/clucumber/vendor/usocket/test/test-usocket.lisp +166 -0
  133. data/lib/clucumber/vendor/usocket/usocket-test.asd +26 -0
  134. data/lib/clucumber/vendor/usocket/usocket.asd +37 -0
  135. data/lib/clucumber/vendor/usocket/usocket.lisp +542 -0
  136. data/lib/clucumber/vendor/usocket/vendor/kqueue.lisp +1 -0
  137. data/lib/clucumber/vendor/usocket/vendor/split-sequence.lisp +245 -0
  138. data/lib/clucumber.rb +29 -7
  139. 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))))