lwes 0.3.1 → 0.4.0
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 +5 -0
- data/ext/lwes/emitter.c +236 -174
- data/ext/lwes/lwes.c +1 -3
- data/ext/lwes/lwes_ruby.h +11 -9
- data/ext/lwes/numeric.c +80 -65
- data/ext/lwes/type_db.c +5 -4
- data/lib/lwes.rb +2 -2
- data/lib/lwes/struct.rb +45 -1
- data/lwes.gemspec +1 -1
- data/test/test_helper.rb +1 -0
- data/test/unit/test_emitter.rb +42 -10
- data/test/unit/test_struct.rb +2 -0
- metadata +2 -2
data/ChangeLog
CHANGED
@@ -1,3 +1,8 @@
|
|
1
|
+
Version 0.4.0 (erik-s-chang)
|
2
|
+
* large performance improvements for ESF + Struct users with large events,
|
3
|
+
one real world app is nearly twice as fast
|
4
|
+
* GC safety fixes when raising exceptions
|
5
|
+
|
1
6
|
Version 0.3.1 (erik-s-chang)
|
2
7
|
* fix tests and enable Ruby warnings for tests
|
3
8
|
|
data/ext/lwes/emitter.c
CHANGED
@@ -1,14 +1,70 @@
|
|
1
1
|
#include "lwes_ruby.h"
|
2
2
|
|
3
|
-
static VALUE
|
4
|
-
static ID id_TYPE_DB, id_TYPE_LIST, id_NAME;
|
5
|
-
static ID id_new;
|
3
|
+
static VALUE ENC; /* LWES_ENCODING */
|
4
|
+
static ID id_TYPE_DB, id_TYPE_LIST, id_NAME, id_HAVE_ENCODING;
|
5
|
+
static ID id_new, id_enc, id_size;
|
6
|
+
static ID sym_enc;
|
7
|
+
|
8
|
+
static void dump_name(VALUE name, LWES_BYTE_P buf, size_t *off)
|
9
|
+
{
|
10
|
+
char *s = RSTRING_PTR(name);
|
11
|
+
|
12
|
+
if (marshall_SHORT_STRING(s, buf, MAX_MSG_SIZE, off) > 0)
|
13
|
+
return;
|
14
|
+
rb_raise(rb_eRuntimeError, "failed to dump name=%s", s);
|
15
|
+
}
|
16
|
+
|
17
|
+
static int dump_bool(VALUE name, VALUE val, LWES_BYTE_P buf, size_t *off)
|
18
|
+
{
|
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
|
+
dump_name(name, buf, off);
|
31
|
+
lwesrb_dump_type(LWES_BOOLEAN_TOKEN, buf, off);
|
32
|
+
return marshall_BOOLEAN(tmp, buf, MAX_MSG_SIZE, off);
|
33
|
+
}
|
34
|
+
|
35
|
+
static int dump_string(VALUE name, VALUE val, LWES_BYTE_P buf, size_t *off)
|
36
|
+
{
|
37
|
+
volatile VALUE raise_inspect;
|
38
|
+
|
39
|
+
if (TYPE(val) != T_STRING)
|
40
|
+
rb_raise(rb_eTypeError, "not a string: %s",
|
41
|
+
RAISE_INSPECT(val));
|
42
|
+
dump_name(name, buf, off);
|
43
|
+
lwesrb_dump_type(LWES_STRING_TOKEN, buf, off);
|
44
|
+
return marshall_LONG_STRING(RSTRING_PTR(val), buf, MAX_MSG_SIZE, off);
|
45
|
+
}
|
46
|
+
|
47
|
+
static void dump_enc(VALUE enc, LWES_BYTE_P buf, size_t *off)
|
48
|
+
{
|
49
|
+
dump_name(ENC, buf, off);
|
50
|
+
lwesrb_dump_num(LWES_INT_16_TOKEN, enc, buf, off);
|
51
|
+
}
|
52
|
+
|
53
|
+
static char *my_strdup(const char *str)
|
54
|
+
{
|
55
|
+
long len = strlen(str) + 1;
|
56
|
+
char *rv = xmalloc(len);
|
57
|
+
|
58
|
+
memcpy(rv, str, len);
|
59
|
+
|
60
|
+
return rv;
|
61
|
+
}
|
6
62
|
|
7
63
|
/* the underlying struct for LWES::Emitter */
|
8
64
|
struct _rb_lwes_emitter {
|
9
65
|
struct lwes_emitter *emitter;
|
10
|
-
|
11
|
-
|
66
|
+
char *address;
|
67
|
+
char *iface;
|
12
68
|
LWES_U_INT_32 port;
|
13
69
|
LWES_BOOLEAN emit_heartbeat;
|
14
70
|
LWES_INT_16 freq;
|
@@ -32,28 +88,11 @@ static void rle_free(void *ptr)
|
|
32
88
|
|
33
89
|
if (rle->emitter)
|
34
90
|
lwes_emitter_destroy(rle->emitter);
|
91
|
+
xfree(rle->address);
|
92
|
+
xfree(rle->iface);
|
35
93
|
xfree(ptr);
|
36
94
|
}
|
37
95
|
|
38
|
-
static struct lwes_event *
|
39
|
-
lwesrb_event_create(struct lwes_event_type_db *db, VALUE name)
|
40
|
-
{
|
41
|
-
int gc_retry = 1;
|
42
|
-
const char *event_name = RSTRING_PTR(name);
|
43
|
-
struct lwes_event *event;
|
44
|
-
|
45
|
-
retry:
|
46
|
-
event = lwes_event_create(db, event_name);
|
47
|
-
if (!event) {
|
48
|
-
if (--gc_retry == 0) {
|
49
|
-
rb_gc();
|
50
|
-
goto retry;
|
51
|
-
}
|
52
|
-
rb_raise(rb_eRuntimeError, "failed to create lwes_event");
|
53
|
-
}
|
54
|
-
return event;
|
55
|
-
}
|
56
|
-
|
57
96
|
/* called by the GC when object is allocated */
|
58
97
|
static VALUE rle_alloc(VALUE klass)
|
59
98
|
{
|
@@ -73,202 +112,213 @@ static VALUE rle_alloc(VALUE klass)
|
|
73
112
|
*/
|
74
113
|
static VALUE event_hash_iter_i(VALUE kv, VALUE memo)
|
75
114
|
{
|
76
|
-
VALUE
|
115
|
+
volatile VALUE raise_inspect;
|
116
|
+
VALUE *tmp = (VALUE *)memo;
|
77
117
|
VALUE val;
|
78
|
-
|
79
|
-
LWES_CONST_SHORT_STRING name;
|
118
|
+
VALUE name;
|
80
119
|
int rv = 0;
|
81
|
-
|
120
|
+
LWES_BYTE_P buf = (LWES_BYTE_P)tmp[0];
|
121
|
+
size_t *off = (size_t *)tmp[1];
|
82
122
|
|
83
|
-
|
84
|
-
|
123
|
+
if (TYPE(kv) != T_ARRAY || RARRAY_LEN(kv) != 2)
|
124
|
+
rb_raise(rb_eTypeError,
|
125
|
+
"hash iteration not giving key-value pairs");
|
85
126
|
tmp = RARRAY_PTR(kv);
|
86
|
-
name =
|
127
|
+
name = tmp[0];
|
128
|
+
|
129
|
+
if (name == sym_enc) return Qnil; /* already dumped first */
|
130
|
+
|
131
|
+
name = rb_obj_as_string(name);
|
132
|
+
|
133
|
+
if (strcmp(RSTRING_PTR(name), LWES_ENCODING) == 0)
|
134
|
+
return Qnil;
|
135
|
+
|
87
136
|
val = tmp[1];
|
88
137
|
|
89
|
-
retry:
|
90
138
|
switch (TYPE(val)) {
|
91
139
|
case T_TRUE:
|
92
|
-
rv = lwes_event_set_BOOLEAN(event, name, TRUE);
|
93
|
-
break;
|
94
140
|
case T_FALSE:
|
95
|
-
rv =
|
141
|
+
rv = dump_bool(name, val, buf, off);
|
96
142
|
break;
|
97
143
|
case T_ARRAY:
|
98
|
-
|
99
|
-
|
144
|
+
dump_name(name, buf, off);
|
145
|
+
lwesrb_dump_num_ary(val, buf, off);
|
146
|
+
return Qnil;
|
100
147
|
case T_STRING:
|
101
|
-
rv =
|
148
|
+
rv = dump_string(name, val, buf, off);
|
102
149
|
break;
|
103
150
|
}
|
104
|
-
|
151
|
+
|
152
|
+
if (rv > 0)
|
105
153
|
return Qnil;
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
} else {
|
110
|
-
/* looking at the lwes source code, -3 is allocation errors */
|
111
|
-
if (rv == -3 && --gc_retry == 0) {
|
112
|
-
rb_gc();
|
113
|
-
goto retry;
|
114
|
-
}
|
115
|
-
rb_raise(rb_eRuntimeError, "failed to set %s=%s for event=%s",
|
116
|
-
name, RSTRING_PTR(rb_inspect(val)), event->eventName);
|
117
|
-
}
|
154
|
+
|
155
|
+
rb_raise(rb_eArgError, "unhandled type %s=%s",
|
156
|
+
RSTRING_PTR(name), RAISE_INSPECT(val));
|
118
157
|
return Qfalse;
|
119
158
|
}
|
120
159
|
|
121
|
-
static VALUE
|
160
|
+
static VALUE emit_hash(VALUE self, VALUE name, VALUE event)
|
122
161
|
{
|
123
|
-
|
124
|
-
|
125
|
-
VALUE
|
126
|
-
|
162
|
+
struct _rb_lwes_emitter *rle = _rle(self);
|
163
|
+
LWES_BYTE_P buf = rle->emitter->buffer;
|
164
|
+
VALUE tmp[2];
|
165
|
+
size_t off = 0;
|
166
|
+
VALUE enc;
|
167
|
+
int size = NUM2INT(rb_funcall(event, id_size, 0, 0));
|
168
|
+
int rv;
|
169
|
+
|
170
|
+
tmp[0] = (VALUE)buf;
|
171
|
+
tmp[1] = (VALUE)&off;
|
172
|
+
|
173
|
+
if (size < 0 || size > UINT16_MAX)
|
174
|
+
rb_raise(rb_eRangeError, "hash size out of uint16 range");
|
175
|
+
|
176
|
+
/* event name first */
|
177
|
+
dump_name(name, buf, &off);
|
178
|
+
|
179
|
+
/* number of attributes second */
|
180
|
+
rv = marshall_U_INT_16((LWES_U_INT_16)size, buf, MAX_MSG_SIZE, &off);
|
181
|
+
if (rv <= 0)
|
182
|
+
rb_raise(rb_eRuntimeError, "failed to dump num_attrs");
|
183
|
+
|
184
|
+
/* dump encoding before other fields */
|
185
|
+
enc = rb_hash_aref(event, sym_enc);
|
186
|
+
if (NIL_P(enc))
|
187
|
+
enc = rb_hash_aref(event, ENC);
|
188
|
+
if (! NIL_P(enc))
|
189
|
+
dump_enc(enc, buf, &off);
|
127
190
|
|
128
|
-
|
129
|
-
|
191
|
+
/* the rest of the fields */
|
192
|
+
rb_iterate(rb_each, event, event_hash_iter_i, (VALUE)&tmp);
|
193
|
+
|
194
|
+
if (lwes_emitter_emit_bytes(rle->emitter, buf, off) < 0)
|
130
195
|
rb_raise(rb_eRuntimeError, "failed to emit event");
|
131
196
|
|
132
|
-
return
|
197
|
+
return event;
|
133
198
|
}
|
134
199
|
|
135
200
|
static void
|
136
|
-
|
137
|
-
|
138
|
-
LWES_CONST_SHORT_STRING name,
|
201
|
+
marshal_field(
|
202
|
+
VALUE name,
|
139
203
|
LWES_TYPE type,
|
140
|
-
VALUE val
|
204
|
+
VALUE val,
|
205
|
+
LWES_BYTE_P buf,
|
206
|
+
size_t *off)
|
141
207
|
{
|
142
|
-
|
143
|
-
int rv;
|
208
|
+
volatile VALUE raise_inspect;
|
144
209
|
|
145
|
-
retry:
|
146
210
|
switch (type) {
|
147
|
-
case LWES_TYPE_BOOLEAN:
|
148
|
-
if (val == Qfalse)
|
149
|
-
rv = lwes_event_set_BOOLEAN(event, name, FALSE);
|
150
|
-
else if (val == Qtrue)
|
151
|
-
rv = lwes_event_set_BOOLEAN(event, name, TRUE);
|
152
|
-
else
|
153
|
-
rb_raise(rb_eTypeError, "non-boolean set for %s: %s",
|
154
|
-
name, RSTRING_PTR(rb_inspect(val)));
|
155
|
-
break;
|
156
211
|
case LWES_TYPE_STRING:
|
157
|
-
if (
|
158
|
-
|
159
|
-
|
160
|
-
|
212
|
+
if (dump_string(name, val, buf, off) > 0)
|
213
|
+
return;
|
214
|
+
break;
|
215
|
+
case LWES_TYPE_BOOLEAN:
|
216
|
+
if (dump_bool(name, val, buf, off) > 0)
|
217
|
+
return;
|
161
218
|
break;
|
162
219
|
default:
|
163
|
-
|
164
|
-
|
165
|
-
if (rv > 0) {
|
220
|
+
dump_name(name, buf, off);
|
221
|
+
lwesrb_dump_num(type, val, buf, off);
|
166
222
|
return;
|
167
|
-
} else {
|
168
|
-
if (rv == -3 && --gc_retry == 0) {
|
169
|
-
rb_gc();
|
170
|
-
goto retry;
|
171
|
-
}
|
172
|
-
rb_raise(rb_eRuntimeError,
|
173
|
-
"failed to set %s=%s for event=%s (error: %d)",
|
174
|
-
name, RSTRING_PTR(rb_inspect(val)),
|
175
|
-
event->eventName, rv);
|
176
223
|
}
|
177
224
|
|
178
|
-
|
225
|
+
rb_raise(rb_eRuntimeError, "failed to set %s=%s",
|
226
|
+
RSTRING_PTR(name), RAISE_INSPECT(val));
|
179
227
|
}
|
180
228
|
|
181
|
-
static
|
229
|
+
static void lwes_struct_class(
|
230
|
+
VALUE *event_class,
|
231
|
+
VALUE *name,
|
232
|
+
VALUE *type_list,
|
233
|
+
VALUE *have_enc,
|
234
|
+
VALUE event)
|
182
235
|
{
|
183
|
-
VALUE
|
184
|
-
VALUE
|
185
|
-
VALUE _event = argv[1];
|
186
|
-
struct lwes_event *event = (struct lwes_event *)argv[2];
|
187
|
-
VALUE type_list = argv[3];
|
188
|
-
long i;
|
189
|
-
VALUE *tmp;
|
190
|
-
|
191
|
-
if (TYPE(type_list) != T_ARRAY)
|
192
|
-
rb_raise(rb_eArgError, "could not get TYPE_LIST const");
|
236
|
+
VALUE type_db;
|
237
|
+
volatile VALUE raise_inspect;
|
193
238
|
|
194
|
-
|
195
|
-
|
196
|
-
/* inner: [ :field_sym, "field_name", type ] */
|
197
|
-
VALUE *inner = RARRAY_PTR(*tmp);
|
198
|
-
VALUE val = rb_struct_aref(_event, inner[0]);
|
199
|
-
LWES_CONST_SHORT_STRING name;
|
200
|
-
LWES_TYPE type;
|
239
|
+
*event_class = CLASS_OF(event);
|
240
|
+
type_db = rb_const_get(*event_class, id_TYPE_DB);
|
201
241
|
|
202
|
-
|
203
|
-
|
242
|
+
if (CLASS_OF(type_db) != cLWES_TypeDB)
|
243
|
+
rb_raise(rb_eArgError, "class does not have valid TYPE_DB");
|
204
244
|
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
245
|
+
*name = rb_const_get(*event_class, id_NAME);
|
246
|
+
if (TYPE(*name) != T_STRING)
|
247
|
+
rb_raise(rb_eArgError,
|
248
|
+
"could not get valid const NAME: %s",
|
249
|
+
RAISE_INSPECT(event));
|
209
250
|
|
210
|
-
|
211
|
-
|
251
|
+
*type_list = rb_const_get(*event_class, id_TYPE_LIST);
|
252
|
+
if (TYPE(*type_list) != T_ARRAY)
|
253
|
+
rb_raise(rb_eArgError,
|
254
|
+
"could not get valid const TYPE_LIST: %s",
|
255
|
+
RAISE_INSPECT(event));
|
212
256
|
|
213
|
-
|
257
|
+
*have_enc = rb_const_get(*event_class, id_HAVE_ENCODING);
|
214
258
|
}
|
215
259
|
|
216
|
-
static VALUE
|
260
|
+
static VALUE emit_struct(VALUE self, VALUE event)
|
217
261
|
{
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
262
|
+
VALUE event_class, name, type_list, have_enc;
|
263
|
+
struct _rb_lwes_emitter *rle = _rle(self);
|
264
|
+
LWES_BYTE_P buf = rle->emitter->buffer;
|
265
|
+
size_t off = 0;
|
266
|
+
long i;
|
267
|
+
VALUE *tmp;
|
268
|
+
LWES_U_INT_16 num_attr = 0;
|
269
|
+
size_t num_attr_off;
|
270
|
+
VALUE *flds;
|
225
271
|
|
226
|
-
|
227
|
-
{
|
228
|
-
VALUE tmp[3];
|
229
|
-
struct lwes_event *event = lwesrb_event_create(NULL, name);
|
272
|
+
lwes_struct_class(&event_class, &name, &type_list, &have_enc, event);
|
230
273
|
|
231
|
-
|
232
|
-
|
233
|
-
tmp[2] = (VALUE)event;
|
234
|
-
rb_ensure(_emit_hash, (VALUE)&tmp, _destroy_event, (VALUE)event);
|
274
|
+
/* event name */
|
275
|
+
dump_name(name, buf, &off);
|
235
276
|
|
236
|
-
|
237
|
-
|
277
|
+
/* number of attributes, use a placeholder until we've iterated */
|
278
|
+
num_attr_off = off;
|
279
|
+
if (marshall_U_INT_16(0, buf, MAX_MSG_SIZE, &off) < 0)
|
280
|
+
rb_raise(rb_eRuntimeError,
|
281
|
+
"failed to marshal number_of_attributes");
|
282
|
+
|
283
|
+
/* dump encoding before other fields */
|
284
|
+
if (have_enc == Qtrue) {
|
285
|
+
VALUE enc = rb_funcall(event, id_enc, 0, 0);
|
286
|
+
if (! NIL_P(enc)) {
|
287
|
+
++num_attr;
|
288
|
+
dump_enc(enc, buf, &off);
|
289
|
+
}
|
290
|
+
}
|
238
291
|
|
239
|
-
|
240
|
-
|
241
|
-
|
292
|
+
i = RARRAY_LEN(type_list);
|
293
|
+
flds = RSTRUCT_PTR(event);
|
294
|
+
tmp = RARRAY_PTR(type_list);
|
295
|
+
for (; --i >= 0; tmp++, flds++) {
|
296
|
+
/* inner: [ :field_sym, "field_name", type ] */
|
297
|
+
VALUE *inner = RARRAY_PTR(*tmp);
|
298
|
+
VALUE val, name;
|
299
|
+
LWES_TYPE type;
|
242
300
|
|
243
|
-
|
244
|
-
|
301
|
+
if (inner[0] == sym_enc) /* encoding was already dumped */
|
302
|
+
continue;
|
245
303
|
|
246
|
-
|
247
|
-
|
304
|
+
val = *flds;
|
305
|
+
if (NIL_P(val))
|
306
|
+
continue; /* LWES doesn't know nil */
|
248
307
|
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
struct lwes_event *event;
|
255
|
-
VALUE name = rb_const_get(event_class, id_NAME);
|
256
|
-
VALUE type_list = rb_const_get(event_class, id_TYPE_LIST);
|
257
|
-
|
258
|
-
if (TYPE(name) != T_STRING || TYPE(type_list) != T_ARRAY)
|
259
|
-
rb_raise(rb_eArgError,
|
260
|
-
"could not get class NAME or TYPE_LIST from: %s",
|
261
|
-
RSTRING_PTR(rb_inspect(_event)));
|
308
|
+
name = inner[1];
|
309
|
+
type = NUM2INT(inner[2]);
|
310
|
+
++num_attr;
|
311
|
+
marshal_field(name, type, val, buf, &off);
|
312
|
+
}
|
262
313
|
|
263
|
-
|
314
|
+
/* now we've iterated, we can accurately give num_attr */
|
315
|
+
if (marshall_U_INT_16(num_attr, buf, MAX_MSG_SIZE, &num_attr_off) <= 0)
|
316
|
+
rb_raise(rb_eRuntimeError, "failed to marshal num_attr");
|
264
317
|
|
265
|
-
|
266
|
-
|
267
|
-
argv[2] = (VALUE)event;
|
268
|
-
argv[3] = type_list;
|
269
|
-
rb_ensure(_emit_struct, (VALUE)&argv, _destroy_event, (VALUE)event);
|
318
|
+
if (lwes_emitter_emit_bytes(rle->emitter, buf, off) < 0)
|
319
|
+
rb_raise(rb_eRuntimeError, "failed to emit event");
|
270
320
|
|
271
|
-
return
|
321
|
+
return event;
|
272
322
|
}
|
273
323
|
|
274
324
|
/*
|
@@ -280,12 +330,12 @@ static VALUE emit_struct(VALUE self, VALUE _event)
|
|
280
330
|
*/
|
281
331
|
static VALUE emitter_ltlt(VALUE self, VALUE event)
|
282
332
|
{
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
333
|
+
volatile VALUE raise_inspect;
|
334
|
+
|
335
|
+
if (TYPE(event) == T_STRUCT)
|
336
|
+
return emit_struct(self, event);
|
287
337
|
|
288
|
-
|
338
|
+
rb_raise(rb_eArgError, "Must be a Struct: %s", RAISE_INSPECT(event));
|
289
339
|
}
|
290
340
|
|
291
341
|
/*
|
@@ -302,6 +352,7 @@ static VALUE emitter_ltlt(VALUE self, VALUE event)
|
|
302
352
|
*/
|
303
353
|
static VALUE emitter_emit(int argc, VALUE *argv, VALUE self)
|
304
354
|
{
|
355
|
+
volatile VALUE raise_inspect;
|
305
356
|
VALUE name = Qnil;
|
306
357
|
VALUE event = Qnil;
|
307
358
|
argc = rb_scan_args(argc, argv, "11", &name, &event);
|
@@ -335,7 +386,7 @@ static VALUE emitter_emit(int argc, VALUE *argv, VALUE self)
|
|
335
386
|
default:
|
336
387
|
rb_raise(rb_eArgError,
|
337
388
|
"bad argument: %s, must be a String, Struct or Class",
|
338
|
-
|
389
|
+
RAISE_INSPECT(name));
|
339
390
|
}
|
340
391
|
|
341
392
|
assert(0 && "should never get here");
|
@@ -388,6 +439,9 @@ static VALUE init_copy(VALUE dest, VALUE obj)
|
|
388
439
|
struct _rb_lwes_emitter *src = _rle(obj);
|
389
440
|
|
390
441
|
memcpy(dst, src, sizeof(*dst));
|
442
|
+
dst->address = my_strdup(src->address);
|
443
|
+
if (dst->iface)
|
444
|
+
dst->iface = my_strdup(src->iface);
|
391
445
|
lwesrb_emitter_create(dst);
|
392
446
|
|
393
447
|
assert(dst->emitter && dst->emitter != src->emitter &&
|
@@ -414,7 +468,7 @@ static VALUE _create(VALUE self, VALUE options)
|
|
414
468
|
address = rb_hash_aref(options, ID2SYM(rb_intern("address")));
|
415
469
|
if (TYPE(address) != T_STRING)
|
416
470
|
rb_raise(rb_eTypeError, ":address must be a string");
|
417
|
-
rle->address = RSTRING_PTR(address);
|
471
|
+
rle->address = my_strdup(RSTRING_PTR(address));
|
418
472
|
|
419
473
|
iface = rb_hash_aref(options, ID2SYM(rb_intern("iface")));
|
420
474
|
switch (TYPE(iface)) {
|
@@ -422,7 +476,7 @@ static VALUE _create(VALUE self, VALUE options)
|
|
422
476
|
rle->iface = NULL;
|
423
477
|
break;
|
424
478
|
case T_STRING:
|
425
|
-
rle->iface = RSTRING_PTR(iface);
|
479
|
+
rle->iface = my_strdup(RSTRING_PTR(iface));
|
426
480
|
break;
|
427
481
|
default:
|
428
482
|
rb_raise(rb_eTypeError, ":iface must be a String or nil");
|
@@ -463,7 +517,8 @@ static VALUE _create(VALUE self, VALUE options)
|
|
463
517
|
void lwesrb_init_emitter(void)
|
464
518
|
{
|
465
519
|
VALUE mLWES = rb_define_module("LWES");
|
466
|
-
cLWES_Emitter =
|
520
|
+
VALUE cLWES_Emitter =
|
521
|
+
rb_define_class_under(mLWES, "Emitter", rb_cObject);
|
467
522
|
|
468
523
|
rb_define_method(cLWES_Emitter, "<<", emitter_ltlt, 1);
|
469
524
|
rb_define_method(cLWES_Emitter, "emit", emitter_emit, -1);
|
@@ -474,5 +529,12 @@ void lwesrb_init_emitter(void)
|
|
474
529
|
LWESRB_MKID(TYPE_DB);
|
475
530
|
LWESRB_MKID(TYPE_LIST);
|
476
531
|
LWESRB_MKID(NAME);
|
477
|
-
|
532
|
+
LWESRB_MKID(HAVE_ENCODING);
|
533
|
+
LWESRB_MKID(new);
|
534
|
+
LWESRB_MKID(size);
|
535
|
+
id_enc = rb_intern(LWES_ENCODING);
|
536
|
+
sym_enc = ID2SYM(id_enc);
|
537
|
+
|
538
|
+
ENC = rb_obj_freeze(rb_str_new2(LWES_ENCODING));
|
539
|
+
rb_define_const(mLWES, "ENCODING", ENC);
|
478
540
|
}
|
data/ext/lwes/lwes.c
CHANGED
@@ -1,11 +1,9 @@
|
|
1
1
|
#include "lwes_ruby.h"
|
2
2
|
|
3
|
-
static VALUE mLWES;
|
4
|
-
|
5
3
|
/* initialize the extension, Ruby automatically picks this up */
|
6
4
|
void Init_lwes_ext(void)
|
7
5
|
{
|
8
|
-
mLWES = rb_define_module("LWES");
|
6
|
+
VALUE mLWES = rb_define_module("LWES");
|
9
7
|
|
10
8
|
#define LWES_TYPE_CONST(name) \
|
11
9
|
rb_define_const(mLWES, #name, INT2FIX(LWES_TYPE_##name))
|
data/ext/lwes/lwes_ruby.h
CHANGED
@@ -19,16 +19,11 @@ void lwesrb_init_emitter(void);
|
|
19
19
|
|
20
20
|
void lwesrb_init_numeric(void);
|
21
21
|
|
22
|
-
|
23
|
-
struct lwes_event *event,
|
24
|
-
LWES_CONST_SHORT_STRING name,
|
25
|
-
VALUE array);
|
22
|
+
void lwesrb_dump_type(LWES_BYTE type, LWES_BYTE_P buf, size_t *off);
|
26
23
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
LWES_TYPE type,
|
31
|
-
VALUE val);
|
24
|
+
void lwesrb_dump_num(LWES_BYTE type, VALUE val, LWES_BYTE_P buf, size_t *off);
|
25
|
+
|
26
|
+
void lwesrb_dump_num_ary(VALUE array, LWES_BYTE_P buf, size_t *off);
|
32
27
|
|
33
28
|
#ifndef RSTRING_PTR
|
34
29
|
# define RSTRING_PTR(s) (RSTRING(s)->ptr)
|
@@ -40,4 +35,11 @@ int lwesrb_event_set_num(
|
|
40
35
|
# define RARRAY_LEN(s) (RARRAY(s)->len)
|
41
36
|
#endif
|
42
37
|
|
38
|
+
#ifndef RSTRUCT_PTR
|
39
|
+
# define RSTRUCT_PTR(s) (RSTRUCT(s)->ptr)
|
40
|
+
# define RSTRUCT_LEN(s) (RSTRUCT(s)->len)
|
41
|
+
#endif
|
42
|
+
|
43
|
+
#define RAISE_INSPECT(v) RSTRING_PTR(raise_inspect = rb_inspect(v))
|
44
|
+
|
43
45
|
#endif /* LWES_RUBY_H */
|
data/ext/lwes/numeric.c
CHANGED
@@ -7,8 +7,14 @@ static ID
|
|
7
7
|
sym_int64, sym_uint64,
|
8
8
|
sym_ip_addr;
|
9
9
|
|
10
|
-
|
11
|
-
|
10
|
+
void lwesrb_dump_type(LWES_BYTE type, LWES_BYTE_P buf, size_t *off)
|
11
|
+
{
|
12
|
+
if (marshall_BYTE(type, buf, MAX_MSG_SIZE, off) > 0)
|
13
|
+
return;
|
14
|
+
rb_raise(rb_eRuntimeError, "failed to dump type=%02x", (unsigned)type);
|
15
|
+
}
|
16
|
+
|
17
|
+
static int dump_uint16(VALUE val, LWES_BYTE_P buf, size_t *off)
|
12
18
|
{
|
13
19
|
int32_t tmp = NUM2INT(val);
|
14
20
|
|
@@ -17,24 +23,24 @@ static int set_uint16(
|
|
17
23
|
if (tmp > UINT16_MAX)
|
18
24
|
rb_raise(rb_eRangeError, ":uint16 too large: %d", tmp);
|
19
25
|
|
20
|
-
|
26
|
+
lwesrb_dump_type(LWES_U_INT_16_TOKEN, buf, off);
|
27
|
+
return marshall_U_INT_16((LWES_U_INT_16)tmp, buf, MAX_MSG_SIZE, off);
|
21
28
|
}
|
22
29
|
|
23
|
-
static int
|
24
|
-
struct lwes_event *event, LWES_CONST_SHORT_STRING name, VALUE val)
|
30
|
+
static int dump_int16(VALUE val, LWES_BYTE_P buf, size_t *off)
|
25
31
|
{
|
26
|
-
|
32
|
+
int32_t tmp = NUM2INT(val);
|
27
33
|
|
28
34
|
if (tmp > INT16_MAX)
|
29
35
|
rb_raise(rb_eRangeError, ":int16 too large: %i", tmp);
|
30
36
|
if (tmp < INT16_MIN)
|
31
37
|
rb_raise(rb_eRangeError, ":int16 too small: %i", tmp);
|
32
38
|
|
33
|
-
|
39
|
+
lwesrb_dump_type(LWES_INT_16_TOKEN, buf, off);
|
40
|
+
return marshall_INT_16((LWES_INT_16)tmp, buf, MAX_MSG_SIZE, off);
|
34
41
|
}
|
35
42
|
|
36
|
-
static int
|
37
|
-
struct lwes_event *event, LWES_CONST_SHORT_STRING name, VALUE val)
|
43
|
+
static int dump_uint32(VALUE val, LWES_BYTE_P buf, size_t *off)
|
38
44
|
{
|
39
45
|
LONG_LONG tmp = NUM2LL(val);
|
40
46
|
|
@@ -43,11 +49,11 @@ static int set_uint32(
|
|
43
49
|
if (tmp > UINT32_MAX)
|
44
50
|
rb_raise(rb_eRangeError, ":uint32 too large: %lli", tmp);
|
45
51
|
|
46
|
-
|
52
|
+
lwesrb_dump_type(LWES_U_INT_32_TOKEN, buf, off);
|
53
|
+
return marshall_U_INT_32((LWES_U_INT_32)tmp, buf, MAX_MSG_SIZE, off);
|
47
54
|
}
|
48
55
|
|
49
|
-
static int
|
50
|
-
struct lwes_event *event, LWES_CONST_SHORT_STRING name, VALUE val)
|
56
|
+
static int dump_int32(VALUE val, LWES_BYTE_P buf, size_t *off)
|
51
57
|
{
|
52
58
|
LONG_LONG tmp = NUM2LL(val);
|
53
59
|
|
@@ -56,66 +62,63 @@ static int set_int32(
|
|
56
62
|
if (tmp < INT32_MIN)
|
57
63
|
rb_raise(rb_eRangeError, ":int32 too small: %lli", tmp);
|
58
64
|
|
59
|
-
|
65
|
+
lwesrb_dump_type(LWES_INT_32_TOKEN, buf, off);
|
66
|
+
return marshall_INT_32((LWES_INT_32)tmp, buf, MAX_MSG_SIZE, off);
|
60
67
|
}
|
61
68
|
|
62
|
-
static int
|
63
|
-
struct lwes_event *event, LWES_CONST_SHORT_STRING name, VALUE val)
|
69
|
+
static int dump_uint64(VALUE val, LWES_BYTE_P buf, size_t *off)
|
64
70
|
{
|
65
71
|
unsigned LONG_LONG tmp = NUM2ULL(val); /* can raise RangeError */
|
66
72
|
ID type = TYPE(val);
|
67
73
|
|
68
74
|
if ((type == T_FIXNUM && FIX2LONG(val) < 0) ||
|
69
|
-
(type == T_BIGNUM && RTEST(rb_funcall(val, '<', 1, INT2FIX(0)))))
|
75
|
+
(type == T_BIGNUM && RTEST(rb_funcall(val, '<', 1, INT2FIX(0))))) {
|
76
|
+
volatile VALUE raise_inspect;
|
77
|
+
|
70
78
|
rb_raise(rb_eRangeError, ":uint64 negative: %s",
|
71
|
-
|
79
|
+
RAISE_INSPECT(val));
|
80
|
+
}
|
72
81
|
|
73
|
-
|
82
|
+
lwesrb_dump_type(LWES_U_INT_64_TOKEN, buf, off);
|
83
|
+
return marshall_U_INT_64((LWES_U_INT_64)tmp, buf, MAX_MSG_SIZE, off);
|
74
84
|
}
|
75
85
|
|
76
|
-
static int
|
77
|
-
struct lwes_event *event, LWES_CONST_SHORT_STRING name, VALUE val)
|
86
|
+
static int dump_int64(VALUE val, LWES_BYTE_P buf, size_t *off)
|
78
87
|
{
|
79
88
|
LONG_LONG tmp = NUM2LL(val); /* can raise RangeError */
|
80
89
|
|
81
|
-
|
90
|
+
lwesrb_dump_type(LWES_INT_64_TOKEN, buf, off);
|
91
|
+
return marshall_INT_64((LWES_INT_64)tmp, buf, MAX_MSG_SIZE, off);
|
82
92
|
}
|
83
93
|
|
84
|
-
static int
|
85
|
-
struct lwes_event *event, LWES_CONST_SHORT_STRING name, VALUE val)
|
94
|
+
static int dump_ip_addr(VALUE val, LWES_BYTE_P buf, size_t *off)
|
86
95
|
{
|
96
|
+
LWES_IP_ADDR addr;
|
97
|
+
volatile VALUE raise_inspect;
|
98
|
+
|
87
99
|
switch (TYPE(val)) {
|
88
100
|
case T_STRING:
|
89
|
-
|
90
|
-
|
91
|
-
return lwes_event_set_IP_ADDR_w_string(event, name, addr);
|
92
|
-
}
|
101
|
+
addr.s_addr = inet_addr(RSTRING_PTR(val));
|
102
|
+
break;
|
93
103
|
case T_FIXNUM:
|
94
104
|
case T_BIGNUM:
|
95
|
-
|
96
|
-
|
97
|
-
int rv;
|
98
|
-
|
99
|
-
addr->s_addr = htonl(NUM2UINT(val));
|
100
|
-
rv = lwes_event_set_IP_ADDR(event, name, *addr);
|
101
|
-
|
102
|
-
if (rv < 0)
|
103
|
-
xfree(addr);
|
104
|
-
return rv;
|
105
|
-
}
|
105
|
+
addr.s_addr = htonl(NUM2UINT(val));
|
106
|
+
break;
|
106
107
|
default:
|
107
108
|
rb_raise(rb_eTypeError,
|
108
109
|
":ip_addr address must be String or Integer: %s",
|
109
|
-
|
110
|
+
RAISE_INSPECT(val));
|
110
111
|
}
|
112
|
+
lwesrb_dump_type(LWES_IP_ADDR_TOKEN, buf, off);
|
113
|
+
return marshall_IP_ADDR(addr, buf, MAX_MSG_SIZE, off);
|
111
114
|
}
|
112
115
|
|
113
116
|
/* simple type => function dispatch map */
|
114
117
|
static struct _type_fn_map {
|
115
118
|
ID type;
|
116
|
-
int (*fn)(
|
119
|
+
int (*fn)(VALUE, LWES_BYTE_P, size_t *);
|
117
120
|
} type_fn_map[] = {
|
118
|
-
#define SYMFN(T) { (ID)&sym_##T,
|
121
|
+
#define SYMFN(T) { (ID)&sym_##T, dump_##T }
|
119
122
|
SYMFN(uint16),
|
120
123
|
SYMFN(int16),
|
121
124
|
SYMFN(uint32),
|
@@ -126,39 +129,47 @@ static struct _type_fn_map {
|
|
126
129
|
#undef SYMFN
|
127
130
|
};
|
128
131
|
|
129
|
-
|
130
|
-
|
131
|
-
LWES_CONST_SHORT_STRING name,
|
132
|
+
/* used for Struct serialization where types are known ahead of time */
|
133
|
+
static int dump_num(
|
132
134
|
LWES_TYPE type,
|
133
|
-
VALUE val
|
135
|
+
VALUE val,
|
136
|
+
LWES_BYTE_P buf,
|
137
|
+
size_t *off)
|
134
138
|
{
|
135
139
|
switch (type) {
|
136
|
-
case LWES_TYPE_U_INT_16: return
|
137
|
-
case LWES_TYPE_INT_16: return
|
138
|
-
case LWES_TYPE_U_INT_32: return
|
139
|
-
case LWES_TYPE_INT_32: return
|
140
|
-
case LWES_TYPE_U_INT_64: return
|
141
|
-
case LWES_TYPE_INT_64: return
|
142
|
-
case LWES_TYPE_IP_ADDR: return
|
140
|
+
case LWES_TYPE_U_INT_16: return dump_uint16(val, buf, off);
|
141
|
+
case LWES_TYPE_INT_16: return dump_int16(val, buf, off);
|
142
|
+
case LWES_TYPE_U_INT_32: return dump_uint32(val, buf, off);
|
143
|
+
case LWES_TYPE_INT_32: return dump_int32(val, buf, off);
|
144
|
+
case LWES_TYPE_U_INT_64: return dump_uint64(val, buf, off);
|
145
|
+
case LWES_TYPE_INT_64: return dump_int64(val, buf, off);
|
146
|
+
case LWES_TYPE_IP_ADDR: return dump_ip_addr(val, buf, off);
|
143
147
|
default:
|
144
148
|
rb_raise(rb_eRuntimeError,
|
145
149
|
"unknown LWES attribute type: 0x%02x", type);
|
146
150
|
}
|
147
|
-
assert("you should never get here (
|
151
|
+
assert("you should never get here (dump_num)");
|
148
152
|
return -1;
|
149
153
|
}
|
150
154
|
|
155
|
+
void lwesrb_dump_num(LWES_BYTE type, VALUE val, LWES_BYTE_P buf, size_t *off)
|
156
|
+
{
|
157
|
+
if (dump_num(type, val, buf, off) > 0)
|
158
|
+
return;
|
159
|
+
rb_raise(rb_eRuntimeError,
|
160
|
+
"dumping numeric type 0x%02x, type failed", type);
|
161
|
+
}
|
162
|
+
|
151
163
|
/*
|
164
|
+
* used for Hash serialization
|
152
165
|
* array contains two elements:
|
153
166
|
* [ symbolic_type, number ]
|
154
167
|
* returns the return value of the underlying lwes_event_set_* call
|
155
168
|
*/
|
156
|
-
|
157
|
-
struct lwes_event *event,
|
158
|
-
LWES_CONST_SHORT_STRING name,
|
159
|
-
VALUE array)
|
169
|
+
void lwesrb_dump_num_ary(VALUE array, LWES_BYTE_P buf, size_t *off)
|
160
170
|
{
|
161
|
-
|
171
|
+
volatile VALUE raise_inspect;
|
172
|
+
int i, rv;
|
162
173
|
struct _type_fn_map *head;
|
163
174
|
VALUE *ary;
|
164
175
|
ID type;
|
@@ -173,15 +184,19 @@ int lwesrb_event_set_numeric(
|
|
173
184
|
|
174
185
|
i = sizeof(type_fn_map) / sizeof(type_fn_map[0]);
|
175
186
|
for (head = type_fn_map; --i >= 0; head++) {
|
176
|
-
if (head->type
|
177
|
-
|
178
|
-
}
|
187
|
+
if (head->type != type)
|
188
|
+
continue;
|
179
189
|
|
180
|
-
|
181
|
-
|
182
|
-
|
190
|
+
rv = head->fn(ary[1], buf, off);
|
191
|
+
if (rv > 0)
|
192
|
+
return;
|
183
193
|
|
184
|
-
|
194
|
+
rb_raise(rb_eRuntimeError,
|
195
|
+
"dumping numeric type %s, type failed",
|
196
|
+
RAISE_INSPECT(type));
|
197
|
+
}
|
198
|
+
|
199
|
+
rb_raise(rb_eArgError, "unknown type: %s", RAISE_INSPECT(type));
|
185
200
|
}
|
186
201
|
|
187
202
|
void lwesrb_init_numeric(void)
|
data/ext/lwes/type_db.c
CHANGED
@@ -103,11 +103,12 @@ struct lwes_event_type_db * lwesrb_get_type_db(VALUE self)
|
|
103
103
|
struct _tdb *tdb;
|
104
104
|
|
105
105
|
Data_Get_Struct(self, struct _tdb, tdb);
|
106
|
-
if (!tdb->db)
|
106
|
+
if (! tdb->db) {
|
107
|
+
volatile VALUE raise_inspect;
|
107
108
|
rb_raise(rb_eRuntimeError,
|
108
|
-
|
109
|
-
|
110
|
-
|
109
|
+
"couldn't get lwes_type_db from %s",
|
110
|
+
RAISE_INSPECT(self));
|
111
|
+
}
|
111
112
|
return tdb->db;
|
112
113
|
}
|
113
114
|
|
data/lib/lwes.rb
CHANGED
data/lib/lwes/struct.rb
CHANGED
@@ -95,9 +95,21 @@ module LWES
|
|
95
95
|
tmp.const_set :NAME, name.to_s
|
96
96
|
ed = tmp.const_set :EVENT_DEF, {}
|
97
97
|
event_def.each { |(field,type)| ed[field] = type }
|
98
|
-
|
98
|
+
|
99
|
+
# freeze since emitter.c can segfault if this ever changes
|
100
|
+
type_list = event_def.map do |(field,type)|
|
101
|
+
[ field, field.to_s.freeze, type ].freeze
|
102
|
+
end.freeze
|
99
103
|
tmp.const_set :TYPE_LIST, type_list
|
100
104
|
|
105
|
+
aref_map = tmp.const_set :AREF_MAP, {}
|
106
|
+
type_list.each_with_index do |(field_sym,field_str,_),idx|
|
107
|
+
aref_map[field_sym] = aref_map[field_str] = idx
|
108
|
+
end
|
109
|
+
|
110
|
+
tmp.const_set :HAVE_ENCODING,
|
111
|
+
type_list.include?([ :enc, 'enc', LWES::INT_16 ])
|
112
|
+
|
101
113
|
defaults = options[:defaults] || {}
|
102
114
|
defaults = tmp.const_set :DEFAULTS, defaults.dup
|
103
115
|
tmp.class_eval(&block) if block_given?
|
@@ -122,6 +134,38 @@ class ::#{tmp.name}
|
|
122
134
|
end
|
123
135
|
end
|
124
136
|
EOS
|
137
|
+
|
138
|
+
# avoid linear scans for large structs, not sure if 50 is a good enough
|
139
|
+
# threshold but it won't help for anything <= 10 since Ruby (or at least
|
140
|
+
# MRI) already optimizes those cases
|
141
|
+
if event_def.size > 50
|
142
|
+
eval <<EOS
|
143
|
+
class ::#{tmp.name}
|
144
|
+
alias __aref []
|
145
|
+
alias __aset []=
|
146
|
+
def [](key)
|
147
|
+
__aref(key.kind_of?(Fixnum) ? key : AREF_MAP[key])
|
148
|
+
end
|
149
|
+
|
150
|
+
def []=(key, value)
|
151
|
+
__aset(key.kind_of?(Fixnum) ? key : AREF_MAP[key], value)
|
152
|
+
end
|
153
|
+
end
|
154
|
+
EOS
|
155
|
+
fast_methods = []
|
156
|
+
event_def.each_with_index do |(fld,type), idx|
|
157
|
+
next if idx <= 9
|
158
|
+
if idx != aref_map[fld]
|
159
|
+
raise LoadError, "event_def corrupt: #{event_def}"
|
160
|
+
end
|
161
|
+
fast_methods << "undef_method :#{fld}, :#{fld}=\n"
|
162
|
+
fast_methods << "\ndef #{fld}; __aref #{idx}; end\n"
|
163
|
+
fast_methods << "\ndef #{fld}=(val); __aset #{idx}, val ; end\n"
|
164
|
+
end
|
165
|
+
|
166
|
+
eval("class ::#{tmp.name}; #{fast_methods.join("\n")}\n end")
|
167
|
+
end
|
168
|
+
|
125
169
|
tmp
|
126
170
|
end
|
127
171
|
end
|
data/lwes.gemspec
CHANGED
data/test/test_helper.rb
CHANGED
data/test/unit/test_emitter.rb
CHANGED
@@ -99,16 +99,6 @@ class TestEmitter < Test::Unit::TestCase
|
|
99
99
|
assert_equal 1, lines.grep(/int_ip = 192.168.1.1/).size
|
100
100
|
end
|
101
101
|
|
102
|
-
def TODO_emit_ip_addr_object
|
103
|
-
emitter = LWES::Emitter.new(@options)
|
104
|
-
event = { :ip => IPAddr.new("192.168.1.1") }
|
105
|
-
out = lwes_listener do
|
106
|
-
assert_nothing_raised { emitter.emit("IP", event) }
|
107
|
-
end
|
108
|
-
lines = out.readlines
|
109
|
-
assert_equal 1, lines.grep(/\bip = 192.168.1.1/).size
|
110
|
-
end
|
111
|
-
|
112
102
|
def test_emit_junk
|
113
103
|
emitter = LWES::Emitter.new(@options)
|
114
104
|
assert_raises(ArgumentError) { emitter.emit("JUNK", :junk => %r{junk}) }
|
@@ -180,6 +170,48 @@ class TestEmitter < Test::Unit::TestCase
|
|
180
170
|
}
|
181
171
|
end
|
182
172
|
|
173
|
+
def test_emit_enc_sym
|
174
|
+
emitter = LWES::Emitter.new(@options)
|
175
|
+
tmp = {
|
176
|
+
:enc => 1,
|
177
|
+
:a => "b",
|
178
|
+
:c => "d",
|
179
|
+
}
|
180
|
+
out = lwes_listener do
|
181
|
+
assert_nothing_raised { emitter.emit("EncTest", tmp) }
|
182
|
+
end
|
183
|
+
lines = out.readlines
|
184
|
+
assert_equal 1, lines.grep(/\A\tenc = 1;\n\z/).size
|
185
|
+
assert_equal 1, lines.grep(/\A\ta = b;\n\z/).size
|
186
|
+
assert_equal 1, lines.grep(/\A\tc = d;\n\z/).size
|
187
|
+
end
|
188
|
+
|
189
|
+
def test_emit_enc_str
|
190
|
+
emitter = LWES::Emitter.new(@options)
|
191
|
+
tmp = {
|
192
|
+
:enc => 1,
|
193
|
+
:a => "b",
|
194
|
+
:c => "d",
|
195
|
+
}
|
196
|
+
out = lwes_listener do
|
197
|
+
assert_nothing_raised { emitter.emit("EncTest", tmp) }
|
198
|
+
end
|
199
|
+
lines = out.readlines
|
200
|
+
assert_equal 1, lines.grep(/\A\tenc = 1;\n\z/).size
|
201
|
+
assert_equal 1, lines.grep(/\A\ta = b;\n\z/).size
|
202
|
+
assert_equal 1, lines.grep(/\A\tc = d;\n\z/).size
|
203
|
+
end
|
204
|
+
|
205
|
+
def test_emit_huge_event
|
206
|
+
emitter = LWES::Emitter.new(@options)
|
207
|
+
tmp = {
|
208
|
+
:a => ("b" * (1024 * 1024)),
|
209
|
+
}
|
210
|
+
assert_raises(ArgumentError) do
|
211
|
+
emitter.emit("BigTest", tmp)
|
212
|
+
end
|
213
|
+
end
|
214
|
+
|
183
215
|
def test_close
|
184
216
|
emitter = LWES::Emitter.new(@options)
|
185
217
|
assert_nil emitter.close
|
data/test/unit/test_struct.rb
CHANGED
@@ -57,6 +57,7 @@ class TestStruct < Test::Unit::TestCase
|
|
57
57
|
:class => :EVENT_BOOL,
|
58
58
|
:name => :EventBool)
|
59
59
|
assert_equal "EVENT_BOOL", b.name
|
60
|
+
assert_equal false, b.const_get(:HAVE_ENCODING)
|
60
61
|
|
61
62
|
e = assert_raises(RuntimeError) {
|
62
63
|
LWES::Struct.new(:file=>MULTI_EVENT_ESF)
|
@@ -84,6 +85,7 @@ class TestStruct < Test::Unit::TestCase
|
|
84
85
|
assert_equal "Event1", a.name
|
85
86
|
assert a.const_get(:TYPE_DB).instance_of?(LWES::TypeDB)
|
86
87
|
assert a.const_get(:EVENT_DEF).instance_of?(Hash)
|
88
|
+
assert a.const_get(:HAVE_ENCODING)
|
87
89
|
assert_equal EXPECT_DB, a.const_get(:EVENT_DEF)
|
88
90
|
assert_equal EXPECT_LIST, a.const_get(:TYPE_LIST)
|
89
91
|
y = a.new
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: lwes
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Erik S. Chang
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2010-04-
|
13
|
+
date: 2010-04-20 00:00:00 +00:00
|
14
14
|
default_executable:
|
15
15
|
dependencies: []
|
16
16
|
|