lwes 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/COPYING +339 -0
- data/ChangeLog +2 -0
- data/README +100 -0
- data/Rakefile +11 -0
- data/examples/demo.rb +36 -0
- data/examples/my_events.esf +17 -0
- data/ext/lwes/emitter.c +366 -0
- data/ext/lwes/extconf.rb +55 -0
- data/ext/lwes/lwes.c +27 -0
- data/ext/lwes/lwes_ruby.h +40 -0
- data/ext/lwes/numeric.c +207 -0
- data/ext/lwes/type_db.c +147 -0
- data/lib/lwes.rb +6 -0
- data/lib/lwes/emitter.rb +19 -0
- data/lib/lwes/struct.rb +116 -0
- data/lib/lwes/type_db.rb +24 -0
- data/lwes.gemspec +43 -0
- data/test/test_helper.rb +45 -0
- data/test/unit/test1.esf +33 -0
- data/test/unit/test2.esf +14 -0
- data/test/unit/test_emit_struct.rb +101 -0
- data/test/unit/test_emitter.rb +169 -0
- data/test/unit/test_struct.rb +207 -0
- data/test/unit/test_type_db.rb +61 -0
- metadata +84 -0
data/ext/lwes/lwes.c
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
#include "lwes_ruby.h"
|
2
|
+
|
3
|
+
static VALUE mLWES;
|
4
|
+
|
5
|
+
/* initialize the extension, Ruby automatically picks this up */
|
6
|
+
void Init_lwes_ext(void)
|
7
|
+
{
|
8
|
+
mLWES = rb_define_module("LWES");
|
9
|
+
|
10
|
+
#define LWES_TYPE_CONST(name) \
|
11
|
+
rb_define_const(mLWES, #name, INT2FIX(LWES_TYPE_##name))
|
12
|
+
LWES_TYPE_CONST(U_INT_16);
|
13
|
+
LWES_TYPE_CONST(INT_16);
|
14
|
+
LWES_TYPE_CONST(U_INT_32);
|
15
|
+
LWES_TYPE_CONST(INT_32);
|
16
|
+
LWES_TYPE_CONST(U_INT_64);
|
17
|
+
LWES_TYPE_CONST(INT_64);
|
18
|
+
LWES_TYPE_CONST(BOOLEAN);
|
19
|
+
LWES_TYPE_CONST(IP_ADDR);
|
20
|
+
LWES_TYPE_CONST(STRING);
|
21
|
+
LWES_TYPE_CONST(UNDEFINED);
|
22
|
+
#undef LWES_TYPE_CONST
|
23
|
+
|
24
|
+
lwesrb_init_numeric();
|
25
|
+
lwesrb_init_emitter();
|
26
|
+
lwesrb_init_type_db();
|
27
|
+
}
|
@@ -0,0 +1,40 @@
|
|
1
|
+
#ifndef LWES_RUBY_H
|
2
|
+
#define LWES_RUBY_H
|
3
|
+
|
4
|
+
#include <lwes.h>
|
5
|
+
#include <ruby.h>
|
6
|
+
#include <assert.h>
|
7
|
+
#include <stdint.h>
|
8
|
+
|
9
|
+
#define LWESRB_MKSYM(SYM) sym_##SYM = ID2SYM(rb_intern(#SYM))
|
10
|
+
|
11
|
+
struct lwes_event_type_db * lwesrb_get_type_db(VALUE self);
|
12
|
+
|
13
|
+
void lwesrb_init_type_db(void);
|
14
|
+
|
15
|
+
void lwesrb_init_emitter(void);
|
16
|
+
|
17
|
+
void lwesrb_init_numeric(void);
|
18
|
+
|
19
|
+
int lwesrb_event_set_numeric(
|
20
|
+
struct lwes_event *event,
|
21
|
+
LWES_CONST_SHORT_STRING name,
|
22
|
+
VALUE array);
|
23
|
+
|
24
|
+
int lwesrb_event_set_num(
|
25
|
+
struct lwes_event *event,
|
26
|
+
LWES_CONST_SHORT_STRING name,
|
27
|
+
LWES_TYPE type,
|
28
|
+
VALUE val);
|
29
|
+
|
30
|
+
#ifndef RSTRING_PTR
|
31
|
+
# define RSTRING_PTR(s) (RSTRING(s)->ptr)
|
32
|
+
# define RSTRING_LEN(s) (RSTRING(s)->len)
|
33
|
+
#endif
|
34
|
+
|
35
|
+
#ifndef RARRAY_PTR
|
36
|
+
# define RARRAY_PTR(s) (RARRAY(s)->ptr)
|
37
|
+
# define RARRAY_LEN(s) (RARRAY(s)->len)
|
38
|
+
#endif
|
39
|
+
|
40
|
+
#endif /* LWES_RUBY_H */
|
data/ext/lwes/numeric.c
ADDED
@@ -0,0 +1,207 @@
|
|
1
|
+
#include "lwes_ruby.h"
|
2
|
+
#include <arpa/inet.h>
|
3
|
+
|
4
|
+
static ID
|
5
|
+
sym_int16, sym_uint16,
|
6
|
+
sym_int32, sym_uint32,
|
7
|
+
sym_int64, sym_uint64,
|
8
|
+
sym_ip_addr;
|
9
|
+
|
10
|
+
static int set_uint16(
|
11
|
+
struct lwes_event *event, LWES_CONST_SHORT_STRING name, VALUE val)
|
12
|
+
{
|
13
|
+
int32_t tmp = NUM2INT(val);
|
14
|
+
|
15
|
+
if (tmp < 0)
|
16
|
+
rb_raise(rb_eRangeError, ":uint16 negative: %d", tmp);
|
17
|
+
if (tmp > UINT16_MAX)
|
18
|
+
rb_raise(rb_eRangeError, ":uint16 too large: %d", tmp);
|
19
|
+
|
20
|
+
return lwes_event_set_U_INT_16(event, name, (LWES_U_INT_16)tmp);
|
21
|
+
}
|
22
|
+
|
23
|
+
static int set_int16(
|
24
|
+
struct lwes_event *event, LWES_CONST_SHORT_STRING name, VALUE val)
|
25
|
+
{
|
26
|
+
int tmp = NUM2INT(val);
|
27
|
+
|
28
|
+
if (tmp > INT16_MAX)
|
29
|
+
rb_raise(rb_eRangeError, ":int16 too large: %i", tmp);
|
30
|
+
if (tmp < INT16_MIN)
|
31
|
+
rb_raise(rb_eRangeError, ":int16 too small: %i", tmp);
|
32
|
+
|
33
|
+
return lwes_event_set_INT_16(event, name, (LWES_INT_16)tmp);
|
34
|
+
}
|
35
|
+
|
36
|
+
static int set_uint32(
|
37
|
+
struct lwes_event *event, LWES_CONST_SHORT_STRING name, VALUE val)
|
38
|
+
{
|
39
|
+
LONG_LONG tmp = NUM2LL(val);
|
40
|
+
|
41
|
+
if (tmp < 0)
|
42
|
+
rb_raise(rb_eRangeError, ":uint32 negative: %lli", tmp);
|
43
|
+
if (tmp > UINT32_MAX)
|
44
|
+
rb_raise(rb_eRangeError, ":uint32 too large: %lli", tmp);
|
45
|
+
|
46
|
+
return lwes_event_set_U_INT_32(event, name, (LWES_U_INT_32)tmp);
|
47
|
+
}
|
48
|
+
|
49
|
+
static int set_int32(
|
50
|
+
struct lwes_event *event, LWES_CONST_SHORT_STRING name, VALUE val)
|
51
|
+
{
|
52
|
+
LONG_LONG tmp = NUM2LL(val);
|
53
|
+
|
54
|
+
if (tmp > INT32_MAX)
|
55
|
+
rb_raise(rb_eRangeError, ":int32 too large: %lli", tmp);
|
56
|
+
if (tmp < INT32_MIN)
|
57
|
+
rb_raise(rb_eRangeError, ":int32 too small: %lli", tmp);
|
58
|
+
|
59
|
+
return lwes_event_set_INT_32(event, name, (LWES_INT_32)tmp);
|
60
|
+
}
|
61
|
+
|
62
|
+
static int set_uint64(
|
63
|
+
struct lwes_event *event, LWES_CONST_SHORT_STRING name, VALUE val)
|
64
|
+
{
|
65
|
+
unsigned LONG_LONG tmp = NUM2ULL(val); /* can raise RangeError */
|
66
|
+
ID type = TYPE(val);
|
67
|
+
|
68
|
+
if ((type == T_FIXNUM && FIX2LONG(val) < 0) ||
|
69
|
+
(type == T_BIGNUM && RTEST(rb_funcall(val, '<', 1, INT2FIX(0)))))
|
70
|
+
rb_raise(rb_eRangeError, ":uint64 negative: %s",
|
71
|
+
RSTRING_PTR(rb_inspect(val)));
|
72
|
+
|
73
|
+
return lwes_event_set_U_INT_64(event, name, (LWES_U_INT_64)tmp);
|
74
|
+
}
|
75
|
+
|
76
|
+
static int set_int64(
|
77
|
+
struct lwes_event *event, LWES_CONST_SHORT_STRING name, VALUE val)
|
78
|
+
{
|
79
|
+
LONG_LONG tmp = NUM2LL(val); /* can raise RangeError */
|
80
|
+
|
81
|
+
return lwes_event_set_INT_64(event, name, (LWES_INT_64)tmp);
|
82
|
+
}
|
83
|
+
|
84
|
+
static int set_ip_addr(
|
85
|
+
struct lwes_event *event, LWES_CONST_SHORT_STRING name, VALUE val)
|
86
|
+
{
|
87
|
+
switch (TYPE(val)) {
|
88
|
+
case T_STRING:
|
89
|
+
{
|
90
|
+
LWES_CONST_SHORT_STRING addr = RSTRING_PTR(val);
|
91
|
+
return lwes_event_set_IP_ADDR_w_string(event, name, addr);
|
92
|
+
}
|
93
|
+
case T_FIXNUM:
|
94
|
+
case T_BIGNUM:
|
95
|
+
{
|
96
|
+
LWES_IP_ADDR *addr = ALLOC(LWES_IP_ADDR); /* never fails */
|
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
|
+
}
|
106
|
+
default:
|
107
|
+
rb_raise(rb_eTypeError,
|
108
|
+
":ip_addr address must be String or Integer: %s",
|
109
|
+
RSTRING_PTR(rb_inspect(val)));
|
110
|
+
}
|
111
|
+
}
|
112
|
+
|
113
|
+
/* simple type => function dispatch map */
|
114
|
+
static struct _type_fn_map {
|
115
|
+
ID type;
|
116
|
+
int (*fn)(struct lwes_event *, LWES_CONST_SHORT_STRING, VALUE);
|
117
|
+
} type_fn_map[] = {
|
118
|
+
#define SYMFN(T) { (ID)&sym_##T, set_##T }
|
119
|
+
SYMFN(uint16),
|
120
|
+
SYMFN(int16),
|
121
|
+
SYMFN(uint32),
|
122
|
+
SYMFN(int32),
|
123
|
+
SYMFN(uint64),
|
124
|
+
SYMFN(int64),
|
125
|
+
SYMFN(ip_addr),
|
126
|
+
#undef SYMFN
|
127
|
+
};
|
128
|
+
|
129
|
+
int lwesrb_event_set_num(
|
130
|
+
struct lwes_event *event,
|
131
|
+
LWES_CONST_SHORT_STRING name,
|
132
|
+
LWES_TYPE type,
|
133
|
+
VALUE val)
|
134
|
+
{
|
135
|
+
switch (type) {
|
136
|
+
case LWES_TYPE_U_INT_16: return set_uint16(event, name, val);
|
137
|
+
case LWES_TYPE_INT_16: return set_int16(event, name, val);
|
138
|
+
case LWES_TYPE_U_INT_32: return set_uint32(event, name, val);
|
139
|
+
case LWES_TYPE_INT_32: return set_int32(event, name, val);
|
140
|
+
case LWES_TYPE_U_INT_64: return set_uint64(event, name, val);
|
141
|
+
case LWES_TYPE_INT_64: return set_int64(event, name, val);
|
142
|
+
case LWES_TYPE_IP_ADDR: return set_ip_addr(event, name, val);
|
143
|
+
default:
|
144
|
+
rb_raise(rb_eRuntimeError,
|
145
|
+
"unknown LWES attribute type: 0x%02x", type);
|
146
|
+
}
|
147
|
+
assert("you should never get here (set_field)");
|
148
|
+
return -1;
|
149
|
+
}
|
150
|
+
|
151
|
+
/*
|
152
|
+
* array contains two elements:
|
153
|
+
* [ symbolic_type, number ]
|
154
|
+
* returns the return value of the underlying lwes_event_set_* call
|
155
|
+
*/
|
156
|
+
int lwesrb_event_set_numeric(
|
157
|
+
struct lwes_event *event,
|
158
|
+
LWES_CONST_SHORT_STRING name,
|
159
|
+
VALUE array)
|
160
|
+
{
|
161
|
+
int i;
|
162
|
+
struct _type_fn_map *head;
|
163
|
+
VALUE *ary;
|
164
|
+
ID type;
|
165
|
+
|
166
|
+
assert(TYPE(array) == T_ARRAY && "need array here");
|
167
|
+
|
168
|
+
if (RARRAY_LEN(array) != 2)
|
169
|
+
rb_raise(rb_eArgError, "expected a two element array");
|
170
|
+
|
171
|
+
ary = RARRAY_PTR(array);
|
172
|
+
type = ary[0];
|
173
|
+
|
174
|
+
i = sizeof(type_fn_map) / sizeof(type_fn_map[0]);
|
175
|
+
for (head = type_fn_map; --i >= 0; head++) {
|
176
|
+
if (head->type == type)
|
177
|
+
return head->fn(event, name, ary[1]);
|
178
|
+
}
|
179
|
+
|
180
|
+
rb_raise(rb_eArgError,
|
181
|
+
"unknown type: %s",
|
182
|
+
RSTRING_PTR(rb_inspect(type)));
|
183
|
+
|
184
|
+
return -1;
|
185
|
+
}
|
186
|
+
|
187
|
+
void lwesrb_init_numeric(void)
|
188
|
+
{
|
189
|
+
int i;
|
190
|
+
|
191
|
+
LWESRB_MKSYM(int16);
|
192
|
+
LWESRB_MKSYM(uint16);
|
193
|
+
LWESRB_MKSYM(int32);
|
194
|
+
LWESRB_MKSYM(uint32);
|
195
|
+
LWESRB_MKSYM(int64);
|
196
|
+
LWESRB_MKSYM(uint64);
|
197
|
+
LWESRB_MKSYM(ip_addr);
|
198
|
+
|
199
|
+
/*
|
200
|
+
* we needed to have constants for compilation, so we set the
|
201
|
+
* address of the IDs and then dereference + reassign them
|
202
|
+
* at initialization time:
|
203
|
+
*/
|
204
|
+
i = sizeof(type_fn_map) / sizeof(type_fn_map[0]);
|
205
|
+
while (--i >= 0)
|
206
|
+
type_fn_map[i].type = *(ID *)type_fn_map[i].type;
|
207
|
+
}
|
data/ext/lwes/type_db.c
ADDED
@@ -0,0 +1,147 @@
|
|
1
|
+
#include "lwes_ruby.h"
|
2
|
+
|
3
|
+
static VALUE cLWES_TypeDB;
|
4
|
+
|
5
|
+
struct _tdb {
|
6
|
+
struct lwes_event_type_db *db;
|
7
|
+
};
|
8
|
+
|
9
|
+
static void tdb_free(void *ptr)
|
10
|
+
{
|
11
|
+
struct _tdb *tdb = ptr;
|
12
|
+
|
13
|
+
if (tdb->db)
|
14
|
+
lwes_event_type_db_destroy(tdb->db);
|
15
|
+
tdb->db = NULL;
|
16
|
+
}
|
17
|
+
|
18
|
+
static VALUE tdb_alloc(VALUE klass)
|
19
|
+
{
|
20
|
+
struct _tdb *tdb;
|
21
|
+
|
22
|
+
return Data_Make_Struct(klass, struct _tdb, NULL, tdb_free, tdb);
|
23
|
+
}
|
24
|
+
|
25
|
+
static VALUE tdb_init(VALUE self, VALUE path)
|
26
|
+
{
|
27
|
+
struct _tdb *tdb;
|
28
|
+
|
29
|
+
Data_Get_Struct(self, struct _tdb, tdb);
|
30
|
+
if (tdb->db)
|
31
|
+
rb_raise(rb_eRuntimeError, "ESF already initialized");
|
32
|
+
|
33
|
+
tdb->db = lwes_event_type_db_create(RSTRING_PTR(path));
|
34
|
+
if (!tdb->db)
|
35
|
+
rb_raise(rb_eRuntimeError,
|
36
|
+
"failed to create type DB for LWES file %s",
|
37
|
+
RSTRING_PTR(path));
|
38
|
+
|
39
|
+
return Qnil;
|
40
|
+
}
|
41
|
+
|
42
|
+
static VALUE attr_sym(struct lwes_event_attribute *attr)
|
43
|
+
{
|
44
|
+
switch (attr->type) {
|
45
|
+
case LWES_TYPE_U_INT_16:
|
46
|
+
case LWES_TYPE_INT_16:
|
47
|
+
case LWES_TYPE_U_INT_32:
|
48
|
+
case LWES_TYPE_INT_32:
|
49
|
+
case LWES_TYPE_U_INT_64:
|
50
|
+
case LWES_TYPE_INT_64:
|
51
|
+
case LWES_TYPE_BOOLEAN:
|
52
|
+
case LWES_TYPE_IP_ADDR:
|
53
|
+
case LWES_TYPE_STRING:
|
54
|
+
return INT2NUM(attr->type);
|
55
|
+
case LWES_TYPE_UNDEFINED:
|
56
|
+
default:
|
57
|
+
rb_raise(rb_eRuntimeError,
|
58
|
+
"unknown LWES attribute type: 0x%02x", attr->type);
|
59
|
+
}
|
60
|
+
|
61
|
+
return Qfalse;
|
62
|
+
}
|
63
|
+
|
64
|
+
static VALUE event_def_ary(struct lwes_hash *hash)
|
65
|
+
{
|
66
|
+
struct lwes_hash_enumeration e;
|
67
|
+
VALUE rv = rb_ary_new();
|
68
|
+
|
69
|
+
if (!lwes_hash_keys(hash, &e))
|
70
|
+
rb_raise(rb_eRuntimeError, "couldn't get event attributes");
|
71
|
+
while (lwes_hash_enumeration_has_more_elements(&e)) {
|
72
|
+
LWES_SHORT_STRING key = lwes_hash_enumeration_next_element(&e);
|
73
|
+
struct lwes_event_attribute *attr;
|
74
|
+
VALUE pair;
|
75
|
+
|
76
|
+
if (!key)
|
77
|
+
rb_raise(rb_eRuntimeError,
|
78
|
+
"LWES event type iteration key fail");
|
79
|
+
|
80
|
+
attr = (struct lwes_event_attribute *)lwes_hash_get(hash, key);
|
81
|
+
if (!attr)
|
82
|
+
rb_raise(rb_eRuntimeError,
|
83
|
+
"LWES event type iteration value fail");
|
84
|
+
|
85
|
+
pair = rb_ary_new3(2, ID2SYM(rb_intern(key)), attr_sym(attr));
|
86
|
+
rb_ary_push(rv, pair);
|
87
|
+
}
|
88
|
+
|
89
|
+
return rv;
|
90
|
+
}
|
91
|
+
|
92
|
+
struct lwes_event_type_db * lwesrb_get_type_db(VALUE self)
|
93
|
+
{
|
94
|
+
struct _tdb *tdb;
|
95
|
+
|
96
|
+
Data_Get_Struct(self, struct _tdb, tdb);
|
97
|
+
if (!tdb->db)
|
98
|
+
rb_raise(rb_eRuntimeError,
|
99
|
+
"couldn't get lwes_type_db from %s",
|
100
|
+
RSTRING_PTR(rb_inspect(self)));
|
101
|
+
|
102
|
+
return tdb->db;
|
103
|
+
}
|
104
|
+
|
105
|
+
static VALUE tdb_to_hash(VALUE self)
|
106
|
+
{
|
107
|
+
struct _tdb *tdb;
|
108
|
+
VALUE rv = rb_hash_new();
|
109
|
+
struct lwes_hash *events;
|
110
|
+
struct lwes_hash_enumeration e;
|
111
|
+
|
112
|
+
Data_Get_Struct(self, struct _tdb, tdb);
|
113
|
+
assert(tdb->db && tdb->db->events && "tdb not initialized");
|
114
|
+
events = tdb->db->events;
|
115
|
+
|
116
|
+
if (!lwes_hash_keys(events, &e))
|
117
|
+
rb_raise(rb_eRuntimeError, "couldn't get type_db events");
|
118
|
+
|
119
|
+
while (lwes_hash_enumeration_has_more_elements(&e)) {
|
120
|
+
struct lwes_hash *hash;
|
121
|
+
ID event_key;
|
122
|
+
LWES_SHORT_STRING key = lwes_hash_enumeration_next_element(&e);
|
123
|
+
|
124
|
+
if (!key)
|
125
|
+
rb_raise(rb_eRuntimeError,
|
126
|
+
"LWES type DB rv iteration key fail");
|
127
|
+
|
128
|
+
hash = (struct lwes_hash*)lwes_hash_get(events, key);
|
129
|
+
if (!hash)
|
130
|
+
rb_raise(rb_eRuntimeError,
|
131
|
+
"LWES type DB rv iteration value fail");
|
132
|
+
|
133
|
+
event_key = ID2SYM(rb_intern(key));
|
134
|
+
rb_hash_aset(rv, event_key, event_def_ary(hash));
|
135
|
+
}
|
136
|
+
|
137
|
+
return rv;
|
138
|
+
}
|
139
|
+
|
140
|
+
void lwesrb_init_type_db(void)
|
141
|
+
{
|
142
|
+
VALUE mLWES = rb_define_module("LWES");
|
143
|
+
cLWES_TypeDB = rb_define_class_under(mLWES, "TypeDB", rb_cObject);
|
144
|
+
rb_define_method(cLWES_TypeDB, "initialize", tdb_init, 1);
|
145
|
+
rb_define_method(cLWES_TypeDB, "to_hash", tdb_to_hash, 0);
|
146
|
+
rb_define_alloc_func(cLWES_TypeDB, tdb_alloc);
|
147
|
+
}
|
data/lib/lwes.rb
ADDED
data/lib/lwes/emitter.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
module LWES
|
2
|
+
class Emitter
|
3
|
+
|
4
|
+
# creates a new Emitter object which may be used for the lifetime
|
5
|
+
# of the process:
|
6
|
+
#
|
7
|
+
# LWES::Emitter.new(:address => '224.1.1.11',
|
8
|
+
# :iface => '0.0.0.0',
|
9
|
+
# :port => 12345,
|
10
|
+
# :heartbeat => false, # Integer for frequency
|
11
|
+
# :ttl => 60, # nil for no ttl)
|
12
|
+
#
|
13
|
+
def initialize(options = {}, &block)
|
14
|
+
options[:iface] ||= '0.0.0.0'
|
15
|
+
_create(options)
|
16
|
+
block_given?
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|