lwes 0.3.1 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
|