eventmachine 1.0.0.beta.3-x86-mswin32-60 → 1.0.0.beta.4.1-x86-mswin32-60
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +5 -0
- data/.yardopts +5 -1
- data/{docs/GNU → GNU} +0 -0
- data/Gemfile +1 -0
- data/{docs/COPYING → LICENSE} +0 -0
- data/README.md +109 -0
- data/Rakefile +8 -0
- data/docs/DocumentationGuidesIndex.md +27 -0
- data/docs/GettingStarted.md +521 -0
- data/docs/{ChangeLog → old/ChangeLog} +0 -0
- data/docs/{DEFERRABLES → old/DEFERRABLES} +0 -0
- data/docs/{EPOLL → old/EPOLL} +0 -0
- data/docs/{INSTALL → old/INSTALL} +0 -0
- data/docs/{KEYBOARD → old/KEYBOARD} +0 -0
- data/docs/{LEGAL → old/LEGAL} +0 -0
- data/docs/{LIGHTWEIGHT_CONCURRENCY → old/LIGHTWEIGHT_CONCURRENCY} +0 -0
- data/docs/{PURE_RUBY → old/PURE_RUBY} +0 -0
- data/docs/{RELEASE_NOTES → old/RELEASE_NOTES} +0 -0
- data/docs/{SMTP → old/SMTP} +0 -0
- data/docs/{SPAWNED_PROCESSES → old/SPAWNED_PROCESSES} +0 -0
- data/docs/{TODO → old/TODO} +0 -0
- data/eventmachine.gemspec +5 -2
- data/examples/guides/getting_started/01_eventmachine_echo_server.rb +18 -0
- data/examples/guides/getting_started/02_eventmachine_echo_server_that_recognizes_exit_command.rb +22 -0
- data/examples/guides/getting_started/03_simple_chat_server.rb +149 -0
- data/examples/guides/getting_started/04_simple_chat_server_step_one.rb +27 -0
- data/examples/guides/getting_started/05_simple_chat_server_step_two.rb +43 -0
- data/examples/guides/getting_started/06_simple_chat_server_step_three.rb +98 -0
- data/examples/guides/getting_started/07_simple_chat_server_step_four.rb +121 -0
- data/examples/guides/getting_started/08_simple_chat_server_step_five.rb +141 -0
- data/examples/{ex_channel.rb → old/ex_channel.rb} +3 -3
- data/examples/{ex_queue.rb → old/ex_queue.rb} +0 -0
- data/examples/{ex_tick_loop_array.rb → old/ex_tick_loop_array.rb} +0 -0
- data/examples/{ex_tick_loop_counter.rb → old/ex_tick_loop_counter.rb} +0 -0
- data/examples/{helper.rb → old/helper.rb} +0 -0
- data/ext/cmain.cpp +3 -3
- data/ext/ed.cpp +90 -15
- data/ext/ed.h +5 -5
- data/ext/em.cpp +48 -56
- data/ext/em.h +12 -2
- data/ext/extconf.rb +3 -3
- data/ext/fastfilereader/extconf.rb +1 -1
- data/ext/pipe.cpp +2 -2
- data/ext/project.h +1 -1
- data/ext/rubymain.cpp +48 -3
- data/ext/ssl.cpp +5 -0
- data/java/src/com/rubyeventmachine/EmReactor.java +2 -2
- data/lib/em/buftok.rb +35 -63
- data/lib/em/callback.rb +43 -11
- data/lib/em/channel.rb +21 -14
- data/lib/em/completion.rb +304 -0
- data/lib/em/connection.rb +339 -209
- data/lib/em/deferrable.rb +4 -0
- data/lib/em/deferrable/pool.rb +2 -0
- data/lib/em/file_watch.rb +37 -18
- data/lib/em/iterator.rb +42 -42
- data/lib/em/pool.rb +146 -0
- data/lib/em/process_watch.rb +5 -4
- data/lib/em/processes.rb +8 -4
- data/lib/em/protocols/httpclient.rb +22 -11
- data/lib/em/protocols/httpclient2.rb +15 -5
- data/lib/em/protocols/line_protocol.rb +2 -1
- data/lib/em/protocols/memcache.rb +17 -9
- data/lib/em/protocols/object_protocol.rb +2 -1
- data/lib/em/protocols/postgres3.rb +8 -9
- data/lib/em/protocols/smtpclient.rb +19 -11
- data/lib/em/protocols/smtpserver.rb +1 -1
- data/lib/em/protocols/stomp.rb +8 -6
- data/lib/em/protocols/tcptest.rb +3 -2
- data/lib/em/pure_ruby.rb +212 -208
- data/lib/em/queue.rb +22 -13
- data/lib/em/resolver.rb +70 -64
- data/lib/em/spawnable.rb +6 -3
- data/lib/em/streamer.rb +33 -45
- data/lib/em/threaded_resource.rb +90 -0
- data/lib/em/timers.rb +6 -2
- data/lib/em/version.rb +1 -1
- data/lib/eventmachine.rb +538 -602
- data/lib/jeventmachine.rb +22 -1
- data/tasks/package.rake +12 -2
- data/tasks/test.rake +1 -0
- data/tests/em_test_helper.rb +12 -3
- data/tests/test_completion.rb +177 -0
- data/tests/test_epoll.rb +2 -2
- data/tests/test_httpclient.rb +9 -9
- data/tests/test_httpclient2.rb +11 -9
- data/tests/test_ltp.rb +2 -10
- data/tests/test_pool.rb +128 -0
- data/tests/test_processes.rb +20 -2
- data/tests/test_queue.rb +8 -0
- data/tests/test_resolver.rb +1 -1
- data/tests/test_set_sock_opt.rb +37 -0
- data/tests/test_shutdown_hooks.rb +23 -0
- data/tests/test_threaded_resource.rb +53 -0
- data/tests/test_unbind_reason.rb +31 -0
- metadata +96 -32
- data/README +0 -81
- data/tasks/doc.rake +0 -30
data/ext/em.h
CHANGED
@@ -43,6 +43,15 @@ See the file COPYING for complete licensing information.
|
|
43
43
|
#ifndef RUBY_UBF_IO
|
44
44
|
#define RUBY_UBF_IO RB_UBF_DFL
|
45
45
|
#endif
|
46
|
+
#ifndef RSTRING_PTR
|
47
|
+
#define RSTRING_PTR(str) RString(str)->ptr
|
48
|
+
#endif
|
49
|
+
#ifndef RSTRING_LEN
|
50
|
+
#define RSTRING_LEN(str) RString(str)->len
|
51
|
+
#endif
|
52
|
+
#ifndef RSTRING_LENINT
|
53
|
+
#define RSTRING_LENINT(str) RSTRING_LEN(str)
|
54
|
+
#endif
|
46
55
|
#else
|
47
56
|
#define EmSelect select
|
48
57
|
#endif
|
@@ -81,6 +90,7 @@ class EventMachine_t
|
|
81
90
|
|
82
91
|
void Add (EventableDescriptor*);
|
83
92
|
void Modify (EventableDescriptor*);
|
93
|
+
void Deregister (EventableDescriptor*);
|
84
94
|
|
85
95
|
const unsigned long AttachFD (int, bool);
|
86
96
|
int DetachFD (EventableDescriptor*);
|
@@ -126,13 +136,13 @@ class EventMachine_t
|
|
126
136
|
bool UsingEpoll() { return bEpoll; }
|
127
137
|
|
128
138
|
void QueueHeartbeat(EventableDescriptor*);
|
129
|
-
void ClearHeartbeat(uint64_t);
|
139
|
+
void ClearHeartbeat(uint64_t, EventableDescriptor*);
|
130
140
|
|
131
141
|
uint64_t GetRealTime();
|
132
142
|
|
133
143
|
private:
|
134
144
|
bool _RunOnce();
|
135
|
-
|
145
|
+
void _RunTimers();
|
136
146
|
void _UpdateTime();
|
137
147
|
void _AddNewDescriptors();
|
138
148
|
void _ModifyDescriptors();
|
data/ext/extconf.rb
CHANGED
@@ -25,7 +25,7 @@ end
|
|
25
25
|
def manual_ssl_config
|
26
26
|
ssl_libs_heads_args = {
|
27
27
|
:unix => [%w[ssl crypto], %w[openssl/ssl.h openssl/err.h]],
|
28
|
-
:mswin => [%w[ssleay32
|
28
|
+
:mswin => [%w[ssleay32 eay32], %w[openssl/ssl.h openssl/err.h]],
|
29
29
|
}
|
30
30
|
|
31
31
|
dc_flags = ['ssl']
|
@@ -57,7 +57,7 @@ if ENV['CROSS_COMPILING']
|
|
57
57
|
end
|
58
58
|
|
59
59
|
# Try to use pkg_config first, fixes #73
|
60
|
-
if pkg_config('openssl') || manual_ssl_config
|
60
|
+
if (!ENV['CROSS_COMPILING'] and pkg_config('openssl')) || manual_ssl_config
|
61
61
|
add_define "WITH_SSL"
|
62
62
|
else
|
63
63
|
add_define "WITHOUT_SSL"
|
@@ -76,7 +76,7 @@ have_func('rb_time_new')
|
|
76
76
|
# Minor platform details between *nix and Windows:
|
77
77
|
|
78
78
|
if RUBY_PLATFORM =~ /(mswin|mingw|bccwin)/
|
79
|
-
GNU_CHAIN = $1 == 'mingw'
|
79
|
+
GNU_CHAIN = ENV['CROSS_COMPILING'] or $1 == 'mingw'
|
80
80
|
OS_WIN32 = true
|
81
81
|
add_define "OS_WIN32"
|
82
82
|
else
|
@@ -17,7 +17,7 @@ add_define 'BUILD_FOR_RUBY'
|
|
17
17
|
# Minor platform details between *nix and Windows:
|
18
18
|
|
19
19
|
if RUBY_PLATFORM =~ /(mswin|mingw|bccwin)/
|
20
|
-
GNU_CHAIN = $1 == 'mingw'
|
20
|
+
GNU_CHAIN = ENV['CROSS_COMPILING'] or $1 == 'mingw'
|
21
21
|
OS_WIN32 = true
|
22
22
|
add_define "OS_WIN32"
|
23
23
|
else
|
data/ext/pipe.cpp
CHANGED
@@ -282,7 +282,7 @@ bool PipeDescriptor::SelectForRead()
|
|
282
282
|
* a pending state, so this is simpler than for the
|
283
283
|
* ConnectionDescriptor object.
|
284
284
|
*/
|
285
|
-
return true;
|
285
|
+
return bPaused ? false : true;
|
286
286
|
}
|
287
287
|
|
288
288
|
/******************************
|
@@ -295,7 +295,7 @@ bool PipeDescriptor::SelectForWrite()
|
|
295
295
|
* a pending state, so this is simpler than for the
|
296
296
|
* ConnectionDescriptor object.
|
297
297
|
*/
|
298
|
-
return (GetOutboundDataSize() > 0);
|
298
|
+
return (GetOutboundDataSize() > 0) && !bPaused ? true : false;
|
299
299
|
}
|
300
300
|
|
301
301
|
|
data/ext/project.h
CHANGED
data/ext/rubymain.cpp
CHANGED
@@ -95,9 +95,13 @@ static inline void event_callback (struct em_event* e)
|
|
95
95
|
return;
|
96
96
|
}
|
97
97
|
case EM_CONNECTION_ACCEPTED:
|
98
|
+
{
|
99
|
+
rb_funcall (EmModule, Intern_event_callback, 3, ULONG2NUM(signature), INT2FIX(event), ULONG2NUM(data_num));
|
100
|
+
return;
|
101
|
+
}
|
98
102
|
case EM_CONNECTION_UNBOUND:
|
99
103
|
{
|
100
|
-
rb_funcall (EmModule, Intern_event_callback, 3, ULONG2NUM(signature), INT2FIX(event),
|
104
|
+
rb_funcall (EmModule, Intern_event_callback, 3, ULONG2NUM(signature), INT2FIX(event), ULONG2NUM(data_num));
|
101
105
|
return;
|
102
106
|
}
|
103
107
|
case EM_CONNECTION_COMPLETED:
|
@@ -426,8 +430,9 @@ t_set_comm_inactivity_timeout
|
|
426
430
|
static VALUE t_set_comm_inactivity_timeout (VALUE self, VALUE signature, VALUE timeout)
|
427
431
|
{
|
428
432
|
float ti = RFLOAT_VALUE(timeout);
|
429
|
-
if (evma_set_comm_inactivity_timeout
|
433
|
+
if (evma_set_comm_inactivity_timeout(NUM2ULONG(signature), ti)) {
|
430
434
|
return Qtrue;
|
435
|
+
}
|
431
436
|
return Qfalse;
|
432
437
|
}
|
433
438
|
|
@@ -447,8 +452,9 @@ t_set_pending_connect_timeout
|
|
447
452
|
static VALUE t_set_pending_connect_timeout (VALUE self, VALUE signature, VALUE timeout)
|
448
453
|
{
|
449
454
|
float ti = RFLOAT_VALUE(timeout);
|
450
|
-
if (evma_set_pending_connect_timeout
|
455
|
+
if (evma_set_pending_connect_timeout(NUM2ULONG(signature), ti)) {
|
451
456
|
return Qtrue;
|
457
|
+
}
|
452
458
|
return Qfalse;
|
453
459
|
}
|
454
460
|
|
@@ -577,6 +583,44 @@ static VALUE t_get_sock_opt (VALUE self, VALUE signature, VALUE lev, VALUE optna
|
|
577
583
|
return rb_str_new(buf, len);
|
578
584
|
}
|
579
585
|
|
586
|
+
/**************
|
587
|
+
t_set_sock_opt
|
588
|
+
**************/
|
589
|
+
|
590
|
+
static VALUE t_set_sock_opt (VALUE self, VALUE signature, VALUE lev, VALUE optname, VALUE optval)
|
591
|
+
{
|
592
|
+
int fd = evma_get_file_descriptor (NUM2ULONG (signature));
|
593
|
+
int level = NUM2INT(lev), option = NUM2INT(optname);
|
594
|
+
int i;
|
595
|
+
void *v;
|
596
|
+
socklen_t len;
|
597
|
+
|
598
|
+
switch (TYPE(optval)) {
|
599
|
+
case T_FIXNUM:
|
600
|
+
i = FIX2INT(optval);
|
601
|
+
goto numval;
|
602
|
+
case T_FALSE:
|
603
|
+
i = 0;
|
604
|
+
goto numval;
|
605
|
+
case T_TRUE:
|
606
|
+
i = 1;
|
607
|
+
numval:
|
608
|
+
v = (void*)&i; len = sizeof(i);
|
609
|
+
break;
|
610
|
+
default:
|
611
|
+
StringValue(optval);
|
612
|
+
v = RSTRING_PTR(optval);
|
613
|
+
len = RSTRING_LENINT(optval);
|
614
|
+
break;
|
615
|
+
}
|
616
|
+
|
617
|
+
|
618
|
+
if (setsockopt(fd, level, option, (char *)v, len) < 0)
|
619
|
+
rb_sys_fail("setsockopt");
|
620
|
+
|
621
|
+
return INT2FIX(0);
|
622
|
+
}
|
623
|
+
|
580
624
|
/********************
|
581
625
|
t_is_notify_readable
|
582
626
|
********************/
|
@@ -1127,6 +1171,7 @@ extern "C" void Init_rubyeventmachine()
|
|
1127
1171
|
rb_define_module_function (EmModule, "attach_fd", (VALUE (*)(...))t_attach_fd, 2);
|
1128
1172
|
rb_define_module_function (EmModule, "detach_fd", (VALUE (*)(...))t_detach_fd, 1);
|
1129
1173
|
rb_define_module_function (EmModule, "get_sock_opt", (VALUE (*)(...))t_get_sock_opt, 3);
|
1174
|
+
rb_define_module_function (EmModule, "set_sock_opt", (VALUE (*)(...))t_set_sock_opt, 4);
|
1130
1175
|
rb_define_module_function (EmModule, "set_notify_readable", (VALUE (*)(...))t_set_notify_readable, 2);
|
1131
1176
|
rb_define_module_function (EmModule, "set_notify_writable", (VALUE (*)(...))t_set_notify_writable, 2);
|
1132
1177
|
rb_define_module_function (EmModule, "is_notify_readable", (VALUE (*)(...))t_is_notify_readable, 1);
|
data/ext/ssl.cpp
CHANGED
@@ -159,11 +159,14 @@ SslContext_t::SslContext_t (bool is_server, const string &privkeyfile, const str
|
|
159
159
|
e = SSL_CTX_use_PrivateKey_file (pCtx, privkeyfile.c_str(), SSL_FILETYPE_PEM);
|
160
160
|
else
|
161
161
|
e = SSL_CTX_use_PrivateKey (pCtx, DefaultPrivateKey);
|
162
|
+
if (e <= 0) ERR_print_errors_fp(stderr);
|
162
163
|
assert (e > 0);
|
164
|
+
|
163
165
|
if (certchainfile.length() > 0)
|
164
166
|
e = SSL_CTX_use_certificate_chain_file (pCtx, certchainfile.c_str());
|
165
167
|
else
|
166
168
|
e = SSL_CTX_use_certificate (pCtx, DefaultCertificate);
|
169
|
+
if (e <= 0) ERR_print_errors_fp(stderr);
|
167
170
|
assert (e > 0);
|
168
171
|
}
|
169
172
|
|
@@ -177,10 +180,12 @@ SslContext_t::SslContext_t (bool is_server, const string &privkeyfile, const str
|
|
177
180
|
int e;
|
178
181
|
if (privkeyfile.length() > 0) {
|
179
182
|
e = SSL_CTX_use_PrivateKey_file (pCtx, privkeyfile.c_str(), SSL_FILETYPE_PEM);
|
183
|
+
if (e <= 0) ERR_print_errors_fp(stderr);
|
180
184
|
assert (e > 0);
|
181
185
|
}
|
182
186
|
if (certchainfile.length() > 0) {
|
183
187
|
e = SSL_CTX_use_certificate_chain_file (pCtx, certchainfile.c_str());
|
188
|
+
if (e <= 0) ERR_print_errors_fp(stderr);
|
184
189
|
assert (e > 0);
|
185
190
|
}
|
186
191
|
}
|
@@ -442,8 +442,8 @@ public class EmReactor {
|
|
442
442
|
Connections.get(sig).setCommInactivityTimeout (mills);
|
443
443
|
}
|
444
444
|
|
445
|
-
public void sendDatagram (long sig,
|
446
|
-
sendDatagram (sig, ByteBuffer.wrap(data
|
445
|
+
public void sendDatagram (long sig, byte[] data, int length, String recipAddress, int recipPort) {
|
446
|
+
sendDatagram (sig, ByteBuffer.wrap(data), recipAddress, recipPort);
|
447
447
|
}
|
448
448
|
|
449
449
|
public void sendDatagram (long sig, ByteBuffer bb, String recipAddress, int recipPort) {
|
data/lib/em/buftok.rb
CHANGED
@@ -1,43 +1,29 @@
|
|
1
|
-
# BufferedTokenizer - Statefully split input data by a specifiable token
|
2
|
-
#
|
3
|
-
# Authors:: Tony Arcieri, Martin Emde
|
4
|
-
#
|
5
|
-
#----------------------------------------------------------------------------
|
6
|
-
#
|
7
|
-
# Copyright (C) 2006-07 by Tony Arcieri and Martin Emde
|
8
|
-
#
|
9
|
-
# Distributed under the Ruby license (http://www.ruby-lang.org/en/LICENSE.txt)
|
10
|
-
#
|
11
|
-
#---------------------------------------------------------------------------
|
12
|
-
#
|
13
|
-
|
14
|
-
# (C)2006 Tony Arcieri, Martin Emde
|
15
|
-
# Distributed under the Ruby license (http://www.ruby-lang.org/en/LICENSE.txt)
|
16
|
-
|
17
1
|
# BufferedTokenizer takes a delimiter upon instantiation, or acts line-based
|
18
2
|
# by default. It allows input to be spoon-fed from some outside source which
|
19
3
|
# receives arbitrary length datagrams which may-or-may-not contain the token
|
20
4
|
# by which entities are delimited.
|
21
5
|
#
|
22
|
-
#
|
6
|
+
# By default, new BufferedTokenizers will operate on lines delimited by "\n" by default
|
7
|
+
# or allow you to specify any delimiter token you so choose, which will then
|
8
|
+
# be used by String#split to tokenize the input data
|
23
9
|
#
|
24
|
-
#
|
25
|
-
#
|
26
|
-
#
|
27
|
-
#
|
28
|
-
#
|
29
|
-
#
|
30
|
-
#
|
31
|
-
|
10
|
+
# @example Using BufferedTokernizer to parse lines out of incoming data
|
11
|
+
#
|
12
|
+
# module LineBufferedConnection
|
13
|
+
# def receive_data(data)
|
14
|
+
# (@buffer ||= BufferedTokenizer.new).extract(data).each do |line|
|
15
|
+
# receive_line(line)
|
16
|
+
# end
|
17
|
+
# end
|
18
|
+
# end
|
19
|
+
#
|
20
|
+
# @author Tony Arcieri
|
21
|
+
# @author Martin Emde
|
32
22
|
class BufferedTokenizer
|
33
|
-
#
|
34
|
-
#
|
35
|
-
# be used by String#split to tokenize the input data
|
23
|
+
# @param [String] delimiter
|
24
|
+
# @param [Integer] size_limit
|
36
25
|
def initialize(delimiter = "\n", size_limit = nil)
|
37
|
-
|
38
|
-
@delimiter = delimiter
|
39
|
-
|
40
|
-
# Store the specified size limitation
|
26
|
+
@delimiter = delimiter
|
41
27
|
@size_limit = size_limit
|
42
28
|
|
43
29
|
# The input buffer is stored as an array. This is by far the most efficient
|
@@ -52,14 +38,18 @@ class BufferedTokenizer
|
|
52
38
|
end
|
53
39
|
|
54
40
|
# Extract takes an arbitrary string of input data and returns an array of
|
55
|
-
# tokenized entities, provided there were any available to extract.
|
56
|
-
# makes for easy processing of datagrams using a pattern like:
|
41
|
+
# tokenized entities, provided there were any available to extract.
|
57
42
|
#
|
58
|
-
#
|
43
|
+
# @example
|
44
|
+
#
|
45
|
+
# tokenizer.extract(data).
|
46
|
+
# map { |entity| Decode(entity) }.each { ... }
|
47
|
+
#
|
48
|
+
# @param [String] data
|
59
49
|
def extract(data)
|
60
50
|
# Extract token-delimited entities from the input string with the split command.
|
61
51
|
# There's a bit of craftiness here with the -1 parameter. Normally split would
|
62
|
-
# behave no differently regardless of if the token lies at the very end of the
|
52
|
+
# behave no differently regardless of if the token lies at the very end of the
|
63
53
|
# input buffer or not (i.e. a literal edge case) Specifying -1 forces split to
|
64
54
|
# return "" in this case, meaning that the last entry in the list represents a
|
65
55
|
# new segment of data where the token has not been encountered
|
@@ -70,7 +60,7 @@ class BufferedTokenizer
|
|
70
60
|
raise 'input buffer full' if @input_size + entities.first.size > @size_limit
|
71
61
|
@input_size += entities.first.size
|
72
62
|
end
|
73
|
-
|
63
|
+
|
74
64
|
# Move the first entry in the resulting array into the input buffer. It represents
|
75
65
|
# the last segment of a token-delimited entity unless it's the only entry in the list.
|
76
66
|
@input << entities.shift
|
@@ -85,36 +75,16 @@ class BufferedTokenizer
|
|
85
75
|
# and add it to our list of discovered entities.
|
86
76
|
entities.unshift @input.join
|
87
77
|
|
88
|
-
=begin
|
89
|
-
# Note added by FC, 10Jul07. This paragraph contains a regression. It breaks
|
90
|
-
# empty tokens. Think of the empty line that delimits an HTTP header. It will have
|
91
|
-
# two "\n" delimiters in a row, and this code mishandles the resulting empty token.
|
92
|
-
# It someone figures out how to fix the problem, we can re-enable this code branch.
|
93
|
-
# Multi-character token support.
|
94
|
-
# Split any tokens that were incomplete on the last iteration buf complete now.
|
95
|
-
entities.map! do |e|
|
96
|
-
e.split @delimiter, -1
|
97
|
-
end
|
98
|
-
# Flatten the resulting array. This has the side effect of removing the empty
|
99
|
-
# entry at the end that was produced by passing -1 to split. Add it again if
|
100
|
-
# necessary.
|
101
|
-
if (entities[-1] == [])
|
102
|
-
entities.flatten! << []
|
103
|
-
else
|
104
|
-
entities.flatten!
|
105
|
-
end
|
106
|
-
=end
|
107
|
-
|
108
78
|
# Now that we've hit a token, joined the input buffer and added it to the entities
|
109
79
|
# list, we can go ahead and clear the input buffer. All of the segments that were
|
110
80
|
# stored before the join can now be garbage collected.
|
111
81
|
@input.clear
|
112
|
-
|
82
|
+
|
113
83
|
# The last entity in the list is not token delimited, however, thanks to the -1
|
114
|
-
# passed to split. It represents the beginning of a new list of as-yet-untokenized
|
84
|
+
# passed to split. It represents the beginning of a new list of as-yet-untokenized
|
115
85
|
# data, so we add it to the start of the list.
|
116
86
|
@input << entities.pop
|
117
|
-
|
87
|
+
|
118
88
|
# Set the new input buffer size, provided we're keeping track
|
119
89
|
@input_size = @input.first.size if @size_limit
|
120
90
|
|
@@ -122,16 +92,18 @@ class BufferedTokenizer
|
|
122
92
|
# in the first place. Hooray!
|
123
93
|
entities
|
124
94
|
end
|
125
|
-
|
95
|
+
|
126
96
|
# Flush the contents of the input buffer, i.e. return the input buffer even though
|
127
|
-
# a token has not yet been encountered
|
97
|
+
# a token has not yet been encountered.
|
98
|
+
#
|
99
|
+
# @return [String]
|
128
100
|
def flush
|
129
101
|
buffer = @input.join
|
130
102
|
@input.clear
|
131
103
|
buffer
|
132
104
|
end
|
133
105
|
|
134
|
-
#
|
106
|
+
# @return [Boolean]
|
135
107
|
def empty?
|
136
108
|
@input.empty?
|
137
109
|
end
|
data/lib/em/callback.rb
CHANGED
@@ -1,26 +1,58 @@
|
|
1
1
|
module EventMachine
|
2
|
-
# Utility method for coercing arguments to an object that responds to
|
2
|
+
# Utility method for coercing arguments to an object that responds to :call.
|
3
3
|
# Accepts an object and a method name to send to, or a block, or an object
|
4
|
-
# that responds to call.
|
4
|
+
# that responds to :call.
|
5
5
|
#
|
6
|
-
#
|
6
|
+
# @example EventMachine.Callback used with a block. Returns that block.
|
7
|
+
#
|
8
|
+
# cb = EventMachine.Callback do |msg|
|
9
|
+
# puts(msg)
|
10
|
+
# end
|
11
|
+
# # returned object is a callable
|
7
12
|
# cb.call('hello world')
|
8
13
|
#
|
9
|
-
#
|
14
|
+
#
|
15
|
+
# @example EventMachine.Callback used with an object (to be more specific, class object) and a method name, returns an object that responds to #call
|
16
|
+
#
|
17
|
+
# cb = EventMachine.Callback(Object, :puts)
|
18
|
+
# # returned object is a callable that delegates to Kernel#puts (in this case Object.puts)
|
10
19
|
# cb.call('hello world')
|
11
20
|
#
|
12
|
-
#
|
21
|
+
#
|
22
|
+
# @example EventMachine.Callback used with an object that responds to #call. Returns the argument.
|
23
|
+
#
|
24
|
+
# cb = EventMachine.Callback(proc{ |msg| puts(msg) })
|
25
|
+
# # returned object is a callable
|
13
26
|
# cb.call('hello world')
|
14
27
|
#
|
28
|
+
#
|
29
|
+
# @overload Callback(object, method)
|
30
|
+
# Wraps `method` invocation on `object` into an object that responds to #call that proxies all the arguments to that method
|
31
|
+
# @param [Object] Object to invoke method on
|
32
|
+
# @param [Symbol] Method name
|
33
|
+
# @return [<#call>] An object that responds to #call that takes any number of arguments and invokes method on object with those arguments
|
34
|
+
#
|
35
|
+
# @overload Callback(object)
|
36
|
+
# Returns callable object as is, without any coercion
|
37
|
+
# @param [<#call>] An object that responds to #call
|
38
|
+
# @return [<#call>] Its argument
|
39
|
+
#
|
40
|
+
# @overload Callback(&block)
|
41
|
+
# Returns block passed to it without any coercion
|
42
|
+
# @return [<#call>] Block passed to this method
|
43
|
+
#
|
44
|
+
# @raise [ArgumentError] When argument doesn't respond to #call, method name is missing or when invoked without arguments and block isn't given
|
45
|
+
#
|
46
|
+
# @return [<#call>]
|
15
47
|
def self.Callback(object = nil, method = nil, &blk)
|
16
48
|
if object && method
|
17
|
-
lambda { |*args| object.
|
49
|
+
lambda { |*args| object.__send__ method, *args }
|
18
50
|
else
|
19
51
|
if object.respond_to? :call
|
20
52
|
object
|
21
|
-
else
|
53
|
+
else
|
22
54
|
blk || raise(ArgumentError)
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
55
|
+
end # if
|
56
|
+
end # if
|
57
|
+
end # self.Callback
|
58
|
+
end # EventMachine
|