ionian 0.3.0 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/doc/Ionian/Socket.html +296 -51
- data/doc/Ionian.html +3 -4
- data/doc/created.rid +5 -4
- data/doc/index.html +5 -1
- data/doc/js/search_index.js +1 -1
- data/doc/table_of_contents.html +86 -25
- data/lib/ionian/extension/io.rb +165 -0
- data/lib/ionian/extension/socket.rb +40 -0
- data/lib/ionian/socket.rb +135 -25
- data/lib/ionian.rb +2 -1
- metadata +4 -3
- data/lib/ionian/io.rb +0 -155
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 81979c2c40c6fa759df1c49a2d5226edfb46ba18
|
4
|
+
data.tar.gz: 76e21b58efbdce773066a8f20c23f1a422df43e5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 239b709e5a1f3f112f238d01054d8e31d0b5f983ae4ef0093025f92573038f689ef1aa7f8425546afb7e53d8a8aac7e6d6d259a31bd38e023e3b78d433a06500
|
7
|
+
data.tar.gz: d8b5ab66d8ae1d31f0aa5d6046198eb34404e15af7711abce4ec09f43b1cecfcf16a0e0c71f31dee609ea8978081ad5369c1bd94787146f23de644f91c0bd5d9
|
data/doc/Ionian/Socket.html
CHANGED
@@ -4,7 +4,7 @@
|
|
4
4
|
<head>
|
5
5
|
<meta charset="UTF-8">
|
6
6
|
|
7
|
-
<title>
|
7
|
+
<title>class Ionian::Socket - RDoc Documentation</title>
|
8
8
|
|
9
9
|
<link href="../fonts.css" rel="stylesheet">
|
10
10
|
<link href="../rdoc.css" rel="stylesheet">
|
@@ -21,7 +21,7 @@
|
|
21
21
|
<script src="../js/darkfish.js"></script>
|
22
22
|
|
23
23
|
|
24
|
-
<body id="top" role="document" class="
|
24
|
+
<body id="top" role="document" class="class">
|
25
25
|
<nav role="navigation">
|
26
26
|
<div id="project-navigation">
|
27
27
|
<div id="home-section" role="banner" class="nav-section">
|
@@ -58,7 +58,14 @@
|
|
58
58
|
|
59
59
|
<div id="class-metadata">
|
60
60
|
|
61
|
-
|
61
|
+
<div id="parent-class-section" class="nav-section">
|
62
|
+
<h3>Parent</h3>
|
63
|
+
|
64
|
+
|
65
|
+
<p class="link">Object
|
66
|
+
|
67
|
+
</div>
|
68
|
+
|
62
69
|
|
63
70
|
<div id="extends-section" class="nav-section">
|
64
71
|
<h3>Extended With Modules</h3>
|
@@ -66,7 +73,7 @@
|
|
66
73
|
<ul class="link-list">
|
67
74
|
|
68
75
|
|
69
|
-
<li><a class="extend" href="
|
76
|
+
<li><a class="extend" href="Extension/Socket.html">Ionian::Extension::Socket</a>
|
70
77
|
|
71
78
|
|
72
79
|
</ul>
|
@@ -78,13 +85,25 @@
|
|
78
85
|
|
79
86
|
<ul class="link-list" role="directory">
|
80
87
|
|
81
|
-
<li ><a href="#method-c-
|
88
|
+
<li ><a href="#method-c-new">::new</a>
|
89
|
+
|
90
|
+
<li ><a href="#method-i-3C-3C">#<<</a>
|
91
|
+
|
92
|
+
<li ><a href="#method-i-closed-3F">#closed?</a>
|
93
|
+
|
94
|
+
<li ><a href="#method-i-cmd">#cmd</a>
|
95
|
+
|
96
|
+
<li ><a href="#method-i-flush">#flush</a>
|
97
|
+
|
98
|
+
<li ><a href="#method-i-has_data-3F">#has_data?</a>
|
82
99
|
|
83
|
-
<li ><a href="#method-i-
|
100
|
+
<li ><a href="#method-i-persistent-3F">#persistent?</a>
|
84
101
|
|
85
|
-
<li ><a href="#method-i-
|
102
|
+
<li ><a href="#method-i-protocol-3F">#protocol?</a>
|
86
103
|
|
87
|
-
<li ><a href="#method-i-
|
104
|
+
<li ><a href="#method-i-puts">#puts</a>
|
105
|
+
|
106
|
+
<li ><a href="#method-i-write">#write</a>
|
88
107
|
|
89
108
|
</ul>
|
90
109
|
</div>
|
@@ -92,21 +111,13 @@
|
|
92
111
|
</div>
|
93
112
|
</nav>
|
94
113
|
|
95
|
-
<main role="main" aria-labelledby="
|
96
|
-
<h1 id="
|
97
|
-
|
114
|
+
<main role="main" aria-labelledby="class-Ionian::Socket">
|
115
|
+
<h1 id="class-Ionian::Socket" class="class">
|
116
|
+
class Ionian::Socket
|
98
117
|
</h1>
|
99
118
|
|
100
119
|
<section class="description">
|
101
120
|
|
102
|
-
<p>A mixin for <a href="Socket.html">Socket</a> objects.</p>
|
103
|
-
|
104
|
-
<p>This module was designed to be extended by instantiated objects that
|
105
|
-
implement the standard library <a href="Socket.html">Socket</a> class.
|
106
|
-
my_socket.extend <a href="Socket.html">Ionian::Socket</a></p>
|
107
|
-
|
108
|
-
<p>Extending this module also extends <a href="IO.html">Ionian::IO</a>.</p>
|
109
|
-
|
110
121
|
</section>
|
111
122
|
|
112
123
|
|
@@ -128,11 +139,11 @@ my_socket.extend <a href="Socket.html">Ionian::Socket</a></p>
|
|
128
139
|
</header>
|
129
140
|
|
130
141
|
|
131
|
-
<div id="method-c-
|
142
|
+
<div id="method-c-new" class="method-detail ">
|
132
143
|
|
133
144
|
<div class="method-heading">
|
134
|
-
<span class="method-name">
|
135
|
-
class="method-args">(
|
145
|
+
<span class="method-name">new</span><span
|
146
|
+
class="method-args">(**kvargs)</span>
|
136
147
|
|
137
148
|
<span class="method-click-advice">click to toggle source</span>
|
138
149
|
|
@@ -141,16 +152,28 @@ my_socket.extend <a href="Socket.html">Ionian::Socket</a></p>
|
|
141
152
|
|
142
153
|
<div class="method-description">
|
143
154
|
|
144
|
-
<p>
|
155
|
+
<p>TODO NOTES</p>
|
156
|
+
|
157
|
+
<p>Always lazily instiantiate @socket, even when persistent? May not work with
|
158
|
+
forwarding method calls. Oh! Unless the forwarded methods check for @socket
|
159
|
+
to exist. Will persistent methods have to check for the socket not to be
|
160
|
+
closed as well?</p>
|
145
161
|
|
146
162
|
|
147
163
|
|
148
164
|
|
149
|
-
<div class="method-source-code" id="
|
165
|
+
<div class="method-source-code" id="new-source">
|
150
166
|
<pre><span class="ruby-comment"># File lib/ionian/socket.rb, line 15</span>
|
151
|
-
<span class="ruby-keyword">def</span> <span class="ruby-
|
152
|
-
<span class="ruby-
|
153
|
-
|
167
|
+
<span class="ruby-keyword">def</span> <span class="ruby-identifier">initialize</span>(<span class="ruby-operator">**</span><span class="ruby-identifier">kvargs</span>)
|
168
|
+
<span class="ruby-ivar">@socket</span> = <span class="ruby-keyword">nil</span>
|
169
|
+
|
170
|
+
<span class="ruby-ivar">@host</span> = <span class="ruby-identifier">kvargs</span>.<span class="ruby-identifier">fetch</span> <span class="ruby-value">:host</span>
|
171
|
+
<span class="ruby-ivar">@port</span> = <span class="ruby-identifier">kvargs</span>.<span class="ruby-identifier">fetch</span> <span class="ruby-value">:port</span>, <span class="ruby-value">23</span>
|
172
|
+
<span class="ruby-ivar">@expression</span> = <span class="ruby-identifier">kvargs</span>.<span class="ruby-identifier">fetch</span> <span class="ruby-value">:expression</span>, <span class="ruby-keyword">nil</span>
|
173
|
+
<span class="ruby-ivar">@protocol</span> = <span class="ruby-identifier">kvargs</span>.<span class="ruby-identifier">fetch</span> <span class="ruby-value">:protocol</span>, <span class="ruby-value">:tcp</span>
|
174
|
+
<span class="ruby-ivar">@persistent</span> = <span class="ruby-identifier">kvargs</span>.<span class="ruby-identifier">fetch</span> <span class="ruby-value">:persistent</span>, <span class="ruby-keyword">true</span>
|
175
|
+
|
176
|
+
<span class="ruby-identifier">create_socket</span> <span class="ruby-keyword">if</span> <span class="ruby-ivar">@persistent</span>
|
154
177
|
<span class="ruby-keyword">end</span></pre>
|
155
178
|
</div>
|
156
179
|
|
@@ -170,10 +193,38 @@ my_socket.extend <a href="Socket.html">Ionian::Socket</a></p>
|
|
170
193
|
</header>
|
171
194
|
|
172
195
|
|
173
|
-
<div id="method-i-
|
196
|
+
<div id="method-i-3C-3C" class="method-detail method-alias">
|
197
|
+
|
198
|
+
<div class="method-heading">
|
199
|
+
<span class="method-name"><<</span><span
|
200
|
+
class="method-args">(string)</span>
|
201
|
+
|
202
|
+
</div>
|
203
|
+
|
204
|
+
|
205
|
+
<div class="method-description">
|
206
|
+
|
207
|
+
|
208
|
+
|
209
|
+
|
210
|
+
|
211
|
+
|
212
|
+
</div>
|
213
|
+
|
214
|
+
|
215
|
+
|
216
|
+
|
217
|
+
<div class="aliases">
|
218
|
+
Alias for: <a href="Socket.html#method-i-write">write</a>
|
219
|
+
</div>
|
220
|
+
|
221
|
+
</div>
|
222
|
+
|
223
|
+
|
224
|
+
<div id="method-i-closed-3F" class="method-detail ">
|
174
225
|
|
175
226
|
<div class="method-heading">
|
176
|
-
<span class="method-name">
|
227
|
+
<span class="method-name">closed?</span><span
|
177
228
|
class="method-args">()</span>
|
178
229
|
|
179
230
|
<span class="method-click-advice">click to toggle source</span>
|
@@ -183,14 +234,58 @@ my_socket.extend <a href="Socket.html">Ionian::Socket</a></p>
|
|
183
234
|
|
184
235
|
<div class="method-description">
|
185
236
|
|
237
|
+
<p>Returns true if the socket is closed.</p>
|
238
|
+
|
239
|
+
|
240
|
+
|
241
|
+
|
242
|
+
<div class="method-source-code" id="closed-3F-source">
|
243
|
+
<pre><span class="ruby-comment"># File lib/ionian/socket.rb, line 65</span>
|
244
|
+
<span class="ruby-keyword">def</span> <span class="ruby-identifier">closed?</span>
|
245
|
+
<span class="ruby-keyword">return</span> <span class="ruby-keyword">true</span> <span class="ruby-keyword">unless</span> <span class="ruby-ivar">@socket</span>
|
246
|
+
<span class="ruby-ivar">@socket</span>.<span class="ruby-identifier">closed?</span>
|
247
|
+
<span class="ruby-keyword">end</span></pre>
|
248
|
+
</div>
|
249
|
+
|
250
|
+
</div>
|
251
|
+
|
252
|
+
|
253
|
+
|
254
|
+
|
255
|
+
</div>
|
256
|
+
|
257
|
+
|
258
|
+
<div id="method-i-cmd" class="method-detail ">
|
259
|
+
|
260
|
+
<div class="method-heading">
|
261
|
+
<span class="method-name">cmd</span><span
|
262
|
+
class="method-args">(string, **kvargs) { |match| ... }</span>
|
263
|
+
|
264
|
+
<span class="method-click-advice">click to toggle source</span>
|
186
265
|
|
266
|
+
</div>
|
267
|
+
|
268
|
+
|
269
|
+
<div class="method-description">
|
270
|
+
|
271
|
+
<p>Send a command (data) to the socket. Returns received matches. Block yields
|
272
|
+
received match. See <a
|
273
|
+
href="Extension/IO.html#method-i-read_match">Ionian::Extension::IO#read_match</a></p>
|
187
274
|
|
188
275
|
|
189
276
|
|
190
277
|
|
191
|
-
<div class="method-source-code" id="
|
192
|
-
<pre><span class="ruby-comment"># File lib/ionian/socket.rb, line
|
193
|
-
<span class="ruby-keyword">def</span> <span class="ruby-identifier">
|
278
|
+
<div class="method-source-code" id="cmd-source">
|
279
|
+
<pre><span class="ruby-comment"># File lib/ionian/socket.rb, line 41</span>
|
280
|
+
<span class="ruby-keyword">def</span> <span class="ruby-identifier">cmd</span>(<span class="ruby-identifier">string</span>, <span class="ruby-operator">**</span><span class="ruby-identifier">kvargs</span>, <span class="ruby-operator">&</span><span class="ruby-identifier">block</span>)
|
281
|
+
<span class="ruby-identifier">create_socket</span> <span class="ruby-keyword">unless</span> <span class="ruby-ivar">@persistent</span>
|
282
|
+
<span class="ruby-ivar">@socket</span>.<span class="ruby-identifier">write</span> <span class="ruby-identifier">string</span>
|
283
|
+
<span class="ruby-ivar">@socket</span>.<span class="ruby-identifier">flush</span>
|
284
|
+
|
285
|
+
<span class="ruby-identifier">matches</span> = <span class="ruby-ivar">@socket</span>.<span class="ruby-identifier">read_match</span>(<span class="ruby-identifier">kvargs</span>) {<span class="ruby-operator">|</span><span class="ruby-identifier">match</span><span class="ruby-operator">|</span> <span class="ruby-keyword">yield</span> <span class="ruby-identifier">match</span> <span class="ruby-keyword">if</span> <span class="ruby-identifier">block_given?</span>}
|
286
|
+
<span class="ruby-ivar">@socket</span>.<span class="ruby-identifier">close</span> <span class="ruby-keyword">unless</span> <span class="ruby-ivar">@persistent</span>
|
287
|
+
|
288
|
+
<span class="ruby-identifier">matches</span>
|
194
289
|
<span class="ruby-keyword">end</span></pre>
|
195
290
|
</div>
|
196
291
|
|
@@ -202,10 +297,10 @@ my_socket.extend <a href="Socket.html">Ionian::Socket</a></p>
|
|
202
297
|
</div>
|
203
298
|
|
204
299
|
|
205
|
-
<div id="method-i-
|
300
|
+
<div id="method-i-flush" class="method-detail ">
|
206
301
|
|
207
302
|
<div class="method-heading">
|
208
|
-
<span class="method-name">
|
303
|
+
<span class="method-name">flush</span><span
|
209
304
|
class="method-args">()</span>
|
210
305
|
|
211
306
|
<span class="method-click-advice">click to toggle source</span>
|
@@ -215,17 +310,16 @@ my_socket.extend <a href="Socket.html">Ionian::Socket</a></p>
|
|
215
310
|
|
216
311
|
<div class="method-description">
|
217
312
|
|
218
|
-
<p>
|
219
|
-
|
313
|
+
<p>Flushes buffered data to the operating system. This method has no effect on
|
314
|
+
non-persistent sockets.</p>
|
220
315
|
|
221
316
|
|
222
317
|
|
223
318
|
|
224
|
-
<div class="method-source-code" id="
|
225
|
-
<pre><span class="ruby-comment"># File lib/ionian/socket.rb, line
|
226
|
-
<span class="ruby-keyword">def</span> <span class="ruby-identifier">
|
227
|
-
<span class="ruby-
|
228
|
-
<span class="ruby-identifier">nagle_disabled</span> <span class="ruby-operator">></span> <span class="ruby-value">0</span> <span class="ruby-operator">?</span> <span class="ruby-keyword">true</span> <span class="ruby-operator">:</span> <span class="ruby-keyword">false</span>
|
319
|
+
<div class="method-source-code" id="flush-source">
|
320
|
+
<pre><span class="ruby-comment"># File lib/ionian/socket.rb, line 72</span>
|
321
|
+
<span class="ruby-keyword">def</span> <span class="ruby-identifier">flush</span>
|
322
|
+
<span class="ruby-ivar">@socket</span>.<span class="ruby-identifier">flush</span> <span class="ruby-keyword">if</span> <span class="ruby-ivar">@persistent</span>
|
229
323
|
<span class="ruby-keyword">end</span></pre>
|
230
324
|
</div>
|
231
325
|
|
@@ -237,11 +331,11 @@ false.</p>
|
|
237
331
|
</div>
|
238
332
|
|
239
333
|
|
240
|
-
<div id="method-i-
|
334
|
+
<div id="method-i-has_data-3F" class="method-detail ">
|
241
335
|
|
242
336
|
<div class="method-heading">
|
243
|
-
<span class="method-name">
|
244
|
-
class="method-args">(
|
337
|
+
<span class="method-name">has_data?</span><span
|
338
|
+
class="method-args">(**kvargs)</span>
|
245
339
|
|
246
340
|
<span class="method-click-advice">click to toggle source</span>
|
247
341
|
|
@@ -250,17 +344,19 @@ false.</p>
|
|
250
344
|
|
251
345
|
<div class="method-description">
|
252
346
|
|
253
|
-
<p>
|
254
|
-
|
347
|
+
<p>Returns true if there is data in the receive buffer. Args:</p>
|
348
|
+
|
349
|
+
<pre>Timeout: Number of seconds to wait for data until
|
350
|
+
giving up. Set to nil for blocking.</pre>
|
255
351
|
|
256
352
|
|
257
353
|
|
258
354
|
|
259
|
-
<div class="method-source-code" id="
|
260
|
-
<pre><span class="ruby-comment"># File lib/ionian/socket.rb, line
|
261
|
-
<span class="ruby-keyword">def</span> <span class="ruby-identifier">
|
262
|
-
<span class="ruby-
|
263
|
-
<span class="ruby-
|
355
|
+
<div class="method-source-code" id="has_data-3F-source">
|
356
|
+
<pre><span class="ruby-comment"># File lib/ionian/socket.rb, line 59</span>
|
357
|
+
<span class="ruby-keyword">def</span> <span class="ruby-identifier">has_data?</span>(<span class="ruby-operator">**</span><span class="ruby-identifier">kvargs</span>)
|
358
|
+
<span class="ruby-keyword">return</span> <span class="ruby-keyword">false</span> <span class="ruby-keyword">unless</span> <span class="ruby-ivar">@socket</span>
|
359
|
+
<span class="ruby-ivar">@socket</span>.<span class="ruby-identifier">has_data?</span> <span class="ruby-identifier">kvargs</span>
|
264
360
|
<span class="ruby-keyword">end</span></pre>
|
265
361
|
</div>
|
266
362
|
|
@@ -269,6 +365,155 @@ false disables the flag (enables Nagle).</p>
|
|
269
365
|
|
270
366
|
|
271
367
|
|
368
|
+
</div>
|
369
|
+
|
370
|
+
|
371
|
+
<div id="method-i-persistent-3F" class="method-detail ">
|
372
|
+
|
373
|
+
<div class="method-heading">
|
374
|
+
<span class="method-name">persistent?</span><span
|
375
|
+
class="method-args">()</span>
|
376
|
+
|
377
|
+
<span class="method-click-advice">click to toggle source</span>
|
378
|
+
|
379
|
+
</div>
|
380
|
+
|
381
|
+
|
382
|
+
<div class="method-description">
|
383
|
+
|
384
|
+
<p>Returns true if the socket remains open after writing data.</p>
|
385
|
+
|
386
|
+
|
387
|
+
|
388
|
+
|
389
|
+
<div class="method-source-code" id="persistent-3F-source">
|
390
|
+
<pre><span class="ruby-comment"># File lib/ionian/socket.rb, line 34</span>
|
391
|
+
<span class="ruby-keyword">def</span> <span class="ruby-identifier">persistent?</span>
|
392
|
+
<span class="ruby-ivar">@persistent</span> <span class="ruby-operator">==</span> <span class="ruby-keyword">false</span> <span class="ruby-operator">||</span> <span class="ruby-ivar">@persistent</span> <span class="ruby-operator">==</span> <span class="ruby-keyword">nil</span> <span class="ruby-operator">?</span> <span class="ruby-keyword">false</span> <span class="ruby-operator">:</span> <span class="ruby-keyword">true</span>
|
393
|
+
<span class="ruby-keyword">end</span></pre>
|
394
|
+
</div>
|
395
|
+
|
396
|
+
</div>
|
397
|
+
|
398
|
+
|
399
|
+
|
400
|
+
|
401
|
+
</div>
|
402
|
+
|
403
|
+
|
404
|
+
<div id="method-i-protocol-3F" class="method-detail ">
|
405
|
+
|
406
|
+
<div class="method-heading">
|
407
|
+
<span class="method-name">protocol?</span><span
|
408
|
+
class="method-args">()</span>
|
409
|
+
|
410
|
+
<span class="method-click-advice">click to toggle source</span>
|
411
|
+
|
412
|
+
</div>
|
413
|
+
|
414
|
+
|
415
|
+
<div class="method-description">
|
416
|
+
|
417
|
+
<p>Returns a symbol of the type of protocol this socket uses: :tcp, :udp,
|
418
|
+
:unix</p>
|
419
|
+
|
420
|
+
|
421
|
+
|
422
|
+
|
423
|
+
<div class="method-source-code" id="protocol-3F-source">
|
424
|
+
<pre><span class="ruby-comment"># File lib/ionian/socket.rb, line 29</span>
|
425
|
+
<span class="ruby-keyword">def</span> <span class="ruby-identifier">protocol?</span>
|
426
|
+
<span class="ruby-ivar">@protocol</span>
|
427
|
+
<span class="ruby-keyword">end</span></pre>
|
428
|
+
</div>
|
429
|
+
|
430
|
+
</div>
|
431
|
+
|
432
|
+
|
433
|
+
|
434
|
+
|
435
|
+
</div>
|
436
|
+
|
437
|
+
|
438
|
+
<div id="method-i-puts" class="method-detail ">
|
439
|
+
|
440
|
+
<div class="method-heading">
|
441
|
+
<span class="method-name">puts</span><span
|
442
|
+
class="method-args">(*string)</span>
|
443
|
+
|
444
|
+
<span class="method-click-advice">click to toggle source</span>
|
445
|
+
|
446
|
+
</div>
|
447
|
+
|
448
|
+
|
449
|
+
<div class="method-description">
|
450
|
+
|
451
|
+
<p>Writes the given string(s) to the socket and appends a newline character to
|
452
|
+
any string not already ending with one.</p>
|
453
|
+
|
454
|
+
|
455
|
+
|
456
|
+
|
457
|
+
<div class="method-source-code" id="puts-source">
|
458
|
+
<pre><span class="ruby-comment"># File lib/ionian/socket.rb, line 78</span>
|
459
|
+
<span class="ruby-keyword">def</span> <span class="ruby-identifier">puts</span>(<span class="ruby-operator">*</span><span class="ruby-identifier">string</span>)
|
460
|
+
<span class="ruby-keyword">self</span>.<span class="ruby-identifier">write</span> <span class="ruby-identifier">string</span>.<span class="ruby-identifier">map</span>{<span class="ruby-operator">|</span><span class="ruby-identifier">s</span><span class="ruby-operator">|</span> <span class="ruby-identifier">s</span>.<span class="ruby-identifier">chomp</span>}.<span class="ruby-identifier">join</span>(<span class="ruby-string">"\n"</span>) <span class="ruby-operator">+</span> <span class="ruby-string">"\n"</span>
|
461
|
+
<span class="ruby-keyword">end</span></pre>
|
462
|
+
</div>
|
463
|
+
|
464
|
+
</div>
|
465
|
+
|
466
|
+
|
467
|
+
|
468
|
+
|
469
|
+
</div>
|
470
|
+
|
471
|
+
|
472
|
+
<div id="method-i-write" class="method-detail ">
|
473
|
+
|
474
|
+
<div class="method-heading">
|
475
|
+
<span class="method-name">write</span><span
|
476
|
+
class="method-args">(string)</span>
|
477
|
+
|
478
|
+
<span class="method-click-advice">click to toggle source</span>
|
479
|
+
|
480
|
+
</div>
|
481
|
+
|
482
|
+
|
483
|
+
<div class="method-description">
|
484
|
+
|
485
|
+
<p>Writes the given string to the socket. Returns the number of bytes written.</p>
|
486
|
+
|
487
|
+
|
488
|
+
|
489
|
+
|
490
|
+
<div class="method-source-code" id="write-source">
|
491
|
+
<pre><span class="ruby-comment"># File lib/ionian/socket.rb, line 84</span>
|
492
|
+
<span class="ruby-keyword">def</span> <span class="ruby-identifier">write</span>(<span class="ruby-identifier">string</span>)
|
493
|
+
<span class="ruby-identifier">create_socket</span> <span class="ruby-keyword">unless</span> <span class="ruby-ivar">@persistent</span>
|
494
|
+
<span class="ruby-identifier">num_bytes</span> = <span class="ruby-ivar">@socket</span>.<span class="ruby-identifier">write</span> <span class="ruby-identifier">string</span>
|
495
|
+
|
496
|
+
<span class="ruby-keyword">unless</span> <span class="ruby-ivar">@persistent</span>
|
497
|
+
<span class="ruby-comment"># Read in data to prevent RST packets.</span>
|
498
|
+
<span class="ruby-identifier">has_data</span> = <span class="ruby-operator">::</span><span class="ruby-constant">IO</span>.<span class="ruby-identifier">select</span> [<span class="ruby-ivar">@socket</span>], <span class="ruby-keyword">nil</span>, <span class="ruby-keyword">nil</span>, <span class="ruby-value">0</span>
|
499
|
+
<span class="ruby-ivar">@socket</span>.<span class="ruby-identifier">readpartial</span> <span class="ruby-value">0xFFFF</span> <span class="ruby-keyword">if</span> <span class="ruby-identifier">has_data</span>
|
500
|
+
|
501
|
+
<span class="ruby-ivar">@socket</span>.<span class="ruby-identifier">close</span>
|
502
|
+
<span class="ruby-keyword">end</span>
|
503
|
+
|
504
|
+
<span class="ruby-identifier">num_bytes</span>
|
505
|
+
<span class="ruby-keyword">end</span></pre>
|
506
|
+
</div>
|
507
|
+
|
508
|
+
</div>
|
509
|
+
|
510
|
+
|
511
|
+
<div class="aliases">
|
512
|
+
Also aliased as: <a href="Socket.html#method-i-3C-3C"><<</a>
|
513
|
+
</div>
|
514
|
+
|
515
|
+
|
516
|
+
|
272
517
|
</div>
|
273
518
|
|
274
519
|
|
data/doc/Ionian.html
CHANGED
@@ -72,10 +72,9 @@
|
|
72
72
|
|
73
73
|
<section class="description">
|
74
74
|
|
75
|
-
<p>A library to simplify interaction with
|
76
|
-
|
77
|
-
|
78
|
-
notification of received data.</p>
|
75
|
+
<p>A library to simplify interaction with IO streams. This includes network
|
76
|
+
sockets, file sockets, and serial streams like the console and RS232.
|
77
|
+
Features regular expression matching and notification of received data.</p>
|
79
78
|
|
80
79
|
</section>
|
81
80
|
|
data/doc/created.rid
CHANGED
@@ -1,4 +1,5 @@
|
|
1
|
-
Sun, 01 Dec 2013 18:46:
|
2
|
-
lib/ionian.rb Sun, 01 Dec 2013 18:46:
|
3
|
-
lib/ionian/io.rb Sun, 01 Dec 2013 18:46:
|
4
|
-
lib/ionian/socket.rb Sun, 01 Dec 2013 18:46:
|
1
|
+
Sun, 01 Dec 2013 18:46:48 -0800
|
2
|
+
lib/ionian.rb Sun, 01 Dec 2013 18:46:44 -0800
|
3
|
+
lib/ionian/extension/io.rb Sun, 01 Dec 2013 18:46:44 -0800
|
4
|
+
lib/ionian/extension/socket.rb Sun, 01 Dec 2013 18:46:44 -0800
|
5
|
+
lib/ionian/socket.rb Sun, 01 Dec 2013 18:46:44 -0800
|
data/doc/index.html
CHANGED
@@ -64,7 +64,11 @@
|
|
64
64
|
|
65
65
|
<li><a href="./Ionian.html">Ionian</a>
|
66
66
|
|
67
|
-
<li><a href="./Ionian/
|
67
|
+
<li><a href="./Ionian/Extension.html">Ionian::Extension</a>
|
68
|
+
|
69
|
+
<li><a href="./Ionian/Extension/IO.html">Ionian::Extension::IO</a>
|
70
|
+
|
71
|
+
<li><a href="./Ionian/Extension/Socket.html">Ionian::Extension::Socket</a>
|
68
72
|
|
69
73
|
<li><a href="./Ionian/Socket.html">Ionian::Socket</a>
|
70
74
|
|
data/doc/js/search_index.js
CHANGED
@@ -1 +1 @@
|
|
1
|
-
var search_data = {"index":{"searchIndex":["ionian","io","socket","expression()","expression=()","extended()","extended()","initialize_ionian()","initialize_ionian_socket()","no_delay()","no_delay=()","on_match()","purge()","read_match()","register_observer()","run_match()","unregister_observer()"],"longSearchIndex":["ionian","ionian::io","ionian::socket","ionian::io#expression()","ionian::io#expression=()","ionian::io::extended()","ionian::socket::extended()","ionian::io#initialize_ionian()","ionian::socket#initialize_ionian_socket()","ionian::socket#no_delay()","ionian::socket#no_delay=()","ionian::io#on_match()","ionian::io#purge()","ionian::io#read_match()","ionian::io#register_observer()","ionian::io#run_match()","ionian::io#unregister_observer()"],"info":[["Ionian","","Ionian.html","","<p>A library to simplify interaction with IO streams. This includes network\nsockets, file sockets, and serial …\n"],["Ionian::IO","","Ionian/IO.html","","<p>A mixin for IO objects that allows regular expression matching and\nconvenient notification of received …\n"],["Ionian::Socket","","Ionian/Socket.html","","<p>A mixin for Socket objects.\n<p>This module was designed to be extended by instantiated objects that\nimplement …\n"],["expression","Ionian::IO","Ionian/IO.html#method-i-expression","()","<p>Returns the regular expression used for #read_match.\n"],["expression=","Ionian::IO","Ionian/IO.html#method-i-expression-3D","(exp)","<p>Set the expression to match against the read buffer. Can be a regular\nexpression specifying capture groups, …\n"],["extended","Ionian::IO","Ionian/IO.html#method-c-extended","(obj)","<p>Called automaticallly when the object is extended with #extend.\n"],["extended","Ionian::Socket","Ionian/Socket.html#method-c-extended","(obj)","<p>Called automaticallly when the object is extended with #extend.\n"],["initialize_ionian","Ionian::IO","Ionian/IO.html#method-i-initialize_ionian","()","<p>Initialize the Ionian instance variables. This is called automatically if\n#extend is called on an object. …\n"],["initialize_ionian_socket","Ionian::Socket","Ionian/Socket.html#method-i-initialize_ionian_socket","()",""],["no_delay","Ionian::Socket","Ionian/Socket.html#method-i-no_delay","()","<p>Returns true if the TCP_NODELAY flag is enabled (Nagle disabled). Otherwise\nfalse.\n"],["no_delay=","Ionian::Socket","Ionian/Socket.html#method-i-no_delay-3D","(value)","<p>Setting to true enables the TCP_NODELAY flag (disables Nagle). Setting to\nfalse disables the flag (enables …\n"],["on_match","Ionian::IO","Ionian/IO.html#method-i-on_match","(&block)",""],["purge","Ionian::IO","Ionian/IO.html#method-i-purge","()","<p>Erase the data in the IO and Ionian buffers. This is typically handled\nautomatically.\n"],["read_match","Ionian::IO","Ionian/IO.html#method-i-read_match","(**kvargs, &block)","<p>Read matched data from the buffer. This method SHOULD NOT be used if\n#run_match is used.\n<p>Passes matches …\n"],["register_observer","Ionian::IO","Ionian/IO.html#method-i-register_observer","(&block)","<p>Register a block to be called when #run_match receives matched data. Method\ncallbacks can be registered …\n"],["run_match","Ionian::IO","Ionian/IO.html#method-i-run_match","(**kvargs)","<p>Start a thread that checks for data and notifies listeners (do |match,\nsocket|). Passes kvargs to #read_match …\n"],["unregister_observer","Ionian::IO","Ionian/IO.html#method-i-unregister_observer","(&block)","<p>Unregister a block from being called when matched data is received.\n"]]}}
|
1
|
+
var search_data = {"index":{"searchIndex":["ionian","extension","io","socket","socket","<<()","closed?()","cmd()","expression()","expression=()","extended()","extended()","flush()","has_data?()","has_data?()","initialize_ionian()","initialize_ionian_socket()","new()","no_delay()","no_delay=()","on_match()","persistent?()","protocol?()","purge()","puts()","read_match()","register_observer()","run_match()","unregister_observer()","write()"],"longSearchIndex":["ionian","ionian::extension","ionian::extension::io","ionian::extension::socket","ionian::socket","ionian::socket#<<()","ionian::socket#closed?()","ionian::socket#cmd()","ionian::extension::io#expression()","ionian::extension::io#expression=()","ionian::extension::io::extended()","ionian::extension::socket::extended()","ionian::socket#flush()","ionian::extension::io#has_data?()","ionian::socket#has_data?()","ionian::extension::io#initialize_ionian()","ionian::extension::socket#initialize_ionian_socket()","ionian::socket::new()","ionian::extension::socket#no_delay()","ionian::extension::socket#no_delay=()","ionian::extension::io#on_match()","ionian::socket#persistent?()","ionian::socket#protocol?()","ionian::extension::io#purge()","ionian::socket#puts()","ionian::extension::io#read_match()","ionian::extension::io#register_observer()","ionian::extension::io#run_match()","ionian::extension::io#unregister_observer()","ionian::socket#write()"],"info":[["Ionian","","Ionian.html","","<p>A library to simplify interaction with IO streams. This includes network\nsockets, file sockets, and serial …\n"],["Ionian::Extension","","Ionian/Extension.html","",""],["Ionian::Extension::IO","","Ionian/Extension/IO.html","","<p>A mixin for IO objects that allows regular expression matching and\nconvenient notification of received …\n"],["Ionian::Extension::Socket","","Ionian/Extension/Socket.html","","<p>A mixin for Socket objects.\n<p>This module was designed to be extended by instantiated objects that\nimplement …\n"],["Ionian::Socket","","Ionian/Socket.html","",""],["<<","Ionian::Socket","Ionian/Socket.html#method-i-3C-3C","(string)",""],["closed?","Ionian::Socket","Ionian/Socket.html#method-i-closed-3F","()","<p>Returns true if the socket is closed.\n"],["cmd","Ionian::Socket","Ionian/Socket.html#method-i-cmd","(string, **kvargs, &block)","<p>Send a command (data) to the socket. Returns received matches. Block yields\nreceived match. See Ionian::Extension::IO#read_match …\n"],["expression","Ionian::Extension::IO","Ionian/Extension/IO.html#method-i-expression","()","<p>Returns the regular expression used for #read_match.\n"],["expression=","Ionian::Extension::IO","Ionian/Extension/IO.html#method-i-expression-3D","(exp)","<p>Set the expression to match against the read buffer. Can be a regular\nexpression specifying capture groups, …\n"],["extended","Ionian::Extension::IO","Ionian/Extension/IO.html#method-c-extended","(obj)","<p>Called automaticallly when the object is extended with #extend.\n"],["extended","Ionian::Extension::Socket","Ionian/Extension/Socket.html#method-c-extended","(obj)","<p>Called automaticallly when the object is extended with #extend.\n"],["flush","Ionian::Socket","Ionian/Socket.html#method-i-flush","()","<p>Flushes buffered data to the operating system. This method has no effect on\nnon-persistent sockets.\n"],["has_data?","Ionian::Extension::IO","Ionian/Extension/IO.html#method-i-has_data-3F","(timeout: 0)","<p>Returns true if there is data in the receive buffer. Args:\n\n<pre>Timeout: Number of seconds to wait for data ...</pre>\n"],["has_data?","Ionian::Socket","Ionian/Socket.html#method-i-has_data-3F","(**kvargs)","<p>Returns true if there is data in the receive buffer. Args:\n\n<pre>Timeout: Number of seconds to wait for data ...</pre>\n"],["initialize_ionian","Ionian::Extension::IO","Ionian/Extension/IO.html#method-i-initialize_ionian","()","<p>Initialize the Ionian instance variables. This is called automatically if\n#extend is called on an object. …\n"],["initialize_ionian_socket","Ionian::Extension::Socket","Ionian/Extension/Socket.html#method-i-initialize_ionian_socket","()",""],["new","Ionian::Socket","Ionian/Socket.html#method-c-new","(**kvargs)","<p>TODO NOTES\n<p>Always lazily instiantiate @socket, even when persistent? May not work with\nforwarding method …\n"],["no_delay","Ionian::Extension::Socket","Ionian/Extension/Socket.html#method-i-no_delay","()","<p>Returns true if the TCP_NODELAY flag is enabled (Nagle disabled). Otherwise\nfalse.\n"],["no_delay=","Ionian::Extension::Socket","Ionian/Extension/Socket.html#method-i-no_delay-3D","(value)","<p>Setting to true enables the TCP_NODELAY flag (disables Nagle). Setting to\nfalse disables the flag (enables …\n"],["on_match","Ionian::Extension::IO","Ionian/Extension/IO.html#method-i-on_match","(&block)",""],["persistent?","Ionian::Socket","Ionian/Socket.html#method-i-persistent-3F","()","<p>Returns true if the socket remains open after writing data.\n"],["protocol?","Ionian::Socket","Ionian/Socket.html#method-i-protocol-3F","()","<p>Returns a symbol of the type of protocol this socket uses: :tcp, :udp,\n:unix\n"],["purge","Ionian::Extension::IO","Ionian/Extension/IO.html#method-i-purge","()","<p>Erase the data in the IO and Ionian buffers. This is typically handled\nautomatically.\n"],["puts","Ionian::Socket","Ionian/Socket.html#method-i-puts","(*string)","<p>Writes the given string(s) to the socket and appends a newline character to\nany string not already ending …\n"],["read_match","Ionian::Extension::IO","Ionian/Extension/IO.html#method-i-read_match","(**kvargs, &block)","<p>Read matched data from the buffer. This method SHOULD NOT be used if\n#run_match is used.\n<p>Passes matches …\n"],["register_observer","Ionian::Extension::IO","Ionian/Extension/IO.html#method-i-register_observer","(&block)","<p>Register a block to be called when #run_match receives matched data. Method\ncallbacks can be registered …\n"],["run_match","Ionian::Extension::IO","Ionian/Extension/IO.html#method-i-run_match","(**kvargs)","<p>Start a thread that checks for data and notifies listeners (do |match,\nsocket|). Passes kvargs to #read_match …\n"],["unregister_observer","Ionian::Extension::IO","Ionian/Extension/IO.html#method-i-unregister_observer","(&block)","<p>Unregister a block from being called when matched data is received.\n"],["write","Ionian::Socket","Ionian/Socket.html#method-i-write","(string)","<p>Writes the given string to the socket. Returns the number of bytes written.\n"]]}}
|
data/doc/table_of_contents.html
CHANGED
@@ -32,9 +32,15 @@
|
|
32
32
|
<a href="Ionian.html">Ionian</a>
|
33
33
|
</li>
|
34
34
|
<li class="module">
|
35
|
-
<a href="Ionian/
|
35
|
+
<a href="Ionian/Extension.html">Ionian::Extension</a>
|
36
36
|
</li>
|
37
37
|
<li class="module">
|
38
|
+
<a href="Ionian/Extension/IO.html">Ionian::Extension::IO</a>
|
39
|
+
</li>
|
40
|
+
<li class="module">
|
41
|
+
<a href="Ionian/Extension/Socket.html">Ionian::Extension::Socket</a>
|
42
|
+
</li>
|
43
|
+
<li class="class">
|
38
44
|
<a href="Ionian/Socket.html">Ionian::Socket</a>
|
39
45
|
</li>
|
40
46
|
</ul>
|
@@ -43,74 +49,129 @@
|
|
43
49
|
<ul>
|
44
50
|
|
45
51
|
<li class="method">
|
46
|
-
<a href="Ionian/IO.html#method-c-extended">::extended</a>
|
52
|
+
<a href="Ionian/Extension/IO.html#method-c-extended">::extended</a>
|
53
|
+
—
|
54
|
+
<span class="container">Ionian::Extension::IO</span>
|
55
|
+
|
56
|
+
<li class="method">
|
57
|
+
<a href="Ionian/Extension/Socket.html#method-c-extended">::extended</a>
|
47
58
|
—
|
48
|
-
<span class="container">Ionian::
|
59
|
+
<span class="container">Ionian::Extension::Socket</span>
|
49
60
|
|
50
61
|
<li class="method">
|
51
|
-
<a href="Ionian/Socket.html#method-c-
|
62
|
+
<a href="Ionian/Socket.html#method-c-new">::new</a>
|
52
63
|
—
|
53
64
|
<span class="container">Ionian::Socket</span>
|
54
65
|
|
55
66
|
<li class="method">
|
56
|
-
<a href="Ionian/
|
67
|
+
<a href="Ionian/Socket.html#method-i-3C-3C">#<<</a>
|
57
68
|
—
|
58
|
-
<span class="container">Ionian::
|
69
|
+
<span class="container">Ionian::Socket</span>
|
59
70
|
|
60
71
|
<li class="method">
|
61
|
-
<a href="Ionian/
|
72
|
+
<a href="Ionian/Socket.html#method-i-closed-3F">#closed?</a>
|
62
73
|
—
|
63
|
-
<span class="container">Ionian::
|
74
|
+
<span class="container">Ionian::Socket</span>
|
64
75
|
|
65
76
|
<li class="method">
|
66
|
-
<a href="Ionian/
|
77
|
+
<a href="Ionian/Socket.html#method-i-cmd">#cmd</a>
|
67
78
|
—
|
68
|
-
<span class="container">Ionian::
|
79
|
+
<span class="container">Ionian::Socket</span>
|
69
80
|
|
70
81
|
<li class="method">
|
71
|
-
<a href="Ionian/
|
82
|
+
<a href="Ionian/Extension/IO.html#method-i-expression">#expression</a>
|
83
|
+
—
|
84
|
+
<span class="container">Ionian::Extension::IO</span>
|
85
|
+
|
86
|
+
<li class="method">
|
87
|
+
<a href="Ionian/Extension/IO.html#method-i-expression-3D">#expression=</a>
|
88
|
+
—
|
89
|
+
<span class="container">Ionian::Extension::IO</span>
|
90
|
+
|
91
|
+
<li class="method">
|
92
|
+
<a href="Ionian/Socket.html#method-i-flush">#flush</a>
|
93
|
+
—
|
94
|
+
<span class="container">Ionian::Socket</span>
|
95
|
+
|
96
|
+
<li class="method">
|
97
|
+
<a href="Ionian/Socket.html#method-i-has_data-3F">#has_data?</a>
|
72
98
|
—
|
73
99
|
<span class="container">Ionian::Socket</span>
|
74
100
|
|
75
101
|
<li class="method">
|
76
|
-
<a href="Ionian/
|
102
|
+
<a href="Ionian/Extension/IO.html#method-i-has_data-3F">#has_data?</a>
|
103
|
+
—
|
104
|
+
<span class="container">Ionian::Extension::IO</span>
|
105
|
+
|
106
|
+
<li class="method">
|
107
|
+
<a href="Ionian/Extension/IO.html#method-i-initialize_ionian">#initialize_ionian</a>
|
108
|
+
—
|
109
|
+
<span class="container">Ionian::Extension::IO</span>
|
110
|
+
|
111
|
+
<li class="method">
|
112
|
+
<a href="Ionian/Extension/Socket.html#method-i-initialize_ionian_socket">#initialize_ionian_socket</a>
|
113
|
+
—
|
114
|
+
<span class="container">Ionian::Extension::Socket</span>
|
115
|
+
|
116
|
+
<li class="method">
|
117
|
+
<a href="Ionian/Extension/Socket.html#method-i-no_delay">#no_delay</a>
|
118
|
+
—
|
119
|
+
<span class="container">Ionian::Extension::Socket</span>
|
120
|
+
|
121
|
+
<li class="method">
|
122
|
+
<a href="Ionian/Extension/Socket.html#method-i-no_delay-3D">#no_delay=</a>
|
123
|
+
—
|
124
|
+
<span class="container">Ionian::Extension::Socket</span>
|
125
|
+
|
126
|
+
<li class="method">
|
127
|
+
<a href="Ionian/Extension/IO.html#method-i-on_match">#on_match</a>
|
128
|
+
—
|
129
|
+
<span class="container">Ionian::Extension::IO</span>
|
130
|
+
|
131
|
+
<li class="method">
|
132
|
+
<a href="Ionian/Socket.html#method-i-persistent-3F">#persistent?</a>
|
77
133
|
—
|
78
134
|
<span class="container">Ionian::Socket</span>
|
79
135
|
|
80
136
|
<li class="method">
|
81
|
-
<a href="Ionian/Socket.html#method-i-
|
137
|
+
<a href="Ionian/Socket.html#method-i-protocol-3F">#protocol?</a>
|
82
138
|
—
|
83
139
|
<span class="container">Ionian::Socket</span>
|
84
140
|
|
85
141
|
<li class="method">
|
86
|
-
<a href="Ionian/IO.html#method-i-
|
142
|
+
<a href="Ionian/Extension/IO.html#method-i-purge">#purge</a>
|
87
143
|
—
|
88
|
-
<span class="container">Ionian::IO</span>
|
144
|
+
<span class="container">Ionian::Extension::IO</span>
|
89
145
|
|
90
146
|
<li class="method">
|
91
|
-
<a href="Ionian/
|
147
|
+
<a href="Ionian/Socket.html#method-i-puts">#puts</a>
|
92
148
|
—
|
93
|
-
<span class="container">Ionian::
|
149
|
+
<span class="container">Ionian::Socket</span>
|
94
150
|
|
95
151
|
<li class="method">
|
96
|
-
<a href="Ionian/IO.html#method-i-read_match">#read_match</a>
|
152
|
+
<a href="Ionian/Extension/IO.html#method-i-read_match">#read_match</a>
|
97
153
|
—
|
98
|
-
<span class="container">Ionian::IO</span>
|
154
|
+
<span class="container">Ionian::Extension::IO</span>
|
99
155
|
|
100
156
|
<li class="method">
|
101
|
-
<a href="Ionian/IO.html#method-i-register_observer">#register_observer</a>
|
157
|
+
<a href="Ionian/Extension/IO.html#method-i-register_observer">#register_observer</a>
|
102
158
|
—
|
103
|
-
<span class="container">Ionian::IO</span>
|
159
|
+
<span class="container">Ionian::Extension::IO</span>
|
104
160
|
|
105
161
|
<li class="method">
|
106
|
-
<a href="Ionian/IO.html#method-i-run_match">#run_match</a>
|
162
|
+
<a href="Ionian/Extension/IO.html#method-i-run_match">#run_match</a>
|
107
163
|
—
|
108
|
-
<span class="container">Ionian::IO</span>
|
164
|
+
<span class="container">Ionian::Extension::IO</span>
|
109
165
|
|
110
166
|
<li class="method">
|
111
|
-
<a href="Ionian/IO.html#method-i-unregister_observer">#unregister_observer</a>
|
167
|
+
<a href="Ionian/Extension/IO.html#method-i-unregister_observer">#unregister_observer</a>
|
112
168
|
—
|
113
|
-
<span class="container">Ionian::IO</span>
|
169
|
+
<span class="container">Ionian::Extension::IO</span>
|
170
|
+
|
171
|
+
<li class="method">
|
172
|
+
<a href="Ionian/Socket.html#method-i-write">#write</a>
|
173
|
+
—
|
174
|
+
<span class="container">Ionian::Socket</span>
|
114
175
|
</ul>
|
115
176
|
</main>
|
116
177
|
|
@@ -0,0 +1,165 @@
|
|
1
|
+
module Ionian
|
2
|
+
module Extension
|
3
|
+
# A mixin for IO objects that allows regular expression matching
|
4
|
+
# and convenient notification of received data.
|
5
|
+
#
|
6
|
+
# This module was designed to be extended by instantiated objects
|
7
|
+
# that implement the standard library IO class.
|
8
|
+
# my_socket.extend Ionian::IO
|
9
|
+
module IO
|
10
|
+
# Number of seconds to attempt an IO operation before timing out.
|
11
|
+
# See standard library IO::select.
|
12
|
+
attr_accessor :ionian_timeout
|
13
|
+
|
14
|
+
# Called automaticallly when the object is extended with #extend.
|
15
|
+
def self.extended(obj)
|
16
|
+
obj.initialize_ionian
|
17
|
+
end
|
18
|
+
|
19
|
+
# Initialize the Ionian instance variables.
|
20
|
+
# This is called automatically if #extend is called on an object.
|
21
|
+
def initialize_ionian
|
22
|
+
@ionian_listeners = []
|
23
|
+
@ionian_buf = ''
|
24
|
+
@ionian_expression = /(.*?)\n/
|
25
|
+
@ionian_timeout = nil
|
26
|
+
@ionian_skip_select = false
|
27
|
+
@ionian_build_methods = true
|
28
|
+
end
|
29
|
+
|
30
|
+
# Returns true if there is data in the receive buffer.
|
31
|
+
# Args:
|
32
|
+
# Timeout: Number of seconds to wait for data until
|
33
|
+
# giving up. Set to nil for blocking.
|
34
|
+
def has_data?(timeout: 0)
|
35
|
+
::IO.select([self], nil, nil, timeout) ? true : false
|
36
|
+
end
|
37
|
+
|
38
|
+
# Returns the regular expression used for #read_match.
|
39
|
+
def expression
|
40
|
+
@ionian_expression
|
41
|
+
end
|
42
|
+
|
43
|
+
# Set the expression to match against the read buffer.
|
44
|
+
# Can be a regular expression specifying capture groups,
|
45
|
+
# or a string specifying the separator or line terminator
|
46
|
+
# sequence. It is possible to use named captures in a
|
47
|
+
# regex, which allows for convienient accessors like
|
48
|
+
# match[:parameter].
|
49
|
+
def expression=(exp)
|
50
|
+
@ionian_expression = exp
|
51
|
+
@ionian_expression = Regexp.new "(.*?)#{expression}" if exp.is_a? String
|
52
|
+
end
|
53
|
+
|
54
|
+
# Read matched data from the buffer.
|
55
|
+
# This method SHOULD NOT be used if #run_match is used.
|
56
|
+
#
|
57
|
+
# Passes matches to the block (do |match|). If there are multiple
|
58
|
+
# matches, the block is called multiple times.
|
59
|
+
#
|
60
|
+
# Returns an array of matches.
|
61
|
+
# Returns nil if no data was received within the timeout period.
|
62
|
+
#
|
63
|
+
# Junk data that could exist before a match in the buffer can
|
64
|
+
# be accessed with match.pre_match.
|
65
|
+
#
|
66
|
+
# Data at the end of the buffer that is not matched can be accessed
|
67
|
+
# in the last match with match.post_match. This data remains in the
|
68
|
+
# buffer for the next #read_match cycle. This is helpful for protocols
|
69
|
+
# like RS232 that do not have packet boundries.
|
70
|
+
#
|
71
|
+
# kvargs:
|
72
|
+
# timeout: Timeout in seconds IO::select will block.
|
73
|
+
# skip_select: Skip over the IO::select statement. Use if you
|
74
|
+
# are calling IO::select ahead of this method.
|
75
|
+
# build_methods: Build method accessors from named captures.
|
76
|
+
# Enabled by default.
|
77
|
+
def read_match(**kvargs, &block)
|
78
|
+
timeout = kvargs.fetch :timeout, @ionian_timeout
|
79
|
+
skip_select = kvargs.fetch :skip_select, @ionian_skip_select
|
80
|
+
build_methods = kvargs.fetch :build_methods, @ionian_build_methods
|
81
|
+
|
82
|
+
unless skip_select
|
83
|
+
return nil unless ::IO.select [self], nil, nil, timeout
|
84
|
+
end
|
85
|
+
|
86
|
+
# Read data from the IO buffer until it's empty.
|
87
|
+
loop do
|
88
|
+
@ionian_buf << readpartial(0xFFFF)
|
89
|
+
break unless ::IO.select [self], nil, nil, 0
|
90
|
+
end
|
91
|
+
|
92
|
+
@matches = []
|
93
|
+
|
94
|
+
while @ionian_buf =~ @ionian_expression
|
95
|
+
@matches << $~ # Match data.
|
96
|
+
yield $~ if block_given?
|
97
|
+
@ionian_buf = $' # Leave post match data in the buffer.
|
98
|
+
end
|
99
|
+
|
100
|
+
# Convert named captures to methods.
|
101
|
+
if build_methods
|
102
|
+
@matches.each do |match|
|
103
|
+
match.names
|
104
|
+
.map {|name| name.to_sym}
|
105
|
+
.each {|symbol| match.singleton_class
|
106
|
+
.send(:define_method, symbol) { match[symbol] } \
|
107
|
+
unless match.respond_to? symbol
|
108
|
+
}
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
@matches
|
113
|
+
end
|
114
|
+
|
115
|
+
# Start a thread that checks for data and notifies listeners (do |match, socket|).
|
116
|
+
# Passes kvargs to #read_match.
|
117
|
+
# This method SHOULD NOT be used if #read_match is used.
|
118
|
+
def run_match(**kvargs)
|
119
|
+
@match_listener ||= Thread.new do
|
120
|
+
begin
|
121
|
+
while not closed? do
|
122
|
+
matches = read_match kvargs
|
123
|
+
matches.each {|match|
|
124
|
+
@ionian_listeners.each {|listener| listener.call match, self}
|
125
|
+
} if matches
|
126
|
+
end
|
127
|
+
rescue EOFError
|
128
|
+
rescue IOError
|
129
|
+
ensure
|
130
|
+
@match_listener = nil
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
# Erase the data in the IO and Ionian buffers.
|
136
|
+
# This is typically handled automatically.
|
137
|
+
def purge
|
138
|
+
# Erase IO buffer.
|
139
|
+
while ::IO.select [self], nil, nil, 0
|
140
|
+
readpartial(0xFFFF)
|
141
|
+
end
|
142
|
+
|
143
|
+
@ionian_buf = ''
|
144
|
+
end
|
145
|
+
|
146
|
+
# Register a block to be called when #run_match receives matched data.
|
147
|
+
# Method callbacks can be registered with &object.method(:method).
|
148
|
+
# Returns a reference to the given block.
|
149
|
+
# block = ionian_socket.register_observer {...}
|
150
|
+
def register_observer(&block)
|
151
|
+
@ionian_listeners << block unless @ionian_listeners.include? block
|
152
|
+
block
|
153
|
+
end
|
154
|
+
|
155
|
+
alias_method :on_match, :register_observer
|
156
|
+
|
157
|
+
# Unregister a block from being called when matched data is received.
|
158
|
+
def unregister_observer(&block)
|
159
|
+
@ionian_listeners.delete_if {|o| o == block}
|
160
|
+
block
|
161
|
+
end
|
162
|
+
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'ionian/extension/io'
|
2
|
+
require 'socket'
|
3
|
+
|
4
|
+
module Ionian
|
5
|
+
module Extension
|
6
|
+
# A mixin for Socket objects.
|
7
|
+
#
|
8
|
+
# This module was designed to be extended by instantiated objects
|
9
|
+
# that implement the standard library Socket class.
|
10
|
+
# my_socket.extend Ionian::Socket
|
11
|
+
#
|
12
|
+
# Extending this module also extends Ionian::IO.
|
13
|
+
module Socket
|
14
|
+
|
15
|
+
# Called automaticallly when the object is extended with #extend.
|
16
|
+
def self.extended(obj)
|
17
|
+
obj.extend Ionian::Extension::IO
|
18
|
+
obj.initialize_ionian_socket
|
19
|
+
end
|
20
|
+
|
21
|
+
def initialize_ionian_socket
|
22
|
+
end
|
23
|
+
|
24
|
+
# Returns true if the TCP_NODELAY flag is enabled (Nagle disabled).
|
25
|
+
# Otherwise false.
|
26
|
+
def no_delay
|
27
|
+
nagle_disabled = self.getsockopt(::Socket::IPPROTO_TCP, ::Socket::TCP_NODELAY).data.ord
|
28
|
+
nagle_disabled > 0 ? true : false
|
29
|
+
end
|
30
|
+
|
31
|
+
# Setting to true enables the TCP_NODELAY flag (disables Nagle).
|
32
|
+
# Setting to false disables the flag (enables Nagle).
|
33
|
+
def no_delay=(value)
|
34
|
+
disable_nagle = value ? 1 : 0
|
35
|
+
self.setsockopt ::Socket::IPPROTO_TCP, ::Socket::TCP_NODELAY, disable_nagle
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
data/lib/ionian/socket.rb
CHANGED
@@ -1,37 +1,147 @@
|
|
1
|
-
require 'ionian/
|
2
|
-
require 'socket'
|
1
|
+
require 'ionian/extension/socket'
|
3
2
|
|
4
3
|
module Ionian
|
5
|
-
|
6
|
-
#
|
7
|
-
# This module was designed to be extended by instantiated objects
|
8
|
-
# that implement the standard library Socket class.
|
9
|
-
# my_socket.extend Ionian::Socket
|
10
|
-
#
|
11
|
-
# Extending this module also extends Ionian::IO.
|
12
|
-
module Socket
|
4
|
+
class Socket
|
13
5
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
6
|
+
############
|
7
|
+
# TODO NOTES
|
8
|
+
############
|
9
|
+
# Always lazily instiantiate @socket, even when persistent?
|
10
|
+
# May not work with forwarding method calls.
|
11
|
+
# Oh! Unless the forwarded methods check for @socket to exist.
|
12
|
+
# Will persistent methods have to check for the socket not to be
|
13
|
+
# closed as well?
|
14
|
+
|
15
|
+
def initialize(**kvargs)
|
16
|
+
@socket = nil
|
17
|
+
|
18
|
+
@host = kvargs.fetch :host
|
19
|
+
@port = kvargs.fetch :port, 23
|
20
|
+
@expression = kvargs.fetch :expression, nil
|
21
|
+
@protocol = kvargs.fetch :protocol, :tcp
|
22
|
+
@persistent = kvargs.fetch :persistent, true
|
23
|
+
|
24
|
+
create_socket if @persistent
|
25
|
+
end
|
26
|
+
|
27
|
+
# Returns a symbol of the type of protocol this socket uses:
|
28
|
+
# :tcp, :udp, :unix
|
29
|
+
def protocol?
|
30
|
+
@protocol
|
31
|
+
end
|
32
|
+
|
33
|
+
# Returns true if the socket remains open after writing data.
|
34
|
+
def persistent?
|
35
|
+
@persistent == false || @persistent == nil ? false : true
|
36
|
+
end
|
37
|
+
|
38
|
+
# Send a command (data) to the socket. Returns received matches.
|
39
|
+
# Block yields received match.
|
40
|
+
# See Ionian::Extension::IO#read_match
|
41
|
+
def cmd(string, **kvargs, &block)
|
42
|
+
create_socket unless @persistent
|
43
|
+
@socket.write string
|
44
|
+
@socket.flush
|
45
|
+
|
46
|
+
matches = @socket.read_match(kvargs) {|match| yield match if block_given?}
|
47
|
+
@socket.close unless @persistent
|
48
|
+
|
49
|
+
matches
|
50
|
+
end
|
51
|
+
|
52
|
+
|
53
|
+
### Methods Forwarded To @socket ###
|
54
|
+
|
55
|
+
# Returns true if there is data in the receive buffer.
|
56
|
+
# Args:
|
57
|
+
# Timeout: Number of seconds to wait for data until
|
58
|
+
# giving up. Set to nil for blocking.
|
59
|
+
def has_data?(**kvargs)
|
60
|
+
return false unless @socket
|
61
|
+
@socket.has_data? kvargs
|
18
62
|
end
|
19
63
|
|
20
|
-
|
64
|
+
# Returns true if the socket is closed.
|
65
|
+
def closed?
|
66
|
+
return true unless @socket
|
67
|
+
@socket.closed?
|
21
68
|
end
|
22
69
|
|
23
|
-
#
|
24
|
-
#
|
25
|
-
def
|
26
|
-
|
27
|
-
|
70
|
+
# Flushes buffered data to the operating system.
|
71
|
+
# This method has no effect on non-persistent sockets.
|
72
|
+
def flush
|
73
|
+
@socket.flush if @persistent
|
74
|
+
end
|
75
|
+
|
76
|
+
# Writes the given string(s) to the socket and appends a
|
77
|
+
# newline character to any string not already ending with one.
|
78
|
+
def puts(*string)
|
79
|
+
self.write string.map{|s| s.chomp}.join("\n") + "\n"
|
80
|
+
end
|
81
|
+
|
82
|
+
# Writes the given string to the socket. Returns the number of
|
83
|
+
# bytes written.
|
84
|
+
def write(string)
|
85
|
+
create_socket unless @persistent
|
86
|
+
num_bytes = @socket.write string
|
87
|
+
|
88
|
+
unless @persistent
|
89
|
+
# Read in data to prevent RST packets.
|
90
|
+
has_data = ::IO.select [@socket], nil, nil, 0
|
91
|
+
@socket.readpartial 0xFFFF if has_data
|
92
|
+
|
93
|
+
@socket.close
|
94
|
+
end
|
95
|
+
|
96
|
+
num_bytes
|
97
|
+
end
|
98
|
+
|
99
|
+
alias_method :<<, :write
|
100
|
+
|
101
|
+
|
102
|
+
private
|
103
|
+
|
104
|
+
def create_socket
|
105
|
+
@socket.close if @socket and not @socket.closed?
|
106
|
+
|
107
|
+
case @protocol
|
108
|
+
when :tcp
|
109
|
+
@socket = ::TCPSocket.new @host, @port
|
110
|
+
when :udp
|
111
|
+
@socket = ::UDPSocket.new
|
112
|
+
@socket.connect @host, @port
|
113
|
+
when :unix
|
114
|
+
@socket = ::UNIXSocket.new @host
|
115
|
+
end
|
116
|
+
|
117
|
+
@socket.extend Ionian::Extension::Socket
|
118
|
+
@socket.expression = @expression if @expression
|
119
|
+
|
120
|
+
initialize_socket_methods
|
28
121
|
end
|
29
122
|
|
30
|
-
#
|
31
|
-
#
|
32
|
-
|
33
|
-
|
34
|
-
|
123
|
+
# Expose the @socket methods that haven't been defined by this class.
|
124
|
+
# Only do this once for performance -- when non-persistent sockets are
|
125
|
+
# recreated, they should be of the same type of socket.
|
126
|
+
def initialize_socket_methods
|
127
|
+
# Only initialize once, lazily.
|
128
|
+
# For non-persistent sockets, this forwards the socket methods
|
129
|
+
# the first time data is sent -- when the new socket is created.
|
130
|
+
return if @socket_methods_initialized
|
131
|
+
|
132
|
+
# Forward undefined methods to @socket.
|
133
|
+
# This was chosen over method_missing to avoid traversing the object
|
134
|
+
# hierarchy on every method call, like transmitting data.
|
135
|
+
@socket.methods
|
136
|
+
.select {|m| @socket.respond_to? m}
|
137
|
+
.select {|m| not self.respond_to? m}
|
138
|
+
.each do |m|
|
139
|
+
self.singleton_class.send :define_method, m do |*args, &block|
|
140
|
+
@socket.__send__ m, *args, &block
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
@socket_methods_initialized = true
|
35
145
|
end
|
36
146
|
|
37
147
|
end
|
data/lib/ionian.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ionian
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Alex McLain
|
@@ -53,7 +53,7 @@ dependencies:
|
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
|
-
name:
|
56
|
+
name: rspec
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
59
|
- - ">="
|
@@ -75,8 +75,9 @@ extensions: []
|
|
75
75
|
extra_rdoc_files: []
|
76
76
|
files:
|
77
77
|
- license.txt
|
78
|
+
- lib/ionian/extension/socket.rb
|
79
|
+
- lib/ionian/extension/io.rb
|
78
80
|
- lib/ionian/socket.rb
|
79
|
-
- lib/ionian/io.rb
|
80
81
|
- lib/ionian.rb
|
81
82
|
- doc/fonts/SourceCodePro-Regular.ttf
|
82
83
|
- doc/fonts/SourceCodePro-Bold.ttf
|
data/lib/ionian/io.rb
DELETED
@@ -1,155 +0,0 @@
|
|
1
|
-
module Ionian
|
2
|
-
# A mixin for IO objects that allows regular expression matching
|
3
|
-
# and convenient notification of received data.
|
4
|
-
#
|
5
|
-
# This module was designed to be extended by instantiated objects
|
6
|
-
# that implement the standard library IO class.
|
7
|
-
# my_socket.extend Ionian::IO
|
8
|
-
module IO
|
9
|
-
# Number of seconds to attempt an IO operation before timing out.
|
10
|
-
# See standard library IO::select.
|
11
|
-
attr_accessor :ionian_timeout
|
12
|
-
|
13
|
-
# Called automaticallly when the object is extended with #extend.
|
14
|
-
def self.extended(obj)
|
15
|
-
obj.initialize_ionian
|
16
|
-
end
|
17
|
-
|
18
|
-
# Initialize the Ionian instance variables.
|
19
|
-
# This is called automatically if #extend is called on an object.
|
20
|
-
def initialize_ionian
|
21
|
-
@ionian_listeners = []
|
22
|
-
@ionian_buf = ''
|
23
|
-
@ionian_expression = /(.*?)\n/
|
24
|
-
@ionian_timeout = nil
|
25
|
-
@ionian_skip_select = false
|
26
|
-
@ionian_build_methods = true
|
27
|
-
end
|
28
|
-
|
29
|
-
# Returns the regular expression used for #read_match.
|
30
|
-
def expression
|
31
|
-
@ionian_expression
|
32
|
-
end
|
33
|
-
|
34
|
-
# Set the expression to match against the read buffer.
|
35
|
-
# Can be a regular expression specifying capture groups,
|
36
|
-
# or a string specifying the separator or line terminator
|
37
|
-
# sequence. It is possible to use named captures in a
|
38
|
-
# regex, which allows for convienient accessors like
|
39
|
-
# match[:parameter].
|
40
|
-
def expression=(exp)
|
41
|
-
@ionian_expression = exp
|
42
|
-
@ionian_expression = Regexp.new "(.*?)#{expression}" if exp.is_a? String
|
43
|
-
end
|
44
|
-
|
45
|
-
# Read matched data from the buffer.
|
46
|
-
# This method SHOULD NOT be used if #run_match is used.
|
47
|
-
#
|
48
|
-
# Passes matches to the block (do |match|). If there are multiple
|
49
|
-
# matches, the block is called multiple times.
|
50
|
-
#
|
51
|
-
# Returns an array of matches.
|
52
|
-
# Returns nil if no data was received within the timeout period.
|
53
|
-
#
|
54
|
-
# Junk data that could exist before a match in the buffer can
|
55
|
-
# be accessed with match.pre_match.
|
56
|
-
#
|
57
|
-
# Data at the end of the buffer that is not matched can be accessed
|
58
|
-
# in the last match with match.post_match. This data remains in the
|
59
|
-
# buffer for the next #read_match cycle. This is helpful for protocols
|
60
|
-
# like RS232 that do not have packet boundries.
|
61
|
-
#
|
62
|
-
# kvargs:
|
63
|
-
# timeout: Timeout in seconds IO::select will block.
|
64
|
-
# skip_select: Skip over the IO::select statement. Use if you
|
65
|
-
# are calling IO::select ahead of this method.
|
66
|
-
# build_methods: Build method accessors from named captures.
|
67
|
-
# Enabled by default.
|
68
|
-
def read_match(**kvargs, &block)
|
69
|
-
timeout = kvargs.fetch :timeout, @ionian_timeout
|
70
|
-
skip_select = kvargs.fetch :skip_select, @ionian_skip_select
|
71
|
-
build_methods = kvargs.fetch :build_methods, @ionian_build_methods
|
72
|
-
|
73
|
-
unless skip_select
|
74
|
-
return nil unless ::IO.select [self], nil, nil, timeout
|
75
|
-
end
|
76
|
-
|
77
|
-
# Read data from the IO buffer until it's empty.
|
78
|
-
loop do
|
79
|
-
@ionian_buf << readpartial(0xFFFF)
|
80
|
-
break unless ::IO.select [self], nil, nil, 0
|
81
|
-
end
|
82
|
-
|
83
|
-
@matches = []
|
84
|
-
|
85
|
-
while @ionian_buf =~ @ionian_expression
|
86
|
-
@matches << $~ # Match data.
|
87
|
-
yield $~ if block_given?
|
88
|
-
@ionian_buf = $' # Leave post match data in the buffer.
|
89
|
-
end
|
90
|
-
|
91
|
-
# Convert named captures to methods.
|
92
|
-
if build_methods
|
93
|
-
@matches.each do |match|
|
94
|
-
match.names
|
95
|
-
.map {|name| name.to_sym}
|
96
|
-
.each {|symbol| match.singleton_class
|
97
|
-
.send(:define_method, symbol) { match[symbol] } \
|
98
|
-
unless match.respond_to? symbol
|
99
|
-
}
|
100
|
-
end
|
101
|
-
end
|
102
|
-
|
103
|
-
@matches
|
104
|
-
end
|
105
|
-
|
106
|
-
# Start a thread that checks for data and notifies listeners (do |match, socket|).
|
107
|
-
# Passes kvargs to #read_match.
|
108
|
-
# This method SHOULD NOT be used if #read_match is used.
|
109
|
-
def run_match(**kvargs)
|
110
|
-
@match_listener ||= Thread.new do
|
111
|
-
begin
|
112
|
-
while not closed? do
|
113
|
-
matches = read_match kvargs
|
114
|
-
matches.each {|match|
|
115
|
-
@ionian_listeners.each {|listener| listener.call match, self}
|
116
|
-
} if matches
|
117
|
-
end
|
118
|
-
rescue EOFError
|
119
|
-
rescue IOError
|
120
|
-
end
|
121
|
-
|
122
|
-
@match_listener = nil
|
123
|
-
end
|
124
|
-
end
|
125
|
-
|
126
|
-
# Erase the data in the IO and Ionian buffers.
|
127
|
-
# This is typically handled automatically.
|
128
|
-
def purge
|
129
|
-
# Erase IO buffer.
|
130
|
-
while ::IO.select [self], nil, nil, 0
|
131
|
-
readpartial(0xFFFF)
|
132
|
-
end
|
133
|
-
|
134
|
-
@ionian_buf = ''
|
135
|
-
end
|
136
|
-
|
137
|
-
# Register a block to be called when #run_match receives matched data.
|
138
|
-
# Method callbacks can be registered with &object.method(:method).
|
139
|
-
# Returns a reference to the given block.
|
140
|
-
# block = ionian_socket.register_observer {...}
|
141
|
-
def register_observer(&block)
|
142
|
-
@ionian_listeners << block unless @ionian_listeners.include? block
|
143
|
-
block
|
144
|
-
end
|
145
|
-
|
146
|
-
alias_method :on_match, :register_observer
|
147
|
-
|
148
|
-
# Unregister a block from being called when matched data is received.
|
149
|
-
def unregister_observer(&block)
|
150
|
-
@ionian_listeners.delete_if {|o| o == block}
|
151
|
-
block
|
152
|
-
end
|
153
|
-
|
154
|
-
end
|
155
|
-
end
|