projects
/
ruby-vorbistagger.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
Keep the original file mode when writing files.
[ruby-vorbistagger.git]
/
ext
/
vcedit.c
diff --git
a/ext/vcedit.c
b/ext/vcedit.c
index 336ce26e94f531a299c045091016dc1bfe7d60d2..414d6d060f31c0d98f6b3a4a12dfa18748e79904 100644
(file)
--- a/
ext/vcedit.c
+++ b/
ext/vcedit.c
@@
-23,6
+23,8
@@
#include <errno.h>
#include <limits.h>
#include <unistd.h>
#include <errno.h>
#include <limits.h>
#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
#include <ogg/ogg.h>
#include <vorbis/codec.h>
#include <assert.h>
#include <ogg/ogg.h>
#include <vorbis/codec.h>
#include <assert.h>
@@
-31,71
+33,53
@@
#define CHUNKSIZE 4096
#define CHUNKSIZE 4096
-static int vcedit_open (vcedit_state *state);
-
struct vcedit_state_St {
int refcount;
struct vcedit_state_St {
int refcount;
- ogg_sync_state *oy;
- ogg_stream_state *os;
-
- vorbis_comment *vc;
- vorbis_info *vi;
+ ogg_sync_state oy;
+ ogg_stream_state os;
- char filename[PATH_MAX];
+ vorbis_comment vc;
+ vorbis_info vi;
FILE *in;
FILE *in;
+ mode_t file_mode;
+
+ bool opened;
long serial;
unsigned char *mainbuf;
unsigned char *bookbuf;
int mainlen;
int booklen;
long serial;
unsigned char *mainbuf;
unsigned char *bookbuf;
int mainlen;
int booklen;
- const char *lasterror;
char *vendor;
int prevW;
int extrapage;
int eosin;
char *vendor;
int prevW;
int extrapage;
int eosin;
+
+ char filename[0];
};
static void
};
static void
-vcedit_state_free (vcedit_state *s
tate
)
+vcedit_state_free (vcedit_state *s)
{
{
- free (state->oy);
- free (state->os);
- free (state->vc);
- free (state->vi);
- free (state->mainbuf);
- free (state->bookbuf);
- free (state->vendor);
-
- if (state->in) {
- fclose (state->in);
- state->in = NULL;
+ free (s->mainbuf);
+ free (s->bookbuf);
+ free (s->vendor);
+
+ if (s->in) {
+ fclose (s->in);
+ s->in = NULL;
}
}
- free (s
tate
);
+ free (s);
}
static bool
}
static bool
-vcedit_state_init (vcedit_state *s
tat
e)
+vcedit_state_init (vcedit_state *s
, const char *filenam
e)
{
{
- s
tate
->refcount = 1;
+ s->refcount = 1;
- state->oy = malloc (sizeof (ogg_sync_state));
- if (!state->oy)
- return false;
-
- state->os = malloc (sizeof (ogg_stream_state));
- if (!state->os)
- return false;
-
- state->vc = malloc (sizeof (vorbis_comment));
- if (!state->vc)
- return false;
-
- state->vi = malloc (sizeof (vorbis_info));
- if (!state->vi)
- return false;
+ strcpy (s->filename, filename);
return true;
}
return true;
}
@@
-103,81
+87,73
@@
vcedit_state_init (vcedit_state *state)
vcedit_state *
vcedit_state_new (const char *filename)
{
vcedit_state *
vcedit_state_new (const char *filename)
{
- vcedit_state *state;
+ vcedit_state *s;
+ size_t len;
-
state = malloc (sizeof (vcedit_state)
);
- if (
!state
)
+
len = strlen (filename
);
+ if (
len > PATH_MAX
)
return NULL;
return NULL;
- memset (state, 0, sizeof (vcedit_state));
-
- if (!vcedit_state_init (state)) {
- vcedit_state_free (state);
+ s= malloc (sizeof (vcedit_state) + len + 1);
+ if (!s)
return NULL;
return NULL;
- }
-
- snprintf (state->filename, sizeof (state->filename),
- "%s", filename);
-
state->in = fopen (state->filename, "rb"
);
+
memset (s, 0, sizeof (vcedit_state)
);
- if (
vcedit_open (state) < 0
) {
- vcedit_state_free (s
tate
);
+ if (
!vcedit_state_init (s, filename)
) {
+ vcedit_state_free (s);
return NULL;
}
return NULL;
}
- return state;
-}
-
-const char *
-vcedit_error (vcedit_state *state)
-{
- return state->lasterror;
+ return s;
}
vorbis_comment *
}
vorbis_comment *
-vcedit_comments (vcedit_state *s
tate
)
+vcedit_comments (vcedit_state *s)
{
{
- return s
tate->vc
;
+ return s
->opened ? &s->vc : NULL
;
}
static void
}
static void
-vcedit_clear_internals (vcedit_state *s
tate
)
+vcedit_clear_internals (vcedit_state *s)
{
{
- ogg_stream_clear (
state
->os);
- ogg_sync_clear (
state
->oy);
+ ogg_stream_clear (
&s
->os);
+ ogg_sync_clear (
&s
->oy);
- vorbis_info_clear (
state
->vi);
- vorbis_comment_clear (
state
->vc);
+ vorbis_info_clear (
&s
->vi);
+ vorbis_comment_clear (
&s
->vc);
- free (s
tate
->vendor);
- s
tate
->vendor = NULL;
+ free (s->vendor);
+ s->vendor = NULL;
- free (s
tate
->mainbuf);
- s
tate
->mainbuf = NULL;
- s
tate
->mainlen = 0;
+ free (s->mainbuf);
+ s->mainbuf = NULL;
+ s->mainlen = 0;
- free (s
tate
->bookbuf);
- s
tate
->bookbuf = NULL;
- s
tate
->booklen = 0;
+ free (s->bookbuf);
+ s->bookbuf = NULL;
+ s->booklen = 0;
- state->serial = 0;
+ s->serial = 0;
+ s->opened = false;
}
void
}
void
-vcedit_state_ref (vcedit_state *s
tate
)
+vcedit_state_ref (vcedit_state *s)
{
{
- s
tate
->refcount++;
+ s->refcount++;
}
void
}
void
-vcedit_state_unref (vcedit_state *s
tate
)
+vcedit_state_unref (vcedit_state *s)
{
{
- if (--s
tate
->refcount)
+ if (--s->refcount)
return;
return;
- vcedit_clear_internals (state);
- vcedit_state_free (state);
+ if (s->opened)
+ vcedit_clear_internals (s);
+
+ vcedit_state_free (s);
}
/* Next two functions pulled straight from libvorbis, apart from one change
}
/* Next two functions pulled straight from libvorbis, apart from one change
@@
-186,17
+162,16
@@
vcedit_state_unref (vcedit_state *state)
static void
_v_writestring (oggpack_buffer *o, char *s, int len)
{
static void
_v_writestring (oggpack_buffer *o, char *s, int len)
{
- while (len--)
{
+ while (len--)
oggpack_write (o, *s++, 8);
oggpack_write (o, *s++, 8);
- }
}
static int
}
static int
-_commentheader_out (v
orbis_comment *vc, char *vendor
, ogg_packet *op)
+_commentheader_out (v
cedit_state *s
, ogg_packet *op)
{
{
- int i;
-
oggpack_buffer opb;
oggpack_buffer opb;
+ size_t len;
+ int i;
oggpack_writeinit (&opb);
oggpack_writeinit (&opb);
@@
-205,19
+180,20
@@
_commentheader_out (vorbis_comment *vc, char *vendor, ogg_packet *op)
_v_writestring (&opb, "vorbis", 6);
/* vendor */
_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 */
/* 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, 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]);
}
}
}
}
@@
-241,7
+217,7
@@
_blocksize (vcedit_state *s, ogg_packet *p)
{
int this, ret = 0;
{
int this, ret = 0;
- this = vorbis_packet_blocksize (s->vi, p);
+ this = vorbis_packet_blocksize (
&
s->vi, p);
if (s->prevW)
ret = (this + s->prevW) / 4;
if (s->prevW)
ret = (this + s->prevW) / 4;
@@
-257,20
+233,19
@@
_fetch_next_packet (vcedit_state *s, ogg_packet *p, ogg_page *page)
char *buffer;
int result, bytes;
char *buffer;
int result, bytes;
- result = ogg_stream_packetout (s->os, p);
-
- if (result > 0)
+ result = ogg_stream_packetout (&s->os, p);
+ if (result == 1)
return 1;
if (s->eosin)
return 0;
return 1;
if (s->eosin)
return 0;
- while (ogg_sync_pageout (
s->oy, page) <= 0
) {
- buffer = ogg_sync_buffer (s->oy, CHUNKSIZE);
+ while (ogg_sync_pageout (
&s->oy, page) != 1
) {
+ buffer = ogg_sync_buffer (
&
s->oy, CHUNKSIZE);
bytes = fread (buffer, 1, CHUNKSIZE, s->in);
bytes = fread (buffer, 1, CHUNKSIZE, s->in);
- ogg_sync_wrote (s->oy, bytes);
+ ogg_sync_wrote (
&
s->oy, bytes);
- if (!bytes)
+ if (!bytes
&& (feof (s->in) || ferror (s->in))
)
return 0;
}
return 0;
}
@@
-282,131
+257,153
@@
_fetch_next_packet (vcedit_state *s, ogg_packet *p, ogg_page *page)
return 0;
}
return 0;
}
- ogg_stream_pagein (s->os, page);
+ ogg_stream_pagein (
&
s->os, page);
return _fetch_next_packet (s, p, page);
}
return _fetch_next_packet (s, p, page);
}
-static int
-vcedit_open (vcedit_state *s
tate
)
+vcedit_error
+vcedit_open (vcedit_state *s)
{
{
- char *buffer;
- int bytes, i;
- int chunks = 0;
+ vcedit_error ret;
ogg_packet *header;
ogg_packet header_main, header_comments, header_codebooks;
ogg_page og;
ogg_packet *header;
ogg_packet header_main, header_comments, header_codebooks;
ogg_page og;
+ struct stat st;
+ char *buffer;
+ size_t bytes, total = 0;
+ int i = 0;
- ogg_sync_init (state->oy);
-
- while (1) {
- buffer = ogg_sync_buffer (state->oy, CHUNKSIZE);
- bytes = fread (buffer, 1, CHUNKSIZE, state->in);
+ s->in = fopen (s->filename, "rb");
+ if (!s->in)
+ return VCEDIT_ERR_OPEN;
-
ogg_sync_wrote (state->oy, bytes)
;
+
s->file_mode = stat (s->filename, &st) ? 0664 : st.st_mode
;
- if (ogg_sync_pageout (state->oy, &og) == 1)
- break;
+ ogg_sync_init (&s->oy);
+ do {
/* Bail if we don't find data in the first 40 kB */
/* Bail if we don't find data in the first 40 kB */
- if (chunks++ >= 10) {
- if (bytes < CHUNKSIZE)
- state->lasterror = "Input truncated or empty.";
- else
- state->lasterror = "Input is not an Ogg bitstream.";
+ if (feof (s->in) || ferror (s->in) || total >= (CHUNKSIZE * 10)) {
+ ogg_sync_clear (&s->oy);
-
goto err
;
+
return VCEDIT_ERR_INVAL
;
}
}
- }
- state->serial = ogg_page_serialno (&og);
+ buffer = ogg_sync_buffer (&s->oy, CHUNKSIZE);
+
+ bytes = fread (buffer, 1, CHUNKSIZE, s->in);
+ total += bytes;
+
+ ogg_sync_wrote (&s->oy, bytes);
+ } while (ogg_sync_pageout (&s->oy, &og) != 1);
+
+ s->serial = ogg_page_serialno (&og);
- ogg_stream_init (
state->os, state
->serial);
- vorbis_info_init (
state
->vi);
- vorbis_comment_init (
state
->vc);
+ ogg_stream_init (
&s->os, s
->serial);
+ vorbis_info_init (
&s
->vi);
+ vorbis_comment_init (
&s
->vc);
- if (ogg_stream_pagein (
state
->os, &og) < 0) {
-
state->lasterror = "Error reading first page of Ogg bitstream."
;
+ if (ogg_stream_pagein (
&s
->os, &og) < 0) {
+
ret = VCEDIT_ERR_INVAL
;
goto err;
}
goto err;
}
- if (ogg_stream_packetout (
state
->os, &header_main) != 1) {
-
state->lasterror = "Error reading initial header packet."
;
+ if (ogg_stream_packetout (
&s
->os, &header_main) != 1) {
+
ret = VCEDIT_ERR_INVAL
;
goto err;
}
goto err;
}
- if (vorbis_synthesis_headerin (
state->vi, state
->vc, &header_main) < 0) {
-
state->lasterror = "Ogg bitstream does not contain vorbis data."
;
+ if (vorbis_synthesis_headerin (
&s->vi, &s
->vc, &header_main) < 0) {
+
ret = VCEDIT_ERR_INVAL
;
goto err;
}
goto err;
}
- s
tate
->mainlen = header_main.bytes;
- s
tate->mainbuf = malloc (state
->mainlen);
- memcpy (s
tate
->mainbuf, header_main.packet, header_main.bytes);
+ s->mainlen = header_main.bytes;
+ s
->mainbuf = malloc (s
->mainlen);
+ memcpy (s->mainbuf, header_main.packet, header_main.bytes);
- i = 0;
header = &header_comments;
while (i < 2) {
header = &header_comments;
while (i < 2) {
+ if (feof (s->in) || ferror (s->in)) {
+ ret = VCEDIT_ERR_INVAL;
+ goto err;
+ }
+
while (i < 2) {
while (i < 2) {
- int result
= ogg_sync_pageout (state->oy, &og)
;
+ int result;
+ result = ogg_sync_pageout (&s->oy, &og);
if (!result)
break; /* Too little data so far */
if (!result)
break; /* Too little data so far */
- if (result == 1) {
- ogg_stream_pagein (state->os, &og);
-
- while (i < 2) {
- result = ogg_stream_packetout (state->os, header);
+ if (result != 1)
+ continue;
- if (!result)
- break;
+ ogg_stream_pagein (&s->os, &og);
-
if (result == -1
) {
-
state->lasterror = "Corrupt secondary header."
;
- goto err;
- }
+
while (i < 2
) {
+
result = ogg_stream_packetout (&s->os, header)
;
+ if (!result)
+ break;
- vorbis_synthesis_headerin (state->vi, state->vc, header);
+ if (result != 1) {
+ ret = VCEDIT_ERR_INVAL;
+ goto err;
+ }
- if (i == 1) {
- state->booklen = header->bytes;
- state->bookbuf = malloc (state->booklen);
- memcpy (state->bookbuf, header->packet, header->bytes);
- }
+ vorbis_synthesis_headerin (&s->vi, &s->vc, header);
- i++;
- header = &header_codebooks;
+ if (i++ == 1) {
+ s->booklen = header->bytes;
+ s->bookbuf = malloc (s->booklen);
+ memcpy (s->bookbuf, header->packet, header->bytes);
}
}
+
+ header = &header_codebooks;
}
}
}
}
- buffer = ogg_sync_buffer (state->oy, CHUNKSIZE);
- bytes = fread (buffer, 1, CHUNKSIZE, state->in);
+ buffer = ogg_sync_buffer (&s->oy, CHUNKSIZE);
- if (bytes == 0 && i < 2) {
- state->lasterror = "EOF before end of vorbis headers.";
- goto err;
- }
-
- ogg_sync_wrote (state->oy, bytes);
+ bytes = fread (buffer, 1, CHUNKSIZE, s->in);
+ ogg_sync_wrote (&s->oy, bytes);
}
/* Copy the vendor tag */
}
/* Copy the vendor tag */
- s
tate->vendor = strdup (state->vc->
vendor);
+ s
->vendor = strdup (s->vc.
vendor);
/* Headers are done! */
/* Headers are done! */
- return 0;
+ s->opened = true;
+
+ return VCEDIT_ERR_SUCCESS;
err:
err:
- vcedit_clear_internals (state);
+ vcedit_clear_internals (s);
+
+ return ret;
+}
- return -1;
+static int
+write_data (const void *buf, size_t size, size_t nmemb, FILE *stream)
+{
+ while (nmemb > 0) {
+ size_t w;
+
+ w = fwrite (buf, size, nmemb, stream);
+ if (!w && ferror (stream))
+ return 0;
+
+ nmemb -= w;
+ buf += size * w;
+ }
+
+ return 1;
}
}
-int
-vcedit_write (vcedit_state *s
tate
)
+vcedit_error
+vcedit_write (vcedit_state *s)
{
ogg_stream_state streamout;
ogg_packet header_main, header_comments, header_codebooks, op;
{
ogg_stream_state streamout;
ogg_packet header_main, header_comments, header_codebooks, op;
@@
-414,84
+411,77
@@
vcedit_write (vcedit_state *state)
ogg_int64_t granpos = 0;
FILE *out;
char *buffer, tmpfile[PATH_MAX];
ogg_int64_t granpos = 0;
FILE *out;
char *buffer, tmpfile[PATH_MAX];
-
int s, result, bytes, needflush = 0, needout = 0
;
-
size_t tmp
;
+
bool success = false
;
+
int fd, result, bytes, needflush = 0, needout = 0
;
- strcpy (tmpfile, state->filename);
+ if (!s->opened)
+ return VCEDIT_ERR_INVAL;
+
+ strcpy (tmpfile, s->filename);
strcat (tmpfile, ".XXXXXX");
strcat (tmpfile, ".XXXXXX");
- s = mkstemp (tmpfile);
- if (s == -1) {
- state->lasterror = "Error writing stream to output. "
- "Cannot open temporary file.";
- return -1;
- }
+ fd = mkstemp (tmpfile);
+ if (fd == -1)
+ return VCEDIT_ERR_TMPFILE;
- out = fdopen (
s
, "wb");
+ out = fdopen (
fd
, "wb");
if (!out) {
unlink (tmpfile);
if (!out) {
unlink (tmpfile);
- close (s);
- state->lasterror = "Error writing stream to output. "
- "Cannot open temporary file.";
- return -1;
+ close (fd);
+
+ return VCEDIT_ERR_TMPFILE;
}
}
- s
tate->prevW = state->extrapage = state
->eosin = 0;
+ s
->prevW = s->extrapage = s
->eosin = 0;
- header_main.bytes = s
tate
->mainlen;
- header_main.packet = s
tate
->mainbuf;
+ header_main.bytes = s->mainlen;
+ header_main.packet = s->mainbuf;
header_main.b_o_s = 1;
header_main.e_o_s = 0;
header_main.granulepos = 0;
header_main.b_o_s = 1;
header_main.e_o_s = 0;
header_main.granulepos = 0;
- header_codebooks.bytes = s
tate
->booklen;
- header_codebooks.packet = s
tate
->bookbuf;
+ header_codebooks.bytes = s->booklen;
+ header_codebooks.packet = s->bookbuf;
header_codebooks.b_o_s = 0;
header_codebooks.e_o_s = 0;
header_codebooks.granulepos = 0;
header_codebooks.b_o_s = 0;
header_codebooks.e_o_s = 0;
header_codebooks.granulepos = 0;
- ogg_stream_init (&streamout, s
tate
->serial);
+ ogg_stream_init (&streamout, s->serial);
- _commentheader_out (s
tate->vc, state->vendor
, &header_comments);
+ _commentheader_out (s, &header_comments);
ogg_stream_packetin (&streamout, &header_main);
ogg_stream_packetin (&streamout, &header_comments);
ogg_stream_packetin (&streamout, &header_codebooks);
while ((result = ogg_stream_flush (&streamout, &ogout))) {
ogg_stream_packetin (&streamout, &header_main);
ogg_stream_packetin (&streamout, &header_comments);
ogg_stream_packetin (&streamout, &header_codebooks);
while ((result = ogg_stream_flush (&streamout, &ogout))) {
- tmp = fwrite (ogout.header, 1, ogout.header_len, out);
- if (tmp != (size_t) ogout.header_len)
+ if (!write_data (ogout.header, 1, ogout.header_len, out))
goto cleanup;
goto cleanup;
- tmp = fwrite (ogout.body, 1, ogout.body_len, out);
- if (tmp != (size_t) ogout.body_len)
+ if (!write_data (ogout.body, 1, ogout.body_len, out))
goto cleanup;
}
goto cleanup;
}
- while (_fetch_next_packet (s
tate
, &op, &ogin)) {
+ while (_fetch_next_packet (s, &op, &ogin)) {
int size;
int size;
- size = _blocksize (s
tate
, &op);
+ size = _blocksize (s, &op);
granpos += size;
if (needflush) {
if (ogg_stream_flush (&streamout, &ogout)) {
granpos += size;
if (needflush) {
if (ogg_stream_flush (&streamout, &ogout)) {
- tmp = fwrite (ogout.header, 1, ogout.header_len, out);
- if (tmp != (size_t) ogout.header_len)
+ if (!write_data (ogout.header, 1, ogout.header_len, out))
goto cleanup;
goto cleanup;
- tmp = fwrite (ogout.body, 1, ogout.body_len, out);
- if (tmp != (size_t) ogout.body_len)
+ if (!write_data (ogout.body, 1, ogout.body_len, out))
goto cleanup;
}
} else if (needout) {
if (ogg_stream_pageout (&streamout, &ogout)) {
goto cleanup;
}
} else if (needout) {
if (ogg_stream_pageout (&streamout, &ogout)) {
- tmp = fwrite (ogout.header, 1, ogout.header_len, out);
- if (tmp != (size_t) ogout.header_len)
+ if (!write_data (ogout.header, 1, ogout.header_len, out))
goto cleanup;
goto cleanup;
- tmp = fwrite (ogout.body, 1, ogout.body_len, out);
- if (tmp != (size_t) ogout.body_len)
+ if (!write_data (ogout.body, 1, ogout.body_len, out))
goto cleanup;
}
}
goto cleanup;
}
}
@@
-519,71
+509,67
@@
vcedit_write (vcedit_state *state)
streamout.e_o_s = 1;
while (ogg_stream_flush (&streamout, &ogout)) {
streamout.e_o_s = 1;
while (ogg_stream_flush (&streamout, &ogout)) {
- tmp = fwrite (ogout.header, 1, ogout.header_len, out);
- if (tmp != (size_t) ogout.header_len)
+ if (!write_data (ogout.header, 1, ogout.header_len, out))
goto cleanup;
goto cleanup;
- tmp = fwrite (ogout.body, 1, ogout.body_len, out);
- if (tmp != (size_t) ogout.body_len)
+ if (!write_data (ogout.body, 1, ogout.body_len, out))
goto cleanup;
}
goto cleanup;
}
- if (state->extrapage) {
- tmp = fwrite (ogin.header, 1, ogin.header_len, out);
- if (tmp != (size_t) ogin.header_len)
+ if (s->extrapage) {
+ if (!write_data (ogin.header, 1, ogin.header_len, out))
goto cleanup;
goto cleanup;
- tmp = fwrite (ogin.body, 1, ogin.body_len, out);
- if (tmp != (size_t) ogin.body_len)
+ if (!write_data (ogin.body, 1, ogin.body_len, out))
goto cleanup;
}
/* clear it, because not all paths to here do */
goto cleanup;
}
/* clear it, because not all paths to here do */
- s
tate
->eosin = 0;
+ s->eosin = 0;
- while (!state->eosin) { /* We reached eos, not eof */
+ do {
/* We copy the rest of the stream (other logical streams)
* through, a page at a time.
*/
/* We copy the rest of the stream (other logical streams)
* through, a page at a time.
*/
- while (1) {
- result = ogg_sync_pageout (state->oy, &ogout);
+ while ((result = ogg_sync_pageout (&s->oy, &ogout))) {
+ if (result != 1)
+ continue;
- if (!result)
- break;
-
- if (result < 0)
- state->lasterror = "Corrupt or missing data, continuing...";
- else {
- /* Don't bother going through the rest, we can just
- * write the page out now
- */
- tmp = fwrite (ogout.header, 1, ogout.header_len, out);
- if (tmp != (size_t) ogout.header_len)
- goto cleanup;
+ /* Don't bother going through the rest, we can just
+ * write the page out now
+ */
+ if (!write_data (ogout.header, 1, ogout.header_len, out))
+ goto cleanup;
- tmp = fwrite (ogout.body, 1, ogout.body_len, out);
- if (tmp != (size_t) ogout.body_len)
- goto cleanup;
- }
+ if (!write_data (ogout.body, 1, ogout.body_len, out))
+ goto cleanup;
}
}
- buffer = ogg_sync_buffer (
state
->oy, CHUNKSIZE);
- bytes = fread (buffer, 1, CHUNKSIZE, s
tate
->in);
- ogg_sync_wrote (
state
->oy, bytes);
+ buffer = ogg_sync_buffer (
&s
->oy, CHUNKSIZE);
+ bytes = fread (buffer, 1, CHUNKSIZE, s->in);
+ ogg_sync_wrote (
&s
->oy, bytes);
- if (!bytes) {
- state->eosin = 1;
- break;
- }
- }
+ if (ferror (s->in))
+ goto cleanup;
-
fclose (out
);
-
fclose (state->
in);
+
s->eosin = !bytes && feof (s->in
);
+
} while (!s->eos
in);
- unlink (state->filename);
- rename (tmpfile, state->filename);
+ success = true;
cleanup:
cleanup:
+ fclose (s->in);
+
+ if (!success) {
+ unlink (tmpfile);
+ fclose (out);
+ } else {
+ fclose (out);
+ unlink (s->filename);
+ rename (tmpfile, s->filename);
+ chmod (s->filename, s->file_mode);
+ }
+
ogg_stream_clear (&streamout);
/* We don't ogg_packet_clear() this, because the memory was
ogg_stream_clear (&streamout);
/* We don't ogg_packet_clear() this, because the memory was
@@
-591,21
+577,16
@@
cleanup:
*/
_ogg_free (header_comments.packet);
*/
_ogg_free (header_comments.packet);
- free (state->mainbuf);
- free (state->bookbuf);
-
- state->mainbuf = state->bookbuf = NULL;
+ free (s->mainbuf);
+ free (s->bookbuf);
- if (!state->eosin) {
- state->lasterror = "Error writing stream to output. "
- "Output stream may be corrupted or truncated.";
- return -1;
- }
+ s->mainbuf = s->bookbuf = NULL;
- vcedit_clear_internals (state);
+ if (!s->eosin)
+ return VCEDIT_ERR_INVAL;
- state->in = fopen (state->filename, "rb");
- vcedit_open (state);
+ vcedit_clear_internals (s);
- return 0;
+ return (vcedit_open (s) == VCEDIT_ERR_SUCCESS) ?
+ VCEDIT_ERR_SUCCESS : VCEDIT_ERR_REOPEN;
}
}