Last active
August 29, 2015 14:27
-
-
Save Asmod4n/7e0a0936e3553ad38f88 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// zproto_codec_mruby.gsl | |
// Generates a codec for a protocol specification. | |
.gsl from "zproto_codec_c.gsl" | |
.output "$(class.source_dir)/mrb_$(class.name)_body.h" | |
/* ========================================================================= | |
$(class.name) - $(class.title:) | |
Codec class for $(class.name). | |
** WARNING ************************************************************* | |
THIS SOURCE FILE IS 100% GENERATED. If you edit this file, you will lose | |
your changes at the next build cycle. This is great for temporary printf | |
statements. DO NOT MAKE ANY CHANGES YOU WISH TO KEEP. The correct places | |
for commits are: | |
* The XML model used for this code generation: $(filename), or | |
* The code generation script that built this file: $(script) | |
************************************************************************ | |
. for class.license | |
$(string.trim (license.):block ) | |
. endfor | |
========================================================================= | |
*/ | |
/* | |
@header | |
$(class.name) - $(class.title:) | |
@discuss | |
@end | |
*/ | |
#include "$(class.package_dir)/$(class.name).h" | |
#include <errno.h> | |
#include <mruby.h> | |
#include <mruby/array.h> | |
#include <mruby/class.h> | |
#include <mruby/data.h> | |
#include <mruby/error.h> | |
#include <mruby/hash.h> | |
#include <mruby/string.h> | |
#include <mruby/throw.h> | |
static void | |
mrb_$(class.name)_destroy (mrb_state *mrb, void *p) | |
{ | |
$(class.name)_destroy (($(class.name)_t **) &p); | |
} | |
static const struct mrb_data_type mrb_$(class.name)_type = { | |
"i_$(class.name)_type", mrb_$(class.name)_destroy | |
}; | |
// -------------------------------------------------------------------------- | |
// Create a new $(class.name) | |
static mrb_value | |
mrb_$(class.name)_initialize (mrb_state *mrb, mrb_value mrb_self) | |
{ | |
errno = 0; | |
$(class.name)_t *self = $(class.name)_new (); | |
if (self == NULL) { | |
mrb_sys_fail (mrb, "$(class.name)_new"); | |
} | |
mrb_data_init (mrb_self, self, &mrb_$(class.name)_type); | |
return mrb_self; | |
} | |
// -------------------------------------------------------------------------- | |
// Receive a $(class.name) from the socket. Returns self if OK, else raises an exception. | |
// Blocks if there is no message waiting. | |
static mrb_value | |
mrb_$(class.name)_recv (mrb_state *mrb, mrb_value mrb_self) | |
{ | |
errno = 0; | |
mrb_value input_obj; | |
mrb_get_args (mrb, "o", &input_obj); | |
if (mrb_type (input_obj) != MRB_TT_DATA) | |
mrb_raise(mrb, E_ARGUMENT_ERROR, "input is not a data type"); | |
.if class.virtual ?= 1 | |
mrb_assert (zmsg_is (DATA_PTR (input_obj))); | |
zmsg_t *input = (zmsg_t *) DATA_PTR (input_obj); | |
.else | |
mrb_assert (zsock_is (DATA_PTR (input_obj))); | |
zsock_t *input = (zsock_t *) DATA_PTR (input_obj); | |
.endif | |
$(class.name)_t *self = ($(class.name)_t *) DATA_PTR (mrb_self); | |
if ($(class.name)_recv (self, input) == -1) { | |
mrb_sys_fail (mrb, "$(class.name)_recv"); | |
} | |
return mrb_self; | |
} | |
// -------------------------------------------------------------------------- | |
// Send the $(class.name) to the socket. Does not destroy it. Returns self if | |
// OK, else raises an exception. | |
static mrb_value | |
mrb_$(class.name)_send (mrb_state *mrb, mrb_value mrb_self) | |
{ | |
errno = 0; | |
mrb_value output_obj; | |
mrb_get_args (mrb, "o", &output_obj); | |
if (mrb_type (output_obj) != MRB_TT_DATA) | |
mrb_raise(mrb, E_ARGUMENT_ERROR, "output is not a data type"); | |
.if class.virtual ?= 1 | |
mrb_assert (zmsg_is (DATA_PTR (output_obj))); | |
zmsg_t *output = (zmsg_t *) DATA_PTR (output_obj); | |
.else | |
mrb_assert (zsock_is (DATA_PTR (output_obj))); | |
zsock_t *output = (zsock_t *) DATA_PTR (output_obj); | |
.endif | |
$(class.name)_t *self = ($(class.name)_t *) DATA_PTR (mrb_self); | |
if ($(class.name)_send (self, output) == -1) { | |
mrb_sys_fail (mrb, "$(class.name)_send"); | |
} | |
return mrb_self; | |
} | |
// -------------------------------------------------------------------------- | |
// Print contents of message to stdout | |
static mrb_value | |
mrb_$(class.name)_print (mrb_state *mrb, mrb_value mrb_self) | |
{ | |
$(class.name)_t *self = ($(class.name)_t *) DATA_PTR (mrb_self); | |
$(class.name)_print (self); | |
return mrb_self; | |
} | |
// -------------------------------------------------------------------------- | |
// Get the message routing_id | |
static mrb_value | |
mrb_$(class.name)_routing_id (mrb_state *mrb, mrb_value mrb_self) | |
{ | |
$(class.name)_t *self = ($(class.name)_t *) DATA_PTR (mrb_self); | |
zframe_t *routing_id = $(class.name)_routing_id (self); | |
return mrb_str_new_static (mrb, zframe_data (routing_id), zframe_size (routing_id)); | |
} | |
// Set the message routing_id | |
static mrb_value | |
mrb_$(class.name)_set_routing_id (mrb_state *mrb, mrb_value mrb_self) | |
{ | |
char *routing_id_str; | |
mrb_int routing_id_len; | |
mrb_get_args (mrb, "s", &routing_id_str, &routing_id_len); | |
if (routing_id_len > 256) { | |
mrb_raise (mrb, E_RANGE_ERROR, "routing_id is too large"); | |
} | |
$(class.name)_t *self = ($(class.name)_t *) DATA_PTR (mrb_self); | |
zframe_t *routing_id = zframe_new (routing_id_str, routing_id_len); | |
$(class.name)_set_routing_id (self, routing_id); | |
zframe_destroy (&routing_id); | |
return mrb_self; | |
} | |
// -------------------------------------------------------------------------- | |
// Get the $(class.name) id | |
static mrb_value | |
mrb_$(class.name)_id (mrb_state *mrb, mrb_value mrb_self) | |
{ | |
$(class.name)_t *self = ($(class.name)_t *) DATA_PTR (mrb_self); | |
// TODO: add bounds checking | |
return mrb_fixnum_value ($(class.name)_id (self)); | |
} | |
// Set the $(class.name) id | |
static mrb_value | |
mrb_$(class.name)_set_id (mrb_state *mrb, mrb_value mrb_self) | |
{ | |
mrb_int id; | |
mrb_get_args (mrb, "i", &id); | |
if (id < INT_MIN || id > INT_MAX) | |
mrb_raise (mrb, E_RANGE_ERROR, "id is out of range"); | |
$(class.name)_t *self = ($(class.name)_t *) DATA_PTR (mrb_self); | |
$(class.name)_set_id (self, id); | |
return mrb_self; | |
} | |
// -------------------------------------------------------------------------- | |
// Return a printable command string | |
static mrb_value | |
mrb_$(class.name)_command (mrb_state *mrb, mrb_value mrb_self) | |
{ | |
$(class.name)_t *self = ($(class.name)_t *) DATA_PTR (mrb_self); | |
const char *command = $(class.name)_command (self); | |
return mrb_str_new_static (mrb, command, strlen (command)); | |
} | |
.for class.field where !defined (value) | |
. if type = "number" | |
// -------------------------------------------------------------------------- | |
// Get the $(name) field | |
static mrb_value | |
mrb_$(class.name)_$(name) (mrb_state *mrb, mrb_value mrb_self) | |
{ | |
$(class.name)_t *self = ($(class.name)_t *) DATA_PTR (mrb_self); | |
// TODO: add bounds checking | |
return mrb_fixnum_value ($(class.name)_$(name) (self)); | |
} | |
// Set the $(name) field | |
static mrb_value | |
mrb_$(class.name)_set_$(name) (mrb_state *mrb, mrb_value mrb_self) | |
{ | |
mrb_int $(name); | |
mrb_get_args (mrb, "i", &$(name)); | |
// TODO: add bounds checking | |
$(class.name)_t *self = ($(class.name)_t *) DATA_PTR (mrb_self); | |
$(class.name)_set_$(name) (self, $(name)); | |
return mrb_self; | |
} | |
. elsif type = "octets" | |
// -------------------------------------------------------------------------- | |
// Get the $(name) field | |
static mrb_value | |
mrb_$(class.name)_$(name) (mrb_state *mrb, mrb_value mrb_self) | |
{ | |
$(class.name)_t *self = ($(class.name)_t *) DATA_PTR (mrb_self); | |
return mrb_str_new_static (mrb, $(class.name)_$(name) (self), $(size)); | |
} | |
// Set the $(name) field | |
static mrb_value | |
mrb_$(class.name)_set_$(name) (mrb_state *mrb, mrb_value mrb_self) | |
{ | |
byte *$(name); | |
mrb_int $(name)_len; | |
mrb_get_args (mrb, "s", &$(name), $(name)_len); | |
if ($(name)_len != $(size)) | |
mrb_raise (mrb, E_ARGUMENT_ERROR, "$(name) must be $(size) bytes long"); | |
$(class.name)_t *self = ($(class.name)_t *) DATA_PTR (mrb_self); | |
$(class.name)_set_$(name) (self, $(name)); | |
return mrb_self; | |
} | |
. elsif type = "string" | type = "longstr" | |
// -------------------------------------------------------------------------- | |
// Get the $(name) field | |
static mrb_value | |
mrb_$(class.name)_$(name) (mrb_state *mrb, mrb_value mrb_self) | |
{ | |
$(class.name)_t *self = ($(class.name)_t *) DATA_PTR (mrb_self); | |
const char *$(name) = $(class.name)_$(name) (self); | |
return mrb_str_new_static (mrb, $(name), strlen ($(name))); | |
} | |
// Set the $(name) field | |
static mrb_value | |
mrb_$(class.name)_set_$(name) (mrb_state *mrb, mrb_value mrb_self) | |
{ | |
char *$(name); | |
mrb_get_args (mrb, "z", &$(name)); | |
$(class.name)_t *self = ($(class.name)_t *) DATA_PTR (mrb_self); | |
$(class.name)_set_$(name) (self, $(name)); | |
return mrb_self; | |
} | |
. elsif type = "strings" | |
// -------------------------------------------------------------------------- | |
// Get the $(name) field | |
static mrb_value | |
mrb_$(class.name)_$(name) (mrb_state *mrb, mrb_value mrb_self) | |
{ | |
$(class.name)_t *self = ($(class.name)_t *) DATA_PTR (mrb_self); | |
zlist_t *$(name)s = $(class.name)_$(name) (self); | |
int ai = mrb_gc_arena_save (mrb); | |
mrb_value $(name) = mrb_ary_new_capa (mrb, zlist_size ($(name)s)); | |
char *item = (char *) zlist_first ($(name)s); | |
while (item) { | |
mrb_value item_obj = mrb_str_new_static (mrb, item, strlen (item)); | |
mrb_ary_push (mrb, $(name), item_obj); | |
mrb_gc_arena_restore (mrb, ai); | |
item = (char *) zlist_next ($(name)s); | |
} | |
return $(name); | |
} | |
// Set the $(name) field | |
static mrb_value | |
mrb_$(class.name)_set_$(name) (mrb_state *mrb, mrb_value mrb_self) | |
{ | |
errno = 0; | |
mrb_value *$(name)s; | |
mrb_int $(name)_len; | |
mrb_get_args (mrb, "a", &$(name)s, &$(name)_len); | |
$(class.name)_t *self = ($(class.name)_t *) DATA_PTR (mrb_self); | |
mrb_value *$(name)s_end = $(name)s + $(name)_len; | |
zlist_t *$(name) = zlist_new (); | |
if ($(name) == NULL) { | |
mrb_sys_fail (mrb, "zlist_new"); | |
} | |
int ai = mrb_gc_arena_save (mrb); | |
for (;$(name)s < $(name)_end ; $(name)s++) { | |
const char *item = mrb_string_value_cstr (mrb, &*$(name)s); | |
mrb_gc_arena_restore (mrb, ai); | |
if (zlist_append ($(name), item) == -1) { | |
zlist_destroy (&$(name)); | |
mrb_sys_fail (mrb, "zlist_append"); | |
} | |
} | |
$(class.name)_set_$(name) (self, &$(name)); | |
return mrb_self; | |
} | |
. elsif type = "hash" | |
// -------------------------------------------------------------------------- | |
// Get the $(name) field | |
static mrb_value | |
mrb_$(class.name)_$(name) (mrb_state *mrb, mrb_value mrb_self) | |
{ | |
$(class.name)_t *self = ($(class.name)_t *) DATA_PTR (mrb_self); | |
zhash_t *$(name)s = $(class.name)_$(name) (self); | |
int ai = mrb_gc_arena_save (mrb); | |
mrb_value $(name) = mrb_hash_new_capa (mrb, zhash_size ($(name)s)); | |
char *item = (char *) zhash_first ($(name)s); | |
while (item) { | |
const char *key = zhash_cursor ($(name)s); | |
mrb_value key_obj = mrb_str_new_static (mrb, key, strlen (key)); | |
mrb_value item_obj = mrb_str_new_static (mrb, item, strlen (item)); | |
mrb_hash_set (mrb, $(name), key_obj, item_obj); | |
mrb_gc_arena_restore (mrb, ai); | |
item = (char *) zhash_next ($(name)s); | |
} | |
return $(name); | |
} | |
// Set the $(name) field | |
static mrb_value | |
mrb_$(class.name)_set_$(name) (mrb_state *mrb, mrb_value mrb_self) | |
{ | |
errno = 0; | |
mrb_value $(name)s; | |
mrb_get_args (mrb, "H", &$(name)s); | |
$(class.name)_t *self = ($(class.name)_t *) DATA_PTR (mrb_self); | |
zhash_t *$(name) = zhash_new (); | |
if ($(name) == NULL) { | |
mrb_sys_fail (mrb, "zhash_new"); | |
} | |
int ai = mrb_gc_arena_save (mrb); | |
mrb_value keys = mrb_hash_keys (mrb, $(name)s); | |
for (mrb_int i = 0; i != RARRAY_LEN(keys); i++) { | |
mrb_value key_obj = mrb_ary_ref(mrb, keys, i); | |
const char *key = mrb_string_value_cstr (mrb, &key_obj); | |
mrb_value item_obj = mrb_hash_get (mrb, $(name)s, key_obj); | |
const char *item = mrb_string_value_cstr (mrb, &item_obj); | |
mrb_gc_arena_restore (mrb, ai); | |
if (zhash_insert ($(name), key, item) == -1) { | |
mrb_sys_fail (mrb, "zhash_insert"); | |
} | |
} | |
$(class.name)_set_$(name) (self, &$(name)); | |
return mrb_self; | |
} | |
. elsif type = "uuid" | |
// -------------------------------------------------------------------------- | |
// Get the $(name) field | |
static mrb_value | |
mrb_$(class.name)_$(name) (mrb_state *mrb, mrb_value mrb_self) | |
{ | |
$(class.name)_t *self = ($(class.name)_t *) DATA_PTR (mrb_self); | |
zuuid_t *$(name) = $(class.name)_$(name) (self); | |
return mrb_str_new_static (mrb, zuuid_data ($(name)), zuuid_size ($(name))); | |
} | |
// Set the $(name) field | |
static mrb_value | |
mrb_$(class.name)_set_$(name) (mrb_state *mrb, mrb_value mrb_self) | |
{ | |
char *$(name)_str; | |
mrb_int $(name)_len; | |
mrb_get_args (mrb, "s", &$(name)_str, &$(name)_len); | |
if ($(name)_len != ZUUID_LEN) | |
mrb_raisef (mrb, E_ARGUMENT_ERROR, "uuid must be %S bytes long", mrb_fixnum_value (ZUUID_LEN)); | |
$(class.name)_t *self = ($(class.name)_t *) DATA_PTR (mrb_self); | |
zuuid_t *$(name) = zuuid_new_from ($(name)_str); | |
$(class.name)_set_$(name) (self, $(name)); | |
zuuid_destroy (&$(name)); | |
return mrb_self; | |
} | |
// Create a $(name) | |
static mrb_value | |
mrb_$(class.name)_create_$(name) (mrb_state *mrb, mrb_value mrb_self) | |
{ | |
$(class.name)_t *self = ($(class.name)_t *) DATA_PTR (mrb_self); | |
zuuid_t *$(name) = zuuid_new (); | |
$(class.name)_set_$(name) (self, $(name)); | |
zuuid_destroy (&$(name)); | |
return mrb_self; | |
} | |
. elsif type = "chunk" | type = "frame" | |
// -------------------------------------------------------------------------- | |
// Get the $(name) field | |
static mrb_value | |
mrb_$(class.name)_$(name) (mrb_state *mrb, mrb_value mrb_self) | |
{ | |
$(class.name)_t *self = ($(class.name)_t *) DATA_PTR (mrb_self); | |
z$(type)_t *$(name) = $(class.name)_$(name) (self); | |
return mrb_str_new_static (mrb, z$(type)_data ($(name)), z$(type)_size ($(name))); | |
} | |
// Set the $(name) field | |
static mrb_value | |
mrb_$(class.name)_set_$(name) (mrb_state *mrb, mrb_value mrb_self) | |
{ | |
char *$(name)_str; | |
mrb_int $(name)_len; | |
mrb_get_args (mrb, "s", &$(name)_str, &$(name)_len); | |
$(class.name)_t *self = ($(class.name)_t *) DATA_PTR (mrb_self); | |
z$(type)_t *$(name) = z$(type)_new ($(name)_str, $(name)_len); | |
$(class.name)_set_$(name) (self, &$(name)); | |
return mrb_self; | |
} | |
. elsif type = "msg" | |
// -------------------------------------------------------------------------- | |
// Get the $(name) field | |
static mrb_value | |
mrb_$(class.name)_$(name) (mrb_state *mrb, mrb_value mrb_self) | |
{ | |
$(class.name)_t *self = ($(class.name)_t *) DATA_PTR (mrb_self); | |
zmsg_t *$(name)s = $(class.name)_$(name) (self); | |
int ai = mrb_gc_arena_save(mrb); | |
mrb_value $(name) = mrb_ary_new_capa (mrb, zmsg_size ($(name)s)); | |
zframe_t *item = zmsg_first ($(name)); | |
while (item) { | |
mrb_value $(name)_str = mrb_str_new_static (mrb, zframe_data (item), zframe_size (item)); | |
mrb_ary_push (mrb, $(name), $(name)_str); | |
mrb_gc_arena_restore (mrb, ai); | |
item = zmsg_next ($(name)s); | |
} | |
return $(name); | |
} | |
// Set the $(name) field | |
static mrb_value | |
mrb_$(class.name)_set_$(name) (mrb_state *mrb, mrb_value mrb_self) | |
{ | |
errno = 0; | |
mrb_value *$(name)s; | |
mrb_int $(name)_len; | |
mrb_get_args (mrb, "a", &$(name)s, &$(name)_len); | |
$(class.name)_t *self = ($(class.name)_t *) DATA_PTR (mrb_self); | |
zmsg_t *$(name) = zmsg_new (); | |
if ($(name) == NULL) { | |
mrb_sys_fail (mrb, "zmsg_new"); | |
} | |
mrb_value *$(name)s_end = $(name)s + $(name)_len; | |
int ai = mrb_gc_arena_save (mrb); | |
for (;$(name)s < $(name)s_end ; $(name)s++) { | |
mrb_value s = mrb_str_to_str (mrb, *$(name)s); | |
mrb_gc_arena_restore (mrb, ai); | |
if (zmsg_addmem ($(name), RSTRING_PTR (s), RSTRING_LEN (s)) == -1) { | |
zmsg_destroy (&$(name)); | |
mrb_sys_fail (mrb, "zmsg_addmem"); | |
} | |
} | |
$(class.name)_set_$(name) (self, &$(name)); | |
return mrb_self; | |
} | |
. endif | |
.endfor | |
.output "$(class.source_dir)/mrb_$(class.name)_gem_init.h" | |
struct RClass *$(class.name)_class; | |
$(class.name)_class = mrb_define_class (mrb, "$(class.name:Neat,Camel)", mrb->object_class); | |
MRB_SET_INSTANCE_TT($(class.name)_class, MRB_TT_DATA); | |
int ai = mrb_gc_arena_save (mrb); | |
.for define | |
mrb_define_const (mrb, $(class.name)_class, "$(DEFINE.NAME)", mrb_str_new_static (mrb, "$(value:)", strlen ("$(value:)")); | |
mrb_gc_arena_restore (mrb, ai); | |
.endfor | |
.for message | |
mrb_define_const (mrb, $(class.name)_class, "$(MESSAGE.NAME)", mrb_fixnum_value ($(id))); | |
mrb_gc_arena_restore (mrb, ai); | |
.endfor | |
.for class.field where type = "octets" | |
mrb_define_const (mrb, $(class.name)_class, "$(FIELD.NAME)_SIZE", mrb_fixnum_value ($(size))); | |
mrb_gc_arena_restore (mrb, ai); | |
.endfor | |
mrb_define_method (mrb, $(class.name)_class, "initialize", mrb_$(class.name)_initialize, MRB_ARGS_NONE()); | |
mrb_define_method (mrb, $(class.name)_class, "recv", mrb_$(class.name)_recv, MRB_ARGS_REQ(1)); | |
mrb_define_method (mrb, $(class.name)_class, "send", mrb_$(class.name)_send, MRB_ARGS_REQ(1)); | |
mrb_define_method (mrb, $(class.name)_class, "print", mrb_$(class.name)_print, MRB_ARGS_NONE()); | |
mrb_define_method (mrb, $(class.name)_class, "routing_id", mrb_$(class.name)_routing_id, MRB_ARGS_NONE()); | |
mrb_define_method (mrb, $(class.name)_class, "routing_id=", mrb_$(class.name)_set_routing_id, MRB_ARGS_REQ(1)); | |
mrb_define_method (mrb, $(class.name)_class, "id", mrb_$(class.name)_id, MRB_ARGS_NONE()); | |
mrb_define_method (mrb, $(class.name)_class, "id=", mrb_$(class.name)_set_id, MRB_ARGS_REQ(1)); | |
mrb_define_method (mrb, $(class.name)_class, "command", mrb_$(class.name)_command, MRB_ARGS_REQ(1)); | |
.for class.field where !defined (value) | |
. if type = "number" | type = "octets" | type = "string" | type = "longstr" | type = "strings" | type = "hash" | type = "chunk" | type = "frame" | type = "msg" | |
mrb_define_method (mrb, $(class.name)_class, "$(name)", mrb_$(class.name)_$(name), MRB_ARGS_NONE()); | |
mrb_define_method (mrb, $(class.name)_class, "$(name)=", mrb_$(class.name)_set_$(name), MRB_ARGS_REQ(1)); | |
. elsif type = "uuid" | |
mrb_define_method (mrb, $(class.name)_class, "$(name)", mrb_$(class.name)_$(name), MRB_ARGS_NONE()); | |
mrb_define_method (mrb, $(class.name)_class, "$(name)=", mrb_$(class.name)_set_$(name), MRB_ARGS_REQ(1)); | |
mrb_define_method (mrb, $(class.name)_class, "create_$(name)", mrb_$(class.name)_create_$(name), MRB_ARGS_NONE()); | |
. else | |
. echo "E: unknown type '$(type)' for field '$(name)'" | |
. endif | |
.endfor |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment