lwes 0.8.1 → 0.8.2
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/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
|