Packages

Cairo wrapper for Elixir

Current section

Files

Jump to
cairo_ex src router.c
Raw

src/router.c

#include "router.h"
#include "eio.h"
#include "api/context.h"
#include "api/path.h"
#include "api/surface.h"
#include "api/transformations.h"
#include <string.h>
typedef struct {
const char *name;
cx_method method;
} method_entry_t;
static method_entry_t method_table[] = {
// Transformations
{"device_to_user", cx_device_to_user },
{"device_to_user_distance", cx_device_to_user_distance },
{"get_matrix", cx_get_matrix },
{"identity_matrix", cx_identity_matrix },
{"rotate", cx_rotate },
{"scale", cx_scale },
{"set_matrix", cx_set_matrix },
{"transform", cx_transform },
{"translate", cx_translate },
{"user_to_device", cx_user_to_device },
{"user_to_device_distance", cx_user_to_device_distance },
// Drawing
{"create", cx_create },
{"destroy", cx_destroy },
{"fill", cx_fill },
{"get_target", cx_get_target },
{"paint", cx_paint },
{"pop_group", cx_pop_group },
{"push_group", cx_push_group },
{"restore", cx_restore },
{"save", cx_save },
{"set_line_width", cx_set_line_width },
{"set_source_rgb", cx_set_source_rgb },
{"set_source_rgba", cx_set_source_rgba },
{"status", cx_status },
{"stroke", cx_stroke },
// Paths
{"arc", cx_arc },
{"line_to", cx_line_to },
{"move_to", cx_move_to },
{"rectangle", cx_rectangle },
// Surface
{"image_surface_create", cx_surface_image_surface_create },
{"surface_destroy", cx_surface_destroy },
{"surface_write_to_png", cx_surface_write_to_png },
{NULL, NULL}
};
static cx_method router_lookup(const char *name) {
for (method_entry_t *e = method_table; e->name != NULL; ++e) {
if (!strcmp(e->name, name)) {
return e->method;
}
}
return NULL;
}
cx_status_t router_handle(const char *buf, size_t _len, cx_result_t *result) {
cx_status_t err;
int index = 0;
int version = 0;
int arity = 0;
char method_name[64];
cx_method method = NULL;
if ((ei_decode_version(buf, &index, &version) != 0) ||
(ei_decode_tuple_header(buf, &index, &arity) != 0) ||
(arity != 2) ||
(ei_decode_atom(buf, &index, method_name) != 0)) {
err = CX_STATUS_DECODE_ERROR;
goto error;
}
if ((method = router_lookup(method_name)) != NULL) {
err = method(buf, &index, result);
} else {
err = CX_STATUS_UNKNOWN_METHOD;
};
error:
switch(err) {
case CX_STATUS_INVALID_REFERENCE:
return eio_encode_result_error_atom(result, "cx_invalid_reference");
case CX_STATUS_UNKNOWN_METHOD:
return eio_encode_result_error_atom(result, "cx_unknown_cmd");
case CX_STATUS_DECODE_ERROR:
return eio_encode_result_error_atom(result, "cx_decode");
case CX_STATUS_ENCODE_ERROR:
return eio_encode_result_error_atom(result, "cx_encode");
default:
return err;
}
}