lwes 0.7.0 → 0.8.0pre1

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 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);