Skip to content

Instantly share code, notes, and snippets.

@Asmod4n
Last active August 29, 2015 14:27
Show Gist options
  • Save Asmod4n/7e0a0936e3553ad38f88 to your computer and use it in GitHub Desktop.
Save Asmod4n/7e0a0936e3553ad38f88 to your computer and use it in GitHub Desktop.
// 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