lwes 0.8.1 → 0.8.2
Sign up to get free protection for your applications and to get access to all the features.
- data/ChangeLog +3 -0
- data/README +3 -23
- data/ext/lwes_ext/emitter.c +25 -10
- data/ext/lwes_ext/event.c +25 -7
- data/ext/lwes_ext/type_db.c +8 -0
- data/lib/lwes.rb +2 -2
- data/lib/lwes/emitter.rb +49 -16
- data/lib/lwes/event.rb +21 -1
- data/lib/lwes/listener.rb +2 -1
- data/lib/lwes/struct.rb +9 -2
- data/lib/lwes/type_db.rb +15 -8
- data/lwes.gemspec +1 -1
- metadata +2 -2
data/ChangeLog
CHANGED
data/README
CHANGED
@@ -51,26 +51,6 @@ See link:LWES.html
|
|
51
51
|
|
52
52
|
For prototyping and development, it may be easier to not use an ESF
|
53
53
|
file. In those cases, you may skip the TypeDB steps entirely and
|
54
|
-
just use an emitter to send Hash objects
|
55
|
-
|
56
|
-
|
57
|
-
:port => 12345,
|
58
|
-
:heartbeat => 30, # nil to disable
|
59
|
-
:ttl => 1) # nil for default TTL(3)
|
60
|
-
|
61
|
-
# Since we can't reliably map certain Ruby types to LWES types, you'll
|
62
|
-
# have to specify them explicitly for IP addresses and all Integer
|
63
|
-
# types.
|
64
|
-
event = {
|
65
|
-
:time_sec => [ :int32, Time.now.to_i ],
|
66
|
-
:time_usec => [ :int32, Time.now.tv_usec ],
|
67
|
-
:remote_addr => [ :ip_addr, "192.168.0.1" ],
|
68
|
-
}
|
69
|
-
|
70
|
-
# Strings and Boolean values are easily mapped, however:
|
71
|
-
event[:field1] = "String value"
|
72
|
-
event[:boolean1] = true
|
73
|
-
event[:boolean2] = false
|
74
|
-
|
75
|
-
# finally, we just emit the hash with any given name
|
76
|
-
emitter.emit "Event3", event
|
54
|
+
just use an emitter to send Hash objects.
|
55
|
+
|
56
|
+
See "NON-ESF USERS" section in link:LWES/Emitter.html
|
data/ext/lwes_ext/emitter.c
CHANGED
@@ -338,10 +338,10 @@ static VALUE emit_event(VALUE self, VALUE event)
|
|
338
338
|
}
|
339
339
|
/*
|
340
340
|
* call-seq:
|
341
|
-
* emitter = LWES::Emitter.new
|
342
|
-
* event = EventStruct.new
|
343
|
-
* event.foo = "bar"
|
344
341
|
* emitter << event
|
342
|
+
*
|
343
|
+
* Emits the given +event+ which much be an LWES::Event or
|
344
|
+
* LWES::Struct-derived object
|
345
345
|
*/
|
346
346
|
static VALUE emitter_ltlt(VALUE self, VALUE event)
|
347
347
|
{
|
@@ -356,15 +356,22 @@ static VALUE emitter_ltlt(VALUE self, VALUE event)
|
|
356
356
|
|
357
357
|
/*
|
358
358
|
* call-seq:
|
359
|
-
*
|
359
|
+
* emitter.emit("EventName", :foo => "HI")
|
360
|
+
* emitter.emit("EventName", :foo => [ :int32, 123 ])
|
361
|
+
* emitter.emit(EventClass, :foo => "HI")
|
362
|
+
* emitter.emit(event)
|
360
363
|
*
|
361
|
-
*
|
364
|
+
* Emits a hash. If EventName is given as a string, it will expect a hash
|
365
|
+
* as its second argument and will do its best to serialize a Ruby Hash
|
366
|
+
* to an LWES Event. If a type is ambiguous, a two-element array may be
|
367
|
+
* specified as its value, including the LWES type information and the
|
368
|
+
* Ruby value.
|
362
369
|
*
|
363
|
-
*
|
370
|
+
* If an EventClass is given, the second argument should be a hash with
|
371
|
+
* the values given to the class. This will emit the event named by
|
372
|
+
* EventClass.
|
364
373
|
*
|
365
|
-
*
|
366
|
-
* struct.foo = "HI"
|
367
|
-
* emitter.emit(struct)
|
374
|
+
* If only one argument is given, it behaves just like LWES::Emitter#<<
|
368
375
|
*/
|
369
376
|
static VALUE emitter_emit(int argc, VALUE *argv, VALUE self)
|
370
377
|
{
|
@@ -412,6 +419,9 @@ static VALUE emitter_emit(int argc, VALUE *argv, VALUE self)
|
|
412
419
|
}
|
413
420
|
|
414
421
|
/*
|
422
|
+
* call-seq:
|
423
|
+
* emitter.close -> nil
|
424
|
+
*
|
415
425
|
* Destroys the associated lwes_emitter and the associated socket. This
|
416
426
|
* method is rarely needed as Ruby garbage collection will take care of
|
417
427
|
* closing for you, but may be useful in odd cases when it is desirable
|
@@ -468,7 +478,7 @@ static VALUE init_copy(VALUE dest, VALUE obj)
|
|
468
478
|
return dest;
|
469
479
|
}
|
470
480
|
|
471
|
-
/* should only used internally by #initialize */
|
481
|
+
/* :nodoc: should only used internally by #initialize */
|
472
482
|
static VALUE _create(VALUE self, VALUE options)
|
473
483
|
{
|
474
484
|
struct _rb_lwes_emitter *rle = _rle(self);
|
@@ -554,5 +564,10 @@ void lwesrb_init_emitter(void)
|
|
554
564
|
sym_enc = ID2SYM(id_enc);
|
555
565
|
|
556
566
|
ENC = rb_obj_freeze(rb_str_new2(LWES_ENCODING));
|
567
|
+
|
568
|
+
/*
|
569
|
+
* the key in an LWES::Event to designate the encoding of
|
570
|
+
* an event, currently "enc"
|
571
|
+
*/
|
557
572
|
rb_define_const(mLWES, "ENCODING", ENC);
|
558
573
|
}
|
data/ext/lwes_ext/event.c
CHANGED
@@ -90,6 +90,14 @@ static char *key2attr(VALUE key)
|
|
90
90
|
return StringValueCStr(key);
|
91
91
|
}
|
92
92
|
|
93
|
+
/*
|
94
|
+
* call-seq:
|
95
|
+
*
|
96
|
+
* event[key] -> value
|
97
|
+
*
|
98
|
+
* Returns the +value+ stored with the +key+. This will return +nil+ if
|
99
|
+
* +key+ does not exist. +key+ must be a Symbol or String object
|
100
|
+
*/
|
93
101
|
static VALUE event_aref(VALUE self, VALUE key)
|
94
102
|
{
|
95
103
|
char *attr = key2attr(key);
|
@@ -100,6 +108,14 @@ static VALUE event_aref(VALUE self, VALUE key)
|
|
100
108
|
return eattr ? lwesrb_attr_to_value(eattr) : Qnil;
|
101
109
|
}
|
102
110
|
|
111
|
+
/*
|
112
|
+
* call-seq:
|
113
|
+
*
|
114
|
+
* event[key] = value
|
115
|
+
*
|
116
|
+
* Assigns +value+ to be stored in the event given by +key+.
|
117
|
+
* +key+ must be a String or Symbol object.
|
118
|
+
*/
|
103
119
|
static VALUE event_aset(VALUE self, VALUE key, VALUE val)
|
104
120
|
{
|
105
121
|
char *attr = key2attr(key);
|
@@ -174,7 +190,13 @@ static VALUE lwesrb_attr_to_value(struct lwes_event_attribute *attr)
|
|
174
190
|
}
|
175
191
|
|
176
192
|
/*
|
177
|
-
*
|
193
|
+
* call-seq:
|
194
|
+
*
|
195
|
+
* event.to_hash -> Hash
|
196
|
+
*
|
197
|
+
* Returns an LWES::Event object as a plain Ruby hash. Useful for
|
198
|
+
* interoperating with existing Ruby code and also when you don't
|
199
|
+
* have Event Specification Files finalized (or available).
|
178
200
|
*/
|
179
201
|
static VALUE to_hash(VALUE self)
|
180
202
|
{
|
@@ -227,13 +249,9 @@ VALUE lwesrb_wrap_event(VALUE klass, struct lwes_event *e)
|
|
227
249
|
/*
|
228
250
|
* call-seq:
|
229
251
|
*
|
230
|
-
*
|
231
|
-
* receiver.bind(nil, 12345)
|
232
|
-
* buf, addr = receiver.recvfrom(65536)
|
233
|
-
* parsed = LWES::Event.parse(buf)
|
234
|
-
* parsed.to_hash -> hash
|
252
|
+
* LWES::Event.parse(buffer) -> LWES::Event
|
235
253
|
*
|
236
|
-
* Parses a string +
|
254
|
+
* Parses a string +buffer+ and returns a new LWES::Event object
|
237
255
|
*/
|
238
256
|
static VALUE parse(VALUE self, VALUE buf)
|
239
257
|
{
|
data/ext/lwes_ext/type_db.c
CHANGED
@@ -15,6 +15,13 @@ static VALUE tdb_alloc(VALUE klass)
|
|
15
15
|
return Data_Wrap_Struct(klass, NULL, tdb_free, NULL);
|
16
16
|
}
|
17
17
|
|
18
|
+
/*
|
19
|
+
* call-seq:
|
20
|
+
*
|
21
|
+
* LWES::TypeDB.new("events.esf") -> LWES::TypeDB
|
22
|
+
*
|
23
|
+
* Initializes a new TypeDB object based on the path to a given ESF file.
|
24
|
+
*/
|
18
25
|
static VALUE tdb_init(VALUE self, VALUE path)
|
19
26
|
{
|
20
27
|
struct lwes_event_type_db *db = DATA_PTR(self);
|
@@ -101,6 +108,7 @@ struct lwes_event_type_db * lwesrb_get_type_db(VALUE self)
|
|
101
108
|
return db;
|
102
109
|
}
|
103
110
|
|
111
|
+
/* :nodoc: */
|
104
112
|
static VALUE tdb_to_hash(VALUE self)
|
105
113
|
{
|
106
114
|
struct lwes_event_type_db *db = DATA_PTR(self);
|
data/lib/lwes.rb
CHANGED
@@ -36,8 +36,8 @@
|
|
36
36
|
# emitter.emit MyApp::Event2, :field1 => value1, :field2 => value2 # ...
|
37
37
|
#
|
38
38
|
module LWES
|
39
|
-
# version of our library, currently 0.8.
|
40
|
-
VERSION = "0.8.
|
39
|
+
# version of our library, currently 0.8.2
|
40
|
+
VERSION = "0.8.2"
|
41
41
|
|
42
42
|
autoload :ClassMaker, "lwes/class_maker"
|
43
43
|
autoload :TypeDB, "lwes/type_db"
|
data/lib/lwes/emitter.rb
CHANGED
@@ -1,19 +1,52 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
# The LWES::Emitter is used for emitting LWES events to a multicast
|
2
|
+
# network or a single host. It can emit LWES::Event objects, LWES::Struct
|
3
|
+
# objects, and even plain Ruby hashes.
|
4
|
+
#
|
5
|
+
# It is non-blocking and does not guarantee delivery.
|
6
|
+
#
|
7
|
+
#
|
8
|
+
# emitter = LWES::Emitter.new(:address => '224.1.1.11',
|
9
|
+
# :port => 12345,
|
10
|
+
# :heartbeat => 30, # nil to disable
|
11
|
+
# :ttl => 1) # nil for default TTL(3)
|
12
|
+
# event = MyEvent.new
|
13
|
+
# event.foo = "bar"
|
14
|
+
#
|
15
|
+
# emitter << event
|
16
|
+
#
|
17
|
+
# === NON-ESF USERS
|
18
|
+
#
|
19
|
+
# Since we can't reliably map certain Ruby types to LWES types, you'll
|
20
|
+
# have to specify them explicitly for IP addresses and all Integer
|
21
|
+
# types.
|
22
|
+
#
|
23
|
+
# event = {
|
24
|
+
# :time_sec => [ :int32, Time.now.to_i ],
|
25
|
+
# :time_usec => [ :int32, Time.now.tv_usec ],
|
26
|
+
# :remote_addr => [ :ip_addr, "192.168.0.1" ],
|
27
|
+
# }
|
28
|
+
#
|
29
|
+
# # Strings and Boolean values are easily mapped, however:
|
30
|
+
# event[:field1] = "String value"
|
31
|
+
# event[:boolean1] = true
|
32
|
+
# event[:boolean2] = false
|
33
|
+
#
|
34
|
+
# # finally, we just emit the hash with any given name
|
35
|
+
# emitter.emit "Event3", event
|
36
|
+
class LWES::Emitter
|
3
37
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
end
|
38
|
+
# creates a new Emitter object which may be used for the lifetime
|
39
|
+
# of the process:
|
40
|
+
#
|
41
|
+
# LWES::Emitter.new(:address => '224.1.1.11',
|
42
|
+
# :iface => '0.0.0.0',
|
43
|
+
# :port => 12345,
|
44
|
+
# :heartbeat => false, # Integer for frequency
|
45
|
+
# :ttl => 60, # nil for no ttl)
|
46
|
+
#
|
47
|
+
def initialize(options = {}, &block)
|
48
|
+
options[:iface] ||= '0.0.0.0'
|
49
|
+
_create(options)
|
50
|
+
block_given?
|
18
51
|
end
|
19
52
|
end
|
data/lib/lwes/event.rb
CHANGED
@@ -2,7 +2,17 @@
|
|
2
2
|
# LWES::Event-derived classes are more memory efficient if your event
|
3
3
|
# definitions have many unused fields.
|
4
4
|
#
|
5
|
-
# LWES::TypeDB.create_classes! with +:sparse+ set to +true+
|
5
|
+
# LWES::TypeDB.create_classes! with +:sparse+ set to +true+ will create
|
6
|
+
# classes subclassed from LWES::Event instead of LWES::Struct.
|
7
|
+
#
|
8
|
+
# For users unable to use LWES::Listener, LWES::Event.parse may also be
|
9
|
+
# used with UDPSocket (distributed with Ruby) to parse events:
|
10
|
+
#
|
11
|
+
# receiver = UDPSocket.new
|
12
|
+
# receiver.bind(nil, port)
|
13
|
+
# buffer, addr = receiver.recvfrom(65536)
|
14
|
+
# event = LWES::Event.parse(buffer)
|
15
|
+
|
6
16
|
class LWES::Event
|
7
17
|
SYM2ATTR = Hash.new { |h,k| h[k] = k.to_s.freeze } # :nodoc:
|
8
18
|
|
@@ -10,6 +20,10 @@ class LWES::Event
|
|
10
20
|
CLASSES = {} # :nodoc:
|
11
21
|
extend LWES::ClassMaker
|
12
22
|
|
23
|
+
# There is no need to call this method directly. use
|
24
|
+
# LWES::TypeDB.create_classes! with the +:sparse+ flag set to +true+.
|
25
|
+
#
|
26
|
+
# This takes the same options as LWES::Struct.new.
|
13
27
|
def self.subclass(options, &block)
|
14
28
|
db = type_db(options)
|
15
29
|
dump = db.to_hash
|
@@ -29,6 +43,7 @@ class LWES::Event
|
|
29
43
|
CLASSES[name] = tmp
|
30
44
|
end
|
31
45
|
|
46
|
+
# returns a human-readable representation of the event
|
32
47
|
def inspect
|
33
48
|
klass = self.class
|
34
49
|
if LWES::Event == klass
|
@@ -38,6 +53,7 @@ class LWES::Event
|
|
38
53
|
end
|
39
54
|
end
|
40
55
|
|
56
|
+
# overwrites the values of the existing event with those given in +src+
|
41
57
|
def merge! src
|
42
58
|
src.to_hash.each { |k,v| self[k] = v }
|
43
59
|
self
|
@@ -45,12 +61,16 @@ class LWES::Event
|
|
45
61
|
|
46
62
|
alias_method :initialize_copy, :merge!
|
47
63
|
|
64
|
+
# duplicates the given event and overwrites the copy with values given
|
65
|
+
# in +src+
|
48
66
|
def merge src
|
49
67
|
dup.merge! src
|
50
68
|
end
|
51
69
|
|
52
70
|
private
|
53
71
|
|
72
|
+
# Initializes a new LWES::Event. If +src+ is given, it must be an
|
73
|
+
# LWES::Event or hash which the new event takes initial values from
|
54
74
|
def initialize(src = nil)
|
55
75
|
src and merge! src
|
56
76
|
end
|
data/lib/lwes/listener.rb
CHANGED
data/lib/lwes/struct.rb
CHANGED
@@ -3,11 +3,18 @@
|
|
3
3
|
#
|
4
4
|
# LWES::Struct is may be more memory-efficient and faster if your application
|
5
5
|
# uses all or most of the fields in the event definition. LWES::Event should
|
6
|
-
# be used in cases where many event fields are unused in
|
6
|
+
# be used in cases where many event fields are unused in an event definition.
|
7
|
+
#
|
8
|
+
# LWES::Struct is created by LWES::TypeDB#create_classes! by default
|
9
|
+
# where the +:sparse+ flag is +false+. There is little need to use this
|
10
|
+
# class directly.
|
7
11
|
class LWES::Struct
|
8
12
|
extend LWES::ClassMaker
|
9
13
|
|
10
|
-
#
|
14
|
+
# There is usually no need to use this method,
|
15
|
+
# LWES::TypeDB.create_classes! will call this for you
|
16
|
+
#
|
17
|
+
# Creates a new Struct-based class, takes the following
|
11
18
|
# options hash:
|
12
19
|
#
|
13
20
|
# :db - pre-created LWES::TypeDB object
|
data/lib/lwes/type_db.rb
CHANGED
@@ -1,3 +1,6 @@
|
|
1
|
+
# This class may be used to load an ESF (event specification files)
|
2
|
+
# and automatically create Ruby classes based on the ESF.
|
3
|
+
|
1
4
|
class LWES::TypeDB
|
2
5
|
|
3
6
|
# create LWES::Struct-derived classes based on the contents
|
@@ -8,19 +11,23 @@ class LWES::TypeDB
|
|
8
11
|
# module MyEvents; end
|
9
12
|
#
|
10
13
|
# type_db = LWES::TypeDB.new("my_events.esf")
|
11
|
-
# type_db.create_classes!(:parent => MyEvents)
|
12
|
-
# type_db.create_classes!(:sparse => true)
|
14
|
+
# type_db.create_classes!(:parent => MyEvents, :sparse => true)
|
13
15
|
#
|
14
16
|
# Assuming you had "Event1" and "Event2" defined in your "my_events.esf"
|
15
17
|
# file, then the classes MyEvents::Event1 and MyEvents::Event2 should
|
16
18
|
# now be accessible.
|
17
19
|
#
|
18
|
-
#
|
19
|
-
#
|
20
|
-
#
|
21
|
-
#
|
22
|
-
#
|
23
|
-
#
|
20
|
+
# [ :parent => class or nil ]
|
21
|
+
#
|
22
|
+
# Parent class or module, the default is 'Object' putting
|
23
|
+
# the new class in the global namespace. May be +nil+ for
|
24
|
+
# creating anonymous classes.
|
25
|
+
#
|
26
|
+
# [ :sparse => true or false ]
|
27
|
+
#
|
28
|
+
# If +true+, this will subclass from LWES::Event instead of
|
29
|
+
# Struct for better memory efficiency when dealing with
|
30
|
+
# events with many unused fields. Default is +false+.
|
24
31
|
def create_classes!(options = {})
|
25
32
|
classes = to_hash.keys - [ :MetaEventInfo ]
|
26
33
|
classes.sort { |a,b| a.to_s.size <=> b.to_s.size }.map! do |klass|
|
data/lwes.gemspec
CHANGED
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: lwes
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 0.8.
|
5
|
+
version: 0.8.2
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Erik S. Chang
|
@@ -11,7 +11,7 @@ autorequire:
|
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
13
|
|
14
|
-
date: 2011-04-
|
14
|
+
date: 2011-04-28 00:00:00 +00:00
|
15
15
|
default_executable:
|
16
16
|
dependencies:
|
17
17
|
- !ruby/object:Gem::Dependency
|