Code cleanup.
[ruby-vorbistagger.git] / ext / vcedit.c
index ce5cb10b56ee9ecadd2a4829b496a2ea990a491a..7976a066f4e5409fd5945617d6ec386fa4439cd2 100644 (file)
@@ -163,11 +163,11 @@ _v_writestring (oggpack_buffer *o, char *s, int len)
 }
 
 static int
-_commentheader_out (vorbis_comment *vc, char *vendor, ogg_packet *op)
+_commentheader_out (vcedit_state *s, ogg_packet *op)
 {
-       int i;
-
        oggpack_buffer opb;
+       size_t len;
+       int i;
 
        oggpack_writeinit (&opb);
 
@@ -176,19 +176,20 @@ _commentheader_out (vorbis_comment *vc, char *vendor, ogg_packet *op)
        _v_writestring (&opb, "vorbis", 6);
 
        /* vendor */
-       oggpack_write (&opb, strlen (vendor), 32);
-       _v_writestring (&opb, vendor, strlen (vendor));
+       len = strlen (s->vendor);
+       oggpack_write (&opb, len, 32);
+       _v_writestring (&opb, s->vendor, len);
 
        /* comments */
-       oggpack_write (&opb, vc->comments, 32);
+       oggpack_write (&opb, s->vc.comments, 32);
 
-       for (i = 0; i < vc->comments; i++) {
-               if (!vc->user_comments[i])
+       for (i = 0; i < s->vc.comments; i++) {
+               if (!s->vc.user_comments[i])
                        oggpack_write (&opb, 0, 32);
                else {
-                       oggpack_write (&opb, vc->comment_lengths[i], 32);
-                       _v_writestring (&opb, vc->user_comments[i],
-                                       vc->comment_lengths[i]);
+                       oggpack_write (&opb, s->vc.comment_lengths[i], 32);
+                       _v_writestring (&opb, s->vc.user_comments[i],
+                                       s->vc.comment_lengths[i]);
                }
        }
 
@@ -240,7 +241,7 @@ _fetch_next_packet (vcedit_state *s, ogg_packet *p, ogg_page *page)
                bytes = fread (buffer, 1, CHUNKSIZE, s->in);
                ogg_sync_wrote (&s->oy, bytes);
 
-               if (!bytes && feof (s->in))
+               if (!bytes && (feof (s->in) || ferror (s->in)))
                        return 0;
        }
 
@@ -276,7 +277,7 @@ vcedit_open (vcedit_state *s)
 
        do {
                /* Bail if we don't find data in the first 40 kB */
-               if (feof (s->in) || total >= (CHUNKSIZE * 10)) {
+               if (feof (s->in) || ferror (s->in) || total >= (CHUNKSIZE * 10)) {
                        ogg_sync_clear (&s->oy);
 
                        return VCEDIT_ERR_INVAL;
@@ -318,6 +319,11 @@ vcedit_open (vcedit_state *s)
        header = &header_comments;
 
        while (i < 2) {
+               if (feof (s->in) || ferror (s->in)) {
+                       ret = VCEDIT_ERR_INVAL;
+                       goto err;
+               }
+
                while (i < 2) {
                        int result;
 
@@ -353,13 +359,8 @@ vcedit_open (vcedit_state *s)
                }
 
                buffer = ogg_sync_buffer (&s->oy, CHUNKSIZE);
-               bytes = fread (buffer, 1, CHUNKSIZE, s->in);
-
-               if (!bytes && feof (s->in) && i < 2) {
-                       ret = VCEDIT_ERR_INVAL;
-                       goto err;
-               }
 
+               bytes = fread (buffer, 1, CHUNKSIZE, s->in);
                ogg_sync_wrote (&s->oy, bytes);
        }
 
@@ -403,6 +404,7 @@ vcedit_write (vcedit_state *s)
        ogg_int64_t granpos = 0;
        FILE *out;
        char *buffer, tmpfile[PATH_MAX];
+       bool success = false;
        int fd, result, bytes, needflush = 0, needout = 0;
 
        if (!s->opened)
@@ -439,7 +441,7 @@ vcedit_write (vcedit_state *s)
 
        ogg_stream_init (&streamout, s->serial);
 
-       _commentheader_out (&s->vc, s->vendor, &header_comments);
+       _commentheader_out (s, &header_comments);
 
        ogg_stream_packetin (&streamout, &header_main);
        ogg_stream_packetin (&streamout, &header_comments);
@@ -540,16 +542,26 @@ vcedit_write (vcedit_state *s)
                bytes = fread (buffer, 1, CHUNKSIZE, s->in);
                ogg_sync_wrote (&s->oy, bytes);
 
+               if (ferror (s->in))
+                       goto cleanup;
+
                s->eosin = !bytes && feof (s->in);
        } while (!s->eosin);
 
-       fclose (out);
+       success = true;
+
+cleanup:
        fclose (s->in);
 
-       unlink (s->filename);
-       rename (tmpfile, s->filename);
+       if (!success) {
+               unlink (tmpfile);
+               fclose (out);
+       } else {
+               fclose (out);
+               unlink (s->filename);
+               rename (tmpfile, s->filename);
+       }
 
-cleanup:
        ogg_stream_clear (&streamout);
 
     /* We don't ogg_packet_clear() this, because the memory was