Reworked error handling.
[ruby-vorbistagger.git] / ext / ext.c
index 9c433f285523c12196501363e132a8662f9907e5..67fa6b14b24811514db40966ca373d1050c9bbf8 100644 (file)
--- a/ext/ext.c
+++ b/ext/ext.c
@@ -20,6 +20,7 @@
 #include <stdio.h>
 #include <stdbool.h>
 #include <errno.h>
+#include <assert.h>
 
 #include "vcedit.h"
 #include "comments.h"
@@ -31,7 +32,8 @@ typedef struct {
 
 static VALUE c_close (VALUE self);
 
-static VALUE cComments, eVTError;
+static VALUE cComments, eVT, eOpen, eInvalidData, eInvalidComment,
+             eTempFile, eReopen;
 static ID id_length;
 
 static void
@@ -100,17 +102,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));
-
-       if (vcedit_open (o->state) < 0)
-               rb_raise (eVTError, "vcedit_open() 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++) {
@@ -118,7 +126,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);
@@ -163,9 +171,16 @@ c_write (VALUE self)
 
        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);
 }
@@ -209,7 +224,13 @@ 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);
+       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");