ionian 0.3.0 → 0.4.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.
- 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
|