X-Git-Url: http://git.code-monkey.de/?a=blobdiff_plain;f=ext%2Fext.c;h=6c640b720e1ec9cf6971eb0c3d76ca8afbc43bd3;hb=9d1a1e30fcc9d74ef5887e478b7282acfa17e07f;hp=eed0e6582b2f679f98b48a39da38b427b98f9ab1;hpb=1d1646f3738b50777b8a13e8724a0270036f7dae;p=ruby-vorbistagger.git diff --git a/ext/ext.c b/ext/ext.c index eed0e65..6c640b7 100644 --- a/ext/ext.c +++ b/ext/ext.c @@ -17,62 +17,22 @@ */ #include +#include #include +#include #include "vcedit.h" #include "comments.h" typedef struct { - VALUE io; - bool need_close; - vcedit_state *state; - VALUE comments; } RbVorbisTagger; static VALUE c_close (VALUE self); -static VALUE cComments, eVTError, io_buf; -static ID id_read, id_write, id_seek, id_length; - -static size_t -on_read (void *ptr, size_t size, size_t nmemb, RbVorbisTagger *o) -{ - struct RString *buf; - size_t total = size * nmemb; - VALUE tmp; - - rb_str_resize (io_buf, size * nmemb); - - tmp = rb_funcall (o->io, id_read, 2, LONG2NUM (total), io_buf); - if (NIL_P (tmp)) - return 0; - - buf = RSTRING (tmp); - memcpy (ptr, buf->ptr, buf->len); - - return buf->len; -} - -static size_t -on_write (const void *ptr, size_t size, size_t nmemb, RbVorbisTagger *o) -{ - size_t total = size * nmemb; - - rb_str_resize (io_buf, total); - memcpy (RSTRING (io_buf)->ptr, ptr, total); - - return NUM2LONG (rb_io_write (o->io, io_buf)); -} - -static void -c_mark (RbVorbisTagger *o) -{ - rb_gc_mark (o->io); - rb_gc_mark (o->comments); - rb_gc_mark (io_buf); -} +static VALUE cComments, eVTError; +static ID id_length; static void c_free (RbVorbisTagger *o) @@ -84,6 +44,12 @@ c_free (RbVorbisTagger *o) ruby_xfree (o); } +static void +c_mark (RbVorbisTagger *o) +{ + rb_gc_mark (o->comments); +} + static VALUE c_alloc (VALUE klass) { @@ -95,14 +61,12 @@ c_alloc (VALUE klass) /* * call-seq: * Ogg::Vorbis::Tagger.open(arg) -> object - * Ogg::Vorbis::Tagger.open(arg) { |object| block } -> nil + * Ogg::Vorbis::Tagger.open(arg) { |object| block } -> object * * If a block isn't specified, Ogg::Vorbis::Tagger.open is a synonym * for Ogg::Vorbis::Tagger.new. - * If a block is given, it will be invoked with the - * Ogg::Vorbis::Tagger object as a parameter, and the file or IO object - * will be automatically closed when the block terminates. - * The method always returns +nil+ in this case. + * If a block is given, it will be invoked with the * Ogg::Vorbis::Tagger + * object as a parameter. */ static VALUE c_open (VALUE klass, VALUE arg) @@ -117,47 +81,28 @@ c_open (VALUE klass, VALUE arg) /* * call-seq: - * Ogg::Vorbis::Tagger.new(arg) -> object + * Ogg::Vorbis::Tagger.new(filename) -> object * - * Returns a new Ogg::Vorbis::Tagger object for the specified argument. - * *arg* can either be an IO object or a filename. + * Returns a new Ogg::Vorbis::Tagger object for the specified file. * * FIXME: add optional mode argument (read-only or read-write) */ static VALUE -c_init (VALUE self, VALUE io) +c_init (VALUE self, VALUE filename) { RbVorbisTagger *o; vorbis_comment *vc; - int s, i; + int i; Data_Get_Struct (self, RbVorbisTagger, o); - /* is this actually an IO object or a filename? */ - if (rb_respond_to (io, id_read) && - rb_respond_to (io, id_write) && - rb_respond_to (io, id_seek)) - o->need_close = false; - else if (!NIL_P (rb_check_string_type (io))) { - io = rb_file_open (StringValuePtr (io), "rb+"); - o->need_close = true; - } else - rb_raise (rb_eArgError, "invalid argument"); + StringValue (filename); - o->io = io; - - o->state = vcedit_state_new (); + o->state = vcedit_state_new (StringValuePtr (filename)); if (!o->state) rb_raise (eVTError, "vcedit_new_state() failed - %s", vcedit_error (o->state)); - s = vcedit_open_callbacks (o->state, o, - (vcedit_read_func) on_read, - (vcedit_write_func) on_write); - if (s < 0) - rb_raise (eVTError, "vcedit_open_callbacks() failed - %s", - vcedit_error (o->state)); - vc = vcedit_comments (o->state); if (!vc) rb_raise (eVTError, "vcedit_comments() failed - %s", @@ -195,9 +140,6 @@ c_close (VALUE self) vcedit_state_unref (o->state); o->state = NULL; - if (o->need_close) - rb_io_close (o->io); - return self; } @@ -212,17 +154,12 @@ static VALUE c_write (VALUE self) { RbVorbisTagger *o; - int s; Data_Get_Struct (self, RbVorbisTagger, o); - comments_sync (o->comments); + comments_sync (o->comments, o->state); - /* seek back to BOF */ - rb_funcall (o->io, id_seek, 1, INT2FIX (0)); - - s = vcedit_write (o->state, o); - if (s < 0) + if (vcedit_write (o->state) < 0) rb_raise (rb_eIOError, "write failed - %s", vcedit_error (o->state)); @@ -270,13 +207,7 @@ Init_vorbistagger_ext (void) eVTError = rb_define_class_under (cVT, "TaggerError", eVorbis); - id_read = rb_intern ("read"); - id_write = rb_intern ("write"); - id_seek = rb_intern ("seek"); id_length = rb_intern ("length"); cComments = Init_Comments (mVorbis); - - io_buf = rb_str_buf_new (0); - rb_global_variable (&io_buf); }