diff --git a/ruby/caca-canvas.c b/ruby/caca-canvas.c index b82e078..33ced76 100644 --- a/ruby/caca-canvas.c +++ b/ruby/caca-canvas.c @@ -18,6 +18,7 @@ #include "caca-font.h" #include "caca_internals.h" #include "common.h" +#include "limits.h" VALUE cCanvas; @@ -41,16 +42,42 @@ static void canvas_free(void * p) caca_free_canvas((caca_canvas_t *)p); } +static size_t canvas_size(const void *p) +{ + const caca_canvas_t *cv = (const caca_canvas_t *)p; + + if (cv->height * cv->width > INT_MAX / cv->framecount) { + return INT_MAX; + } + + return cv->height * cv->width * cv->framecount; +} + +static const rb_data_type_t canvas_dt = { + .wrap_struct_name = "Caca::Canvas", + .function = { + .dsize = canvas_size, + .dfree = canvas_free, + }, +}; + +static const rb_data_type_t display_autocreated_canvas_dt = { + .wrap_struct_name = "Caca::Canvas", + .function = { + .dsize = canvas_size, + }, +}; + static VALUE canvas_alloc(VALUE klass) { VALUE obj; - obj = Data_Wrap_Struct(klass, NULL, canvas_free, NULL); + obj = TypedData_Wrap_Struct(klass, &canvas_dt, NULL); return obj; } VALUE canvas_create(caca_canvas_t *canvas) { - return Data_Wrap_Struct(cCanvas, NULL, NULL, canvas); + return TypedData_Wrap_Struct(cCanvas, &display_autocreated_canvas_dt, canvas); } static VALUE canvas_initialize(VALUE self, VALUE width, VALUE height) @@ -223,7 +250,7 @@ static VALUE blit(int argc, VALUE* argv, VALUE self) { { rb_raise(rb_eArgError, "src is not a Caca::Canvas"); } - Data_Get_Struct(src, caca_canvas_t, csrc); + TypedData_Get_Struct(src, caca_canvas_t, &canvas_dt, csrc); if(!NIL_P(mask)) { @@ -231,7 +258,7 @@ static VALUE blit(int argc, VALUE* argv, VALUE self) { { rb_raise(rb_eArgError, "mask is not a Caca::Canvas"); } - Data_Get_Struct(mask, caca_canvas_t, cmask); + TypedData_Get_Struct(mask, caca_canvas_t, &canvas_dt, cmask); } else cmask = NULL; @@ -504,7 +531,7 @@ static VALUE fill_triangle_textured(VALUE self, VALUE coords, VALUE texture, VAL { rb_raise(rb_eArgError, "texture is not a Caca::Canvas"); } - Data_Get_Struct(texture, caca_canvas_t, ctexture); + TypedData_Get_Struct(texture, caca_canvas_t, &canvas_dt, ctexture); caca_fill_triangle_textured(_SELF, ccoords, ctexture, cuv); return self; diff --git a/ruby/caca-display.c b/ruby/caca-display.c index a3b3487..b478fc2 100644 --- a/ruby/caca-display.c +++ b/ruby/caca-display.c @@ -23,11 +23,16 @@ void display_free(void *display) caca_free_display((caca_display_t *)display); } +static const rb_data_type_t display_dt = { + .wrap_struct_name = "Caca::Display", + .function = { + .dfree = display_free, + }, +}; + static VALUE display_alloc(VALUE klass) { - VALUE obj; - obj = Data_Wrap_Struct(klass, 0, display_free, NULL); - return obj; + return TypedData_Wrap_Struct(klass, &display_dt, NULL); } static VALUE display_initialize(int argc, VALUE* argv, VALUE self) diff --git a/ruby/caca-dither.c b/ruby/caca-dither.c index 0ca5e5f..b4e8d9c 100644 --- a/ruby/caca-dither.c +++ b/ruby/caca-dither.c @@ -21,10 +21,17 @@ void dither_free(void *dither) caca_free_dither((caca_dither_t *)dither); } +static const rb_data_type_t dither_dt = { + .wrap_struct_name = "Caca::Dither", + .function = { + .dfree = dither_free, + }, +}; + static VALUE dither_alloc(VALUE klass) { VALUE obj; - obj = Data_Wrap_Struct(klass, 0, dither_free, NULL); + obj = TypedData_Wrap_Struct(klass, &dither_dt, NULL); return obj; } diff --git a/ruby/caca-font.c b/ruby/caca-font.c index 72b5629..20c0e31 100644 --- a/ruby/caca-font.c +++ b/ruby/caca-font.c @@ -21,10 +21,17 @@ void font_free(void *font) caca_free_font((caca_font_t *)font); } +static const rb_data_type_t font_dt = { + .wrap_struct_name = "Caca::Font", + .function = { + .dfree = font_free, + }, +}; + static VALUE font_alloc(VALUE klass) { VALUE obj; - obj = Data_Wrap_Struct(klass, 0, font_free, NULL); + obj = TypedData_Wrap_Struct(klass, &font_dt, NULL); return obj; }