X-Git-Url: http://git.code-monkey.de/?a=blobdiff_plain;f=ext%2Fext.c;h=957dc41260c77473fb548d18670f5388f1883890;hb=5520025d1eba64b292866dfb0dfaebf0bfe6d8db;hp=6c640b720e1ec9cf6971eb0c3d76ca8afbc43bd3;hpb=9d1a1e30fcc9d74ef5887e478b7282acfa17e07f;p=ruby-vorbistagger.git diff --git a/ext/ext.c b/ext/ext.c index 6c640b7..957dc41 100644 --- a/ext/ext.c +++ b/ext/ext.c @@ -20,10 +20,15 @@ #include #include #include +#include #include "vcedit.h" #include "comments.h" +#define CHECK_CLOSED(o) \ + if (!o->state) \ + rb_raise (eClosed, "closed stream"); + typedef struct { vcedit_state *state; VALUE comments; @@ -31,7 +36,8 @@ typedef struct { static VALUE c_close (VALUE self); -static VALUE cComments, eVTError; +static VALUE cComments, eVT, eClosed, eOpen, eInvalidData, + eInvalidComment, eTempFile, eReopen; static ID id_length; static void @@ -100,13 +106,23 @@ c_init (VALUE self, VALUE filename) o->state = vcedit_state_new (StringValuePtr (filename)); if (!o->state) - rb_raise (eVTError, "vcedit_new_state() failed - %s", - vcedit_error (o->state)); + rb_raise (rb_eNoMemError, "Out of Memory"); + + switch (vcedit_open (o->state)) { + case VCEDIT_ERR_OPEN: + rb_raise (eOpen, "Cannot open file"); + case VCEDIT_ERR_INVAL: + rb_raise (eInvalidData, "Invalid data"); + default: + break; + } vc = vcedit_comments (o->state); - if (!vc) - rb_raise (eVTError, "vcedit_comments() failed - %s", - vcedit_error (o->state)); + + /* vcedit_open() succeeded, so vcedit_comments() cannot + * return NULL. + */ + assert (vc); /* check whether all comments are well-formed */ for (i = 0; i < vc->comments; i++) { @@ -114,7 +130,7 @@ c_init (VALUE self, VALUE filename) ptr = strchr (content, '='); if (!ptr || ptr == content) - rb_raise (eVTError, "malformed comment - %s", content); + rb_raise (eInvalidComment, "invalid comment - %s", content); } o->comments = rb_class_new_instance (0, NULL, cComments); @@ -126,9 +142,11 @@ c_init (VALUE self, VALUE filename) /* * call-seq: - * object.close -> object + * object.close -> nil * - * Closes *object* and returns it. + * Closes *object*. Further method calls on *object* will raise an + * Ogg::Vorbis::Tagger::ClosedStreamError exception. + * Returns +nil+. */ static VALUE c_close (VALUE self) @@ -137,10 +155,12 @@ c_close (VALUE self) Data_Get_Struct (self, RbVorbisTagger, o); + CHECK_CLOSED (o); + vcedit_state_unref (o->state); o->state = NULL; - return self; + return Qnil; } /* @@ -157,13 +177,22 @@ c_write (VALUE self) Data_Get_Struct (self, RbVorbisTagger, o); + CHECK_CLOSED (o); + comments_sync (o->comments, o->state); - if (vcedit_write (o->state) < 0) - rb_raise (rb_eIOError, "write failed - %s", - vcedit_error (o->state)); + switch (vcedit_write (o->state)) { + case VCEDIT_ERR_INVAL: + rb_raise (eInvalidData, "Invalid data"); + case VCEDIT_ERR_TMPFILE: + rb_raise (eTempFile, "Cannot create temporary file"); + case VCEDIT_ERR_REOPEN: + rb_raise (eReopen, "Cannot reopen file"); + default: + break; + } - return rb_funcall (o->comments, id_length, 0); + return rb_funcall2 (o->comments, id_length, 0, NULL); } /* @@ -180,6 +209,8 @@ c_comments (VALUE self) Data_Get_Struct (self, RbVorbisTagger, o); + CHECK_CLOSED (o); + return o->comments; } @@ -205,7 +236,14 @@ Init_vorbistagger_ext (void) rb_define_method (cVT, "write", c_write, 0); rb_define_method (cVT, "comments", c_comments, 0); - eVTError = rb_define_class_under (cVT, "TaggerError", eVorbis); + eVT = rb_define_class_under (cVT, "TaggerError", eVorbis); + eClosed = rb_define_class_under (cVT, "ClosedStreamError", eVT); + eOpen = rb_define_class_under (cVT, "OpenError", eVT); + eInvalidData = rb_define_class_under (cVT, "InvalidDataError", eVT); + eInvalidComment = rb_define_class_under (cVT, "InvalidCommentError", + eInvalidData); + eTempFile = rb_define_class_under (cVT, "TempFileError", eVT); + eReopen = rb_define_class_under (cVT, "ReopenError", eVT); id_length = rb_intern ("length");