11 static int dump_uint16(VALUE val
, LWES_BYTE_P buf
, size_t *off
)
13 lwesrb_dump_type(LWES_U_INT_16_TOKEN
, buf
, off
);
14 return marshall_U_INT_16(lwesrb_uint16(val
), buf
, MAX_MSG_SIZE
, off
);
17 static int dump_int16(VALUE val
, LWES_BYTE_P buf
, size_t *off
)
19 lwesrb_dump_type(LWES_INT_16_TOKEN
, buf
, off
);
20 return marshall_INT_16(lwesrb_int16(val
), buf
, MAX_MSG_SIZE
, off
);
23 static int dump_uint32(VALUE val
, LWES_BYTE_P buf
, size_t *off
)
25 lwesrb_dump_type(LWES_U_INT_32_TOKEN
, buf
, off
);
26 return marshall_U_INT_32(lwesrb_uint32(val
), buf
, MAX_MSG_SIZE
, off
);
29 static int dump_int32(VALUE val
, LWES_BYTE_P buf
, size_t *off
)
31 lwesrb_dump_type(LWES_INT_32_TOKEN
, buf
, off
);
32 return marshall_INT_32(lwesrb_int32(val
), buf
, MAX_MSG_SIZE
, off
);
35 static int dump_uint64(VALUE val
, LWES_BYTE_P buf
, size_t *off
)
37 lwesrb_dump_type(LWES_U_INT_64_TOKEN
, buf
, off
);
38 return marshall_U_INT_64(lwesrb_uint64(val
), buf
, MAX_MSG_SIZE
, off
);
41 static int dump_int64(VALUE val
, LWES_BYTE_P buf
, size_t *off
)
43 lwesrb_dump_type(LWES_INT_64_TOKEN
, buf
, off
);
44 return marshall_INT_64(lwesrb_int64(val
), buf
, MAX_MSG_SIZE
, off
);
47 static int dump_ip_addr(VALUE val
, LWES_BYTE_P buf
, size_t *off
)
49 lwesrb_dump_type(LWES_IP_ADDR_TOKEN
, buf
, off
);
50 return marshall_IP_ADDR(lwesrb_ip_addr(val
), buf
, MAX_MSG_SIZE
, off
);
53 /* simple type => function dispatch map */
54 static struct _type_fn_map
{
56 int (*fn
)(VALUE
, LWES_BYTE_P
, size_t *);
58 #define SYMFN(T) { (ID)&sym_##T, dump_##T }
69 /* used for Struct serialization where types are known ahead of time */
76 if (type
!= LWES_TYPE_IP_ADDR
&& TYPE(val
) == T_STRING
)
77 val
= rb_funcall(val
, id_to_i
, 0, 0);
80 case LWES_TYPE_U_INT_16
: return dump_uint16(val
, buf
, off
);
81 case LWES_TYPE_INT_16
: return dump_int16(val
, buf
, off
);
82 case LWES_TYPE_U_INT_32
: return dump_uint32(val
, buf
, off
);
83 case LWES_TYPE_INT_32
: return dump_int32(val
, buf
, off
);
84 case LWES_TYPE_U_INT_64
: return dump_uint64(val
, buf
, off
);
85 case LWES_TYPE_INT_64
: return dump_int64(val
, buf
, off
);
86 case LWES_TYPE_IP_ADDR
: return dump_ip_addr(val
, buf
, off
);
88 rb_raise(rb_eRuntimeError
,
89 "unknown LWES attribute type: 0x%02x", type
);
91 assert("you should never get here (dump_num)");
95 void lwesrb_dump_num(LWES_BYTE type
, VALUE val
, LWES_BYTE_P buf
, size_t *off
)
97 if (dump_num(type
, val
, buf
, off
) > 0)
99 rb_raise(rb_eRuntimeError
,
100 "dumping numeric type 0x%02x, type failed", type
);
104 * used for Hash serialization
105 * array contains two elements:
106 * [ symbolic_type, number ]
107 * returns the return value of the underlying lwes_event_set_* call
109 void lwesrb_dump_num_ary(VALUE array
, LWES_BYTE_P buf
, size_t *off
)
111 volatile VALUE raise_inspect
;
113 struct _type_fn_map
*head
;
116 assert(TYPE(array
) == T_ARRAY
&& "need array here");
118 if (RARRAY_LEN(array
) != 2)
119 rb_raise(rb_eArgError
, "expected a two element array");
121 type
= rb_ary_entry(array
, 0);
123 i
= sizeof(type_fn_map
) / sizeof(type_fn_map
[0]);
124 for (head
= type_fn_map
; --i
>= 0; head
++) {
125 if (head
->type
!= type
)
128 rv
= head
->fn(rb_ary_entry(array
, 1), buf
, off
);
132 rb_raise(rb_eRuntimeError
,
133 "dumping numeric type %s, type failed",
134 RAISE_INSPECT(type
));
137 rb_raise(rb_eArgError
, "unknown type: %s", RAISE_INSPECT(type
));
140 void lwesrb_init_numeric(void)
145 LWESRB_MKSYM(uint16
);
147 LWESRB_MKSYM(uint32
);
149 LWESRB_MKSYM(uint64
);
150 LWESRB_MKSYM(ip_addr
);
151 id_to_i
= rb_intern("to_i");
154 * we needed to have constants for compilation, so we set the
155 * address of the IDs and then dereference + reassign them
156 * at initialization time:
158 i
= sizeof(type_fn_map
) / sizeof(type_fn_map
[0]);
160 type_fn_map
[i
].type
= *(ID
*)type_fn_map
[i
].type
;