lwes 0.7.0 → 0.8.0pre1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,4 @@
1
+ *.o
2
+ *.so
3
+ *.log
4
+ /tmp
data/ChangeLog CHANGED
@@ -1,3 +1,7 @@
1
+ Version 0.8.0pre1 (erik-s-chang)
2
+ * preliminary LWES::Listener support for Ruby 1.9 users
3
+ * LWES::Event enhancements and cleanups
4
+
1
5
  Version 0.7.0 (erik-s-chang)
2
6
  * rely on lwes-c 0.23.1 instead of patching 0.22.3
3
7
 
data/README CHANGED
@@ -1,7 +1,7 @@
1
- = LWES - Light Weight Event System API for Ruby
1
+ = LWES - Light Weight Event System bindings for Ruby
2
2
 
3
3
  * http://www.lwes.org
4
- * http://sourceforge.net/projects/lwes
4
+ * git://rubyforge.org/lwes.git
5
5
 
6
6
  == DESCRIPTION:
7
7
 
@@ -23,13 +23,16 @@ may support listening and journaling capabilities as time allows.
23
23
 
24
24
  == SUPPORT:
25
25
 
26
- See the SourceForge project.
26
+ Email the author: mailto:erik.s.chang@gmail.com and expect a response
27
+ within 72 hours.
27
28
 
28
29
  == DEVELOPMENT:
29
30
 
30
- Our SVN repository is here:
31
+ Our git repository is here:
31
32
 
32
- https://lwes.svn.sourceforge.net/svnroot/lwes/lwes-ruby
33
+ git clone git://rubyforge.org/lwes.git
34
+
35
+ Email pull requests or patches to the the author mailto:erik.s.chang@gmail.com
33
36
 
34
37
  == INSTALL:
35
38
 
@@ -40,42 +43,9 @@ gem.
40
43
 
41
44
  gem install lwes
42
45
 
43
- == SYNOPSIS:
44
-
45
- require 'lwes'
46
-
47
- # create an Emitter which may be used for the lifetime of your process
48
- emitter = LWES::Emitter.new(:address => '224.1.1.11',
49
- :port => 12345,
50
- :heartbeat => 30, # nil to disable
51
- :ttl => 1) # nil for default TTL(3)
52
-
53
- # parse your ESF file at startup, the example below assumes you
54
- # have "Event1" and "Event2" defined in your ESF file:
55
- type_db = LWES::TypeDB.new("my_events.esf")
56
-
57
- # create classes to use, by default and to encourage DRY-ness,
58
- # we map each event in the ESF file to a class
59
- # Optionally, you may specify :parent => module/namespace
60
- type_db.create_classes! :parent => MyApp
61
-
62
- # inside your application, you may now do this to slowly build up
63
- # fields for the event
64
- my_event = MyApp::Event1.new
65
- my_event.started = Time.now.to_i
66
- my_event.remote_addr = "192.168.0.1"
67
- # ...do a lot of stuff here in between...
68
- my_event.field1 = value1
69
- my_event.field2 = value2
70
- my_event.field3 = value3
71
- my_event.finished = Time.now.to_i
72
- emitter << my_event
73
-
74
- # Alternatively, if you know ahead of time all the fields you want to
75
- # set for an event, you can emit an event in one step:
76
-
77
- emitter.emit MyApp::Event2, :field1 => value1, :field2 => value2 # ...
46
+ == SYNOPSIS
78
47
 
48
+ See link:LWES.html
79
49
 
80
50
  == NON-ESF USERS:
81
51
 
data/Rakefile CHANGED
@@ -1,21 +1,24 @@
1
1
  require 'rake/testtask'
2
+ task :default => :test
2
3
 
3
4
  desc "run all tests"
4
5
  task :test => %w(test:unit)
5
6
 
6
7
  desc "run unit tests"
7
- Rake::TestTask.new('test:unit') do |t|
8
- t.libs << "ext/lwes"
8
+ Rake::TestTask.new('test:unit' => :compile) do |t|
9
+ t.libs << "ext/lwes_ext"
9
10
  t.test_files = FileList['test/unit/test_*.rb']
10
11
  t.warning = true
11
12
  t.verbose = true if ENV["VERBOSE"].to_i > 0
12
13
  end
14
+ require "rake/extensiontask"
15
+ Rake::ExtensionTask.new("lwes_ext")
13
16
 
14
- gem 'rdoc', '>= 2.4.3'
17
+ gem 'rdoc', '>= 3.5.3'
15
18
  require 'rdoc/task'
16
19
  RDoc::Task.new do |rd|
17
20
  rd.main = "README"
18
- rd.rdoc_files.include("README", "lib/**/*.rb", "ext/lwes/*.c")
21
+ rd.rdoc_files.include("README", "lib/**/*.rb", "ext/lwes_ext/*.c")
19
22
  end
20
23
 
21
24
  desc "update website"
@@ -0,0 +1,2 @@
1
+ Makefile
2
+ /.inst
@@ -3,36 +3,23 @@
3
3
  static VALUE ENC; /* LWES_ENCODING */
4
4
  static ID id_TYPE_DB, id_TYPE_LIST, id_NAME, id_HAVE_ENCODING;
5
5
  static ID id_new, id_enc, id_size;
6
- static ID sym_enc;
6
+ static VALUE sym_enc;
7
7
 
8
- static void dump_name(VALUE name, LWES_BYTE_P buf, size_t *off)
8
+ static void dump_name(char *name, LWES_BYTE_P buf, size_t *off)
9
9
  {
10
- char *s = RSTRING_PTR(name);
11
-
12
- if (marshall_SHORT_STRING(s, buf, MAX_MSG_SIZE, off) > 0)
10
+ if (marshall_SHORT_STRING(name, buf, MAX_MSG_SIZE, off) > 0)
13
11
  return;
14
- rb_raise(rb_eRuntimeError, "failed to dump name=%s", s);
12
+ rb_raise(rb_eRuntimeError, "failed to dump name=%s", name);
15
13
  }
16
14
 
17
- static int dump_bool(VALUE name, VALUE val, LWES_BYTE_P buf, size_t *off)
15
+ static int dump_bool(char *name, VALUE val, LWES_BYTE_P buf, size_t *off)
18
16
  {
19
- LWES_BOOLEAN tmp = FALSE;
20
-
21
- if (val == Qtrue) {
22
- tmp = TRUE;
23
- } else if (val != Qfalse) {
24
- volatile VALUE raise_inspect;
25
-
26
- rb_raise(rb_eTypeError, "non-boolean set for %s: %s",
27
- RSTRING_PTR(name),
28
- RAISE_INSPECT(val));
29
- }
30
17
  dump_name(name, buf, off);
31
18
  lwesrb_dump_type(LWES_BOOLEAN_TOKEN, buf, off);
32
- return marshall_BOOLEAN(tmp, buf, MAX_MSG_SIZE, off);
19
+ return marshall_BOOLEAN(lwesrb_boolean(val), buf, MAX_MSG_SIZE, off);
33
20
  }
34
21
 
35
- static int dump_string(VALUE name, VALUE val, LWES_BYTE_P buf, size_t *off)
22
+ static int dump_string(char *name, VALUE val, LWES_BYTE_P buf, size_t *off)
36
23
  {
37
24
  char *dst;
38
25
 
@@ -41,7 +28,7 @@ static int dump_string(VALUE name, VALUE val, LWES_BYTE_P buf, size_t *off)
41
28
  case T_FIXNUM:
42
29
  val = rb_obj_as_string(val);
43
30
  }
44
- dst = StringValuePtr(val);
31
+ dst = StringValueCStr(val);
45
32
 
46
33
  dump_name(name, buf, off);
47
34
  lwesrb_dump_type(LWES_STRING_TOKEN, buf, off);
@@ -50,7 +37,7 @@ static int dump_string(VALUE name, VALUE val, LWES_BYTE_P buf, size_t *off)
50
37
 
51
38
  static void dump_enc(VALUE enc, LWES_BYTE_P buf, size_t *off)
52
39
  {
53
- dump_name(ENC, buf, off);
40
+ dump_name((char *)LWES_ENCODING, buf, off);
54
41
  lwesrb_dump_num(LWES_INT_16_TOKEN, enc, buf, off);
55
42
  }
56
43
 
@@ -106,6 +93,11 @@ static VALUE rle_alloc(VALUE klass)
106
93
  NULL, rle_free, rle);
107
94
  }
108
95
 
96
+ struct hash_memo {
97
+ size_t off;
98
+ LWES_BYTE_P buf;
99
+ };
100
+
109
101
  /*
110
102
  * kv - Array:
111
103
  * key => String,
@@ -117,12 +109,14 @@ static VALUE rle_alloc(VALUE klass)
117
109
  static VALUE event_hash_iter_i(VALUE kv, VALUE memo)
118
110
  {
119
111
  volatile VALUE raise_inspect;
120
- VALUE *tmp = (VALUE *)memo;
112
+ struct hash_memo *hash_memo = (struct hash_memo *)NUM2ULONG(memo);
121
113
  VALUE val;
122
114
  VALUE name;
115
+ char *attr_name;
123
116
  int rv = 0;
124
- LWES_BYTE_P buf = (LWES_BYTE_P)tmp[0];
125
- size_t *off = (size_t *)tmp[1];
117
+ LWES_BYTE_P buf = hash_memo->buf;
118
+ size_t *off = &hash_memo->off;
119
+ VALUE *tmp;
126
120
 
127
121
  if (TYPE(kv) != T_ARRAY || RARRAY_LEN(kv) != 2)
128
122
  rb_raise(rb_eTypeError,
@@ -133,8 +127,9 @@ static VALUE event_hash_iter_i(VALUE kv, VALUE memo)
133
127
  if (name == sym_enc) return Qnil; /* already dumped first */
134
128
 
135
129
  name = rb_obj_as_string(name);
130
+ attr_name = StringValueCStr(name);
136
131
 
137
- if (strcmp(RSTRING_PTR(name), LWES_ENCODING) == 0)
132
+ if (strcmp(attr_name, LWES_ENCODING) == 0)
138
133
  return Qnil;
139
134
 
140
135
  val = tmp[1];
@@ -142,14 +137,14 @@ static VALUE event_hash_iter_i(VALUE kv, VALUE memo)
142
137
  switch (TYPE(val)) {
143
138
  case T_TRUE:
144
139
  case T_FALSE:
145
- rv = dump_bool(name, val, buf, off);
140
+ rv = dump_bool(attr_name, val, buf, off);
146
141
  break;
147
142
  case T_ARRAY:
148
- dump_name(name, buf, off);
143
+ dump_name(attr_name, buf, off);
149
144
  lwesrb_dump_num_ary(val, buf, off);
150
145
  return Qnil;
151
146
  case T_STRING:
152
- rv = dump_string(name, val, buf, off);
147
+ rv = dump_string(attr_name, val, buf, off);
153
148
  break;
154
149
  }
155
150
 
@@ -157,31 +152,31 @@ static VALUE event_hash_iter_i(VALUE kv, VALUE memo)
157
152
  return Qnil;
158
153
 
159
154
  rb_raise(rb_eArgError, "unhandled type %s=%s",
160
- RSTRING_PTR(name), RAISE_INSPECT(val));
155
+ attr_name, RAISE_INSPECT(val));
161
156
  return Qfalse;
162
157
  }
163
158
 
164
159
  static VALUE emit_hash(VALUE self, VALUE name, VALUE event)
165
160
  {
166
161
  struct _rb_lwes_emitter *rle = _rle(self);
167
- LWES_BYTE_P buf = rle->emitter->buffer;
168
- VALUE tmp[2];
169
- size_t off = 0;
162
+ struct hash_memo hash_memo;
163
+ LWES_BYTE_P buf;
164
+ size_t *off;
165
+ VALUE memo = ULONG2NUM((unsigned long)&hash_memo);
170
166
  VALUE enc;
171
- int size = NUM2INT(rb_funcall(event, id_size, 0, 0));
167
+ LWES_U_INT_16 size = lwesrb_uint16(rb_funcall(event, id_size, 0, 0));
172
168
  int rv;
169
+ char *event_name = StringValueCStr(name);
173
170
 
174
- tmp[0] = (VALUE)buf;
175
- tmp[1] = (VALUE)&off;
176
-
177
- if (size < 0 || size > UINT16_MAX)
178
- rb_raise(rb_eRangeError, "hash size out of uint16 range");
171
+ buf = hash_memo.buf = rle->emitter->buffer;
172
+ hash_memo.off = 0;
173
+ off = &hash_memo.off;
179
174
 
180
175
  /* event name first */
181
- dump_name(name, buf, &off);
176
+ dump_name(event_name, buf, off);
182
177
 
183
178
  /* number of attributes second */
184
- rv = marshall_U_INT_16((LWES_U_INT_16)size, buf, MAX_MSG_SIZE, &off);
179
+ rv = marshall_U_INT_16(size, buf, MAX_MSG_SIZE, off);
185
180
  if (rv <= 0)
186
181
  rb_raise(rb_eRuntimeError, "failed to dump num_attrs");
187
182
 
@@ -190,12 +185,12 @@ static VALUE emit_hash(VALUE self, VALUE name, VALUE event)
190
185
  if (NIL_P(enc))
191
186
  enc = rb_hash_aref(event, ENC);
192
187
  if (! NIL_P(enc))
193
- dump_enc(enc, buf, &off);
188
+ dump_enc(enc, buf, off);
194
189
 
195
190
  /* the rest of the fields */
196
- rb_iterate(rb_each, event, event_hash_iter_i, (VALUE)&tmp);
191
+ rb_iterate(rb_each, event, event_hash_iter_i, memo);
197
192
 
198
- if (lwes_emitter_emit_bytes(rle->emitter, buf, off) < 0)
193
+ if (lwes_emitter_emit_bytes(rle->emitter, buf, *off) < 0)
199
194
  rb_raise(rb_eRuntimeError, "failed to emit event");
200
195
 
201
196
  return event;
@@ -203,7 +198,7 @@ static VALUE emit_hash(VALUE self, VALUE name, VALUE event)
203
198
 
204
199
  static void
205
200
  marshal_field(
206
- VALUE name,
201
+ char *name,
207
202
  LWES_TYPE type,
208
203
  VALUE val,
209
204
  LWES_BYTE_P buf,
@@ -227,7 +222,7 @@ marshal_field(
227
222
  }
228
223
 
229
224
  rb_raise(rb_eRuntimeError, "failed to set %s=%s",
230
- RSTRING_PTR(name), RAISE_INSPECT(val));
225
+ name, RAISE_INSPECT(val));
231
226
  }
232
227
 
233
228
  static void lwes_struct_class(
@@ -253,6 +248,19 @@ static void lwes_struct_class(
253
248
  *have_enc = rb_const_get(*event_class, id_HAVE_ENCODING);
254
249
  }
255
250
 
251
+ #if !defined(RSTRUCT_PTR) && defined(RSTRUCT)
252
+ # define RSTRUCT_PTR(s) (RSTRUCT(s)->ptr)
253
+ #endif
254
+ static VALUE * rstruct_ptr(VALUE *ary, VALUE rstruct)
255
+ {
256
+ #ifdef RSTRUCT_PTR
257
+ return RSTRUCT_PTR(*ary = rstruct);
258
+ #else
259
+ *ary = rb_funcall(rstruct, rb_intern("to_a"), 0, 0);
260
+ return RARRAY_PTR(*ary);
261
+ #endif
262
+ }
263
+
256
264
  static VALUE emit_struct(VALUE self, VALUE event)
257
265
  {
258
266
  VALUE event_class, name, type_list, have_enc;
@@ -264,11 +272,13 @@ static VALUE emit_struct(VALUE self, VALUE event)
264
272
  LWES_U_INT_16 num_attr = 0;
265
273
  size_t num_attr_off;
266
274
  VALUE *flds;
275
+ char *str;
267
276
 
268
277
  lwes_struct_class(&event_class, &name, &type_list, &have_enc, event);
269
278
 
270
279
  /* event name */
271
- dump_name(name, buf, &off);
280
+ str = StringValueCStr(name);
281
+ dump_name(str, buf, &off);
272
282
 
273
283
  /* number of attributes, use a placeholder until we've iterated */
274
284
  num_attr_off = off;
@@ -286,12 +296,12 @@ static VALUE emit_struct(VALUE self, VALUE event)
286
296
  }
287
297
 
288
298
  i = RARRAY_LEN(type_list);
289
- flds = RSTRUCT_PTR(event);
299
+ flds = rstruct_ptr(&name, event);
290
300
  tmp = RARRAY_PTR(type_list);
291
301
  for (; --i >= 0; tmp++, flds++) {
292
302
  /* inner: [ :field_sym, "field_name", type ] */
293
303
  VALUE *inner = RARRAY_PTR(*tmp);
294
- VALUE val, name;
304
+ VALUE val;
295
305
  LWES_TYPE type;
296
306
 
297
307
  if (inner[0] == sym_enc) /* encoding was already dumped */
@@ -301,10 +311,10 @@ static VALUE emit_struct(VALUE self, VALUE event)
301
311
  if (NIL_P(val))
302
312
  continue; /* LWES doesn't know nil */
303
313
 
304
- name = inner[1];
314
+ str = StringValueCStr(inner[1]);
305
315
  type = NUM2INT(inner[2]);
306
316
  ++num_attr;
307
- marshal_field(name, type, val, buf, &off);
317
+ marshal_field(str, type, val, buf, &off);
308
318
  }
309
319
 
310
320
  /* now we've iterated, we can accurately give num_attr */
@@ -476,7 +486,7 @@ static VALUE _create(VALUE self, VALUE options)
476
486
  address = rb_hash_aref(options, ID2SYM(rb_intern("address")));
477
487
  if (TYPE(address) != T_STRING)
478
488
  rb_raise(rb_eTypeError, ":address must be a string");
479
- rle->address = my_strdup(RSTRING_PTR(address));
489
+ rle->address = my_strdup(StringValueCStr(address));
480
490
 
481
491
  iface = rb_hash_aref(options, ID2SYM(rb_intern("iface")));
482
492
  switch (TYPE(iface)) {
@@ -484,7 +494,7 @@ static VALUE _create(VALUE self, VALUE options)
484
494
  rle->iface = NULL;
485
495
  break;
486
496
  case T_STRING:
487
- rle->iface = my_strdup(RSTRING_PTR(iface));
497
+ rle->iface = my_strdup(StringValueCStr(iface));
488
498
  break;
489
499
  default:
490
500
  rb_raise(rb_eTypeError, ":iface must be a String or nil");
@@ -1,8 +1,11 @@
1
1
  #include "lwes_ruby.h"
2
2
  VALUE cLWES_Event;
3
3
 
4
+ static VALUE tmp_class_name;
5
+ static VALUE SYM2ATTR, CLASSES;
4
6
  static ID id_TYPE_DB, id_NAME;
5
7
  static VALUE sym_name;
8
+ static VALUE lwesrb_attr_to_value(struct lwes_event_attribute *attr);
6
9
 
7
10
  struct lwes_event * lwesrb_get_event(VALUE self)
8
11
  {
@@ -20,7 +23,6 @@ static void event_free(void *ptr)
20
23
  lwes_event_destroy(event);
21
24
  }
22
25
 
23
-
24
26
  static VALUE event_alloc(VALUE klass)
25
27
  {
26
28
  struct lwes_event *e;
@@ -35,7 +37,7 @@ static VALUE event_alloc(VALUE klass)
35
37
  VALUE type_db = rb_const_get(klass, id_TYPE_DB);
36
38
  struct lwes_event_type_db *tdb = lwesrb_get_type_db(type_db);
37
39
  VALUE name = rb_const_get(klass, id_NAME);
38
- const char *ename = StringValuePtr(name);
40
+ const char *ename = StringValueCStr(name);
39
41
 
40
42
  e = lwes_event_create(tdb, ename);
41
43
  if (e == NULL) {
@@ -49,56 +51,85 @@ static VALUE event_alloc(VALUE klass)
49
51
  return Data_Wrap_Struct(klass, NULL, event_free, e);
50
52
  }
51
53
 
52
- /*
53
- * kv - Array:
54
- * key => String,
55
- * key => [ numeric_type, Numeric ],
56
- * key => true,
57
- * key => false,
58
- * memo - lwes_event pointer
59
- */
60
- static VALUE event_hash_iter_i(VALUE kv, VALUE memo)
61
- {
62
- /* TODO */
63
- }
64
-
65
54
  static struct lwes_event_type_db * get_type_db(VALUE self)
66
55
  {
67
56
  VALUE type_db = rb_const_get(CLASS_OF(self), id_TYPE_DB);
68
- struct lwes_event_type_db *tdb = lwesrb_get_type_db(type_db);
69
57
 
70
- return tdb;
58
+ return lwesrb_get_type_db(type_db);
71
59
  }
72
60
 
73
- static VALUE event_init(int argc, VALUE *argv, VALUE self)
61
+ static LWES_BYTE get_attr_type(VALUE self, char *attr)
74
62
  {
75
- VALUE hash;
76
- struct lwes_event *event;
63
+ struct lwes_event_type_db *tdb = get_type_db(self);
64
+ struct lwes_event *e = lwesrb_get_event(self);
65
+ struct lwes_hash *ehash = lwes_hash_get(tdb->events, e->eventName);
66
+ LWES_BYTE *attr_type;
77
67
 
78
- rb_scan_args(argc, argv, "01", &hash);
68
+ if (ehash == NULL)
69
+ rb_raise(rb_eArgError, "invalid event: %s", e->eventName);
79
70
 
80
- Data_Get_Struct(self, struct lwes_event, event);
71
+ attr_type = lwes_hash_get(ehash, attr);
72
+ if (attr_type)
73
+ return *attr_type;
81
74
 
82
- return self;
75
+ ehash = lwes_hash_get(tdb->events, LWES_META_INFO_STRING);
76
+ if (ehash == NULL)
77
+ rb_raise(rb_eArgError, "%s not found", LWES_META_INFO_STRING);
78
+
79
+ attr_type = lwes_hash_get(ehash, attr);
80
+ if (attr_type)
81
+ return *attr_type;
82
+
83
+ rb_raise(rb_eArgError, "invalid attribute: %s", attr);
83
84
  }
84
85
 
85
- static VALUE event_aset(VALUE self, VALUE key, VALUE val)
86
+ static char *key2attr(VALUE key)
86
87
  {
87
- struct lwes_event_type_db *tdb = get_type_db(self);
88
+ if (TYPE(key) == T_SYMBOL)
89
+ key = rb_hash_aref(SYM2ATTR, key);
90
+ return StringValueCStr(key);
91
+ }
92
+
93
+ static VALUE event_aref(VALUE self, VALUE key)
94
+ {
95
+ char *attr = key2attr(key);
88
96
  struct lwes_event *e = lwesrb_get_event(self);
89
- const char *attr = StringValuePtr(key);
90
- struct lwes_hash *ehash = lwes_hash_get(tdb->events, e->eventName);
91
- LWES_BYTE *attr_type;
97
+ struct lwes_event_attribute *eattr;
92
98
 
93
- if (ehash == NULL)
94
- rb_raise(rb_eArgError, "invalid event: %s\n", e->eventName);
99
+ eattr = lwes_hash_get(e->attributes, attr);
100
+ return eattr ? lwesrb_attr_to_value(eattr) : Qnil;
101
+ }
95
102
 
96
- attr_type = lwes_hash_get(ehash, attr);
97
- if (attr_type == NULL)
98
- rb_raise(rb_eArgError, "invalid attribute: %s\n", attr);
103
+ static VALUE event_aset(VALUE self, VALUE key, VALUE val)
104
+ {
105
+ char *attr = key2attr(key);
106
+ LWES_BYTE attr_type = get_attr_type(self, attr);
107
+ struct lwes_event *e = lwesrb_get_event(self);
99
108
 
100
- switch (*attr_type) {
109
+ if (attr_type == LWES_STRING_TOKEN) {
110
+ lwes_event_set_STRING(e, attr, StringValueCStr(val));
111
+ } else if (attr_type == LWES_U_INT_16_TOKEN) {
112
+ lwes_event_set_U_INT_16(e, attr, lwesrb_uint16(val));
113
+ } else if (attr_type == LWES_INT_16_TOKEN) {
114
+ lwes_event_set_INT_16(e, attr, lwesrb_int16(val));
115
+ } else if (attr_type == LWES_U_INT_32_TOKEN) {
116
+ lwes_event_set_U_INT_32(e, attr, lwesrb_uint32(val));
117
+ } else if (attr_type == LWES_INT_32_TOKEN) {
118
+ lwes_event_set_INT_32(e, attr, lwesrb_int32(val));
119
+ } else if (attr_type == LWES_U_INT_64_TOKEN) {
120
+ lwes_event_set_U_INT_64(e, attr, lwesrb_uint64(val));
121
+ } else if (attr_type == LWES_INT_64_TOKEN) {
122
+ lwes_event_set_INT_64(e, attr, lwesrb_int64(val));
123
+ } else if (attr_type == LWES_IP_ADDR_TOKEN) {
124
+ lwes_event_set_IP_ADDR(e, attr, lwesrb_ip_addr(val));
125
+ } else if (attr_type == LWES_BOOLEAN_TOKEN) {
126
+ lwes_event_set_BOOLEAN(e, attr, lwesrb_boolean(val));
127
+ } else {
128
+ rb_raise(rb_eRuntimeError,
129
+ "unknown LWES attribute type: 0x%02x",
130
+ (unsigned)attr_type);
101
131
  }
132
+ return val;
102
133
  }
103
134
 
104
135
  static VALUE lwesrb_attr_to_value(struct lwes_event_attribute *attr)
@@ -132,6 +163,8 @@ static VALUE lwesrb_attr_to_value(struct lwes_event_attribute *attr)
132
163
  rb_str_set_len(str, strlen(name));
133
164
  return str;
134
165
  } else {
166
+ rb_warn("possible event corruption: attr->type=%02x",
167
+ (unsigned)attr->type);
135
168
  /*
136
169
  * possible event corruption
137
170
  * skip it like the C library does ...
@@ -146,8 +179,49 @@ static VALUE lwesrb_attr_to_value(struct lwes_event_attribute *attr)
146
179
  static VALUE to_hash(VALUE self)
147
180
  {
148
181
  struct lwes_event *e = lwesrb_get_event(self);
182
+ VALUE rv = rb_hash_new();
183
+ VALUE val;
184
+ struct lwes_hash_enumeration hen;
185
+ LWES_SHORT_STRING name;
186
+ VALUE sym_attr_name;
187
+ struct lwes_event_attribute *attr;
149
188
 
150
- return lwesrb_event_to_hash(e);
189
+ if (e->eventName != NULL && CLASS_OF(self) == cLWES_Event) {
190
+ val = rb_str_new2(e->eventName);
191
+ rb_hash_aset(rv, sym_name, val);
192
+ }
193
+
194
+ if (! lwes_hash_keys(e->attributes, &hen))
195
+ return rv;
196
+ while (lwes_hash_enumeration_has_more_elements(&hen)) {
197
+ name = lwes_hash_enumeration_next_element(&hen);
198
+ sym_attr_name = ID2SYM(rb_intern(name));
199
+ attr = lwes_hash_get(e->attributes, name);
200
+ if (attr == NULL)
201
+ rb_raise(rb_eRuntimeError,
202
+ "missing attr during enumeration: %s", name);
203
+ val = lwesrb_attr_to_value(attr);
204
+ if (! NIL_P(val))
205
+ rb_hash_aset(rv, sym_attr_name, val);
206
+ }
207
+
208
+ return rv;
209
+ }
210
+
211
+ VALUE lwesrb_wrap_event(VALUE klass, struct lwes_event *e)
212
+ {
213
+ if (e->eventName) {
214
+ long len = strlen(e->eventName);
215
+ VALUE tmp;
216
+
217
+ rb_str_resize(tmp_class_name, len);
218
+ memcpy(RSTRING_PTR(tmp_class_name), e->eventName, len);
219
+ tmp = rb_hash_aref(CLASSES, tmp_class_name);
220
+ if (tmp != Qnil)
221
+ klass = tmp;
222
+ }
223
+
224
+ return Data_Wrap_Struct(klass, NULL, event_free, e);
151
225
  }
152
226
 
153
227
  /*
@@ -163,8 +237,7 @@ static VALUE to_hash(VALUE self)
163
237
  */
164
238
  static VALUE parse(VALUE self, VALUE buf)
165
239
  {
166
- VALUE event = event_alloc(cLWES_Event);
167
- struct lwes_event *e = lwesrb_get_event(event);
240
+ struct lwes_event *e;
168
241
  struct lwes_event_deserialize_tmp dtmp;
169
242
  LWES_BYTE_P bytes;
170
243
  size_t num_bytes;
@@ -173,39 +246,15 @@ static VALUE parse(VALUE self, VALUE buf)
173
246
  StringValue(buf);
174
247
  bytes = (LWES_BYTE_P)RSTRING_PTR(buf);
175
248
  num_bytes = (size_t)RSTRING_LEN(buf);
249
+ e = lwes_event_create_no_name(NULL);
176
250
  rc = lwes_event_from_bytes(e, bytes, num_bytes, 0, &dtmp);
177
- if (rc < 0)
251
+ if (rc < 0) {
252
+ lwes_event_destroy(e);
178
253
  rb_raise(rb_eRuntimeError,
179
- "failed to parse LWES event (code: %d)\n", rc);
180
- return event;
181
- }
182
-
183
- VALUE lwesrb_event_to_hash(struct lwes_event *e)
184
- {
185
- VALUE rv = rb_hash_new();
186
- VALUE val;
187
- struct lwes_hash_enumeration hen;
188
- LWES_SHORT_STRING name;
189
- VALUE sym_attr_name;
190
- struct lwes_event_attribute *attr;
191
-
192
- if (e->eventName != NULL) {
193
- val = rb_str_new2(e->eventName);
194
- rb_hash_aset(rv, sym_name, val);
254
+ "failed to parse LWES event (code: %d)", rc);
195
255
  }
196
256
 
197
- if (! lwes_hash_keys(e->attributes, &hen))
198
- return rv;
199
- while (lwes_hash_enumeration_has_more_elements(&hen)) {
200
- name = lwes_hash_enumeration_next_element(&hen);
201
- sym_attr_name = ID2SYM(rb_intern(name));
202
- attr = lwes_hash_get(e->attributes, name);
203
- val = lwesrb_attr_to_value(attr);
204
- if (! NIL_P(val))
205
- rb_hash_aset(rv, sym_attr_name, val);
206
- }
207
-
208
- return rv;
257
+ return lwesrb_wrap_event(self, e);
209
258
  }
210
259
 
211
260
  void lwesrb_init_event(void)
@@ -213,10 +262,15 @@ void lwesrb_init_event(void)
213
262
  VALUE mLWES = rb_define_module("LWES");
214
263
  cLWES_Event = rb_define_class_under(mLWES, "Event", rb_cObject);
215
264
 
216
- rb_define_method(cLWES_Event, "initialize", event_init, -1);
265
+ SYM2ATTR = rb_const_get(cLWES_Event, rb_intern("SYM2ATTR"));
266
+ CLASSES = rb_const_get(cLWES_Event, rb_intern("CLASSES"));
217
267
  rb_define_alloc_func(cLWES_Event, event_alloc);
218
268
  rb_define_singleton_method(cLWES_Event, "parse", parse, 1);
219
269
  rb_define_method(cLWES_Event, "to_hash", to_hash, 0);
270
+ rb_define_method(cLWES_Event, "[]", event_aref, 1);
271
+ rb_define_method(cLWES_Event, "[]=", event_aset, 2);
272
+ tmp_class_name = rb_str_new(0, 0);
273
+ rb_global_variable(&tmp_class_name);
220
274
 
221
275
  LWESRB_MKID(TYPE_DB);
222
276
  LWESRB_MKID(NAME);