[easytag] Use GFile instead of stdio in vcedit.c, bug 700874
- From: David King <davidk src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [easytag] Use GFile instead of stdio in vcedit.c, bug 700874
- Date: Thu, 23 May 2013 18:47:38 +0000 (UTC)
commit 94b6a68b51347d10e6a5c9a07dc035a3e3ce025c
Author: Abhinav <abhijangda hotmail com>
Date: Thu May 23 23:13:59 2013 +0530
Use GFile instead of stdio in vcedit.c, bug 700874
src/ogg_header.c | 38 +++++---
src/ogg_header.h | 41 ++++++++
src/ogg_tag.c | 92 ++++++++++--------
src/vcedit.c | 291 ++++++++++++++++++++++++++++++++++++++----------------
src/vcedit.h | 15 +---
5 files changed, 327 insertions(+), 150 deletions(-)
---
diff --git a/src/ogg_header.c b/src/ogg_header.c
index 9d86a46..fed435a 100644
--- a/src/ogg_header.c
+++ b/src/ogg_header.c
@@ -18,7 +18,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#include <config.h> // For definition of ENABLE_OGG
+#include "config.h" /* For definition of ENABLE_OGG. */
#ifdef ENABLE_OGG
@@ -46,6 +46,19 @@
* Functions *
*************/
+/*
+ * et_ogg_error_quark:
+ *
+ * To get EtOGGError domain.
+ *
+ * Returns: GQuark for EtOGGError domain
+ */
+GQuark
+et_ogg_error_quark (void)
+{
+ return g_quark_from_static_string ("et-ogg-error-quark");
+}
+
gboolean Ogg_Header_Read_File_Info (gchar *filename, ET_File_Info *ETFileInfo)
{
FILE *file;
@@ -149,7 +162,6 @@ gboolean Ogg_Header_Read_File_Info (gchar *filename, ET_File_Info *ETFileInfo)
gboolean Speex_Header_Read_File_Info (gchar *filename, ET_File_Info *ETFileInfo)
{
- FILE *file;
vcedit_state *state;
SpeexHeader *si;
gchar *encoder_version = NULL;
@@ -159,24 +171,22 @@ gboolean Speex_Header_Read_File_Info (gchar *filename, ET_File_Info *ETFileInfo)
gdouble duration = 0;
gulong filesize;
gchar *filename_utf8;
+ GFile *gfile;
+ GError *error = NULL;
g_return_val_if_fail (filename != NULL && ETFileInfo != NULL, FALSE);
filename_utf8 = filename_to_display(filename);
- if ( (file=fopen(filename,"rb"))==NULL ) // Warning : it is important to open the file in binary mode!
(to get header information under Win32)
- {
- Log_Print(LOG_ERROR,_("Error while opening file: '%s' (%s)."),filename_utf8,g_strerror(errno));
- g_free(filename_utf8);
- return FALSE;
- }
-
-
state = vcedit_new_state(); // Allocate memory for 'state'
- if ( vcedit_open(state,file) < 0 )
+ gfile = g_file_new_for_path (filename);
+ if (!vcedit_open (state, gfile, &error))
{
- Log_Print(LOG_ERROR,_("Error: Failed to open file: '%s' as Vorbis
(%s)."),filename_utf8,vcedit_error(state));
- fclose(file);
+ Log_Print (LOG_ERROR,
+ _("Error: Failed to open file: '%s' as Vorbis (%s)."),
+ filename_utf8, error->message);
+ g_error_free (error);
+ g_object_unref (gfile);
g_free(filename_utf8);
vcedit_clear(state);
return FALSE;
@@ -210,7 +220,7 @@ gboolean Speex_Header_Read_File_Info (gchar *filename, ET_File_Info *ETFileInfo)
ETFileInfo->duration = duration;
vcedit_clear(state);
- fclose(file);
+ g_object_unref (gfile);
g_free(filename_utf8);
return TRUE;
}
diff --git a/src/ogg_header.h b/src/ogg_header.h
index 3662576..c35c36c 100644
--- a/src/ogg_header.h
+++ b/src/ogg_header.h
@@ -30,6 +30,47 @@
* Declarations *
****************/
+/*
+ * Error domain and codes for errors while reading/writing OGG files
+ */
+GQuark et_ogg_error_quark (void);
+
+#define ET_OGG_ERROR et_ogg_error_quark ()
+
+/*
+ * EtOGGError:
+ * @ET_OGG_ERROR_EOS: reached end of logical bitstream
+ * @ET_OGG_ERROR_EOF: reached end of file
+ * @ET_OGG_ERROR_SN: page and state's serial number are unequal
+ * @ET_OGG_ERROR_TRUNC: input truncated or empty
+ * @ET_OGG_ERROR_NOTOGG: input is not ogg bitstream
+ * @ET_OGG_ERROR_PAGE: cannot read first page of ogg bitstream
+ * @ET_OGG_ERROR_HEADER: error reading initial header packet
+ * @ET_OGG_ERROR_INVALID: ogg bitstream doesnot contains Speex or Vorbis data
+ * @ET_OGG_ERROR_CORRUPT: corrupt secondary header
+ * @ET_OGG_ERROR_EXTRA: need to save extra headers
+ * @ET_OGG_ERROR_VORBIS: eof before end of Vorbis headers
+ * @ET_OGG_ERROR_FAILED: corrupt or missing data
+ * @ET_OGG_ERROR_OUTPUT: error writing stream to output
+ *
+ * Errors that can occur when reading OGG files.
+ */
+typedef enum
+{
+ ET_OGG_ERROR_EOS,
+ ET_OGG_ERROR_EOF,
+ ET_OGG_ERROR_SN,
+ ET_OGG_ERROR_TRUNC,
+ ET_OGG_ERROR_NOTOGG,
+ ET_OGG_ERROR_PAGE,
+ ET_OGG_ERROR_HEADER,
+ ET_OGG_ERROR_INVALID,
+ ET_OGG_ERROR_CORRUPT,
+ ET_OGG_ERROR_EXTRA,
+ ET_OGG_ERROR_VORBIS,
+ ET_OGG_ERROR_FAILED,
+ ET_OGG_ERROR_OUTPUT
+} EtOGGError;
/**************
* Prototypes *
diff --git a/src/ogg_tag.c b/src/ogg_tag.c
index d06cc1e..907d887 100644
--- a/src/ogg_tag.c
+++ b/src/ogg_tag.c
@@ -18,7 +18,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#include <config.h> // For definition of ENABLE_OGG
+#include "config.h" // For definition of ENABLE_OGG
#ifdef ENABLE_OGG
@@ -105,7 +105,8 @@
/**************
* Prototypes *
**************/
-static gboolean Ogg_Tag_Write_File (FILE *file_in, gchar *filename_in, vcedit_state *state);
+static gboolean Ogg_Tag_Write_File (GFile *file_in, gchar *filename_in,
+ vcedit_state *state, GError **error);
static gboolean Ogg_Write_Delimetered_Tag (vorbis_comment *vc, const gchar *tag_name, gchar *values);
static gboolean Ogg_Write_Tag (vorbis_comment *vc, const gchar *tag_name, gchar *value);
@@ -123,6 +124,8 @@ static void Ogg_Set_Tag (vorbis_comment *vc, const gchar *tag_name, gchar *value
gboolean Ogg_Tag_Read_File_Tag (gchar *filename, File_Tag *FileTag)
{
FILE *file;
+ GFile *gfile;
+ GError *error = NULL;
vcedit_state *state;
vorbis_comment *vc;
gchar *string = NULL;
@@ -177,12 +180,18 @@ gboolean Ogg_Tag_Read_File_Tag (gchar *filename, File_Tag *FileTag)
}
}
+ fclose(file);
+
state = vcedit_new_state(); // Allocate memory for 'state'
- if ( vcedit_open(state,file) < 0 )
+ gfile = g_file_new_for_path (filename);
+
+ if (!vcedit_open (state, gfile, &error))
{
- Log_Print(LOG_ERROR,_("Error: Failed to open file: '%s' as Vorbis
(%s)."),filename_utf8,vcedit_error(state));
- ogg_error_msg = vcedit_error(state);
- fclose(file);
+ Log_Print (LOG_ERROR,
+ _("Error: Failed to open file: '%s' as Vorbis (%s)."),
+ filename_utf8, error->message);
+ g_error_free (error);
+ g_object_unref (gfile);
g_free(filename_utf8);
vcedit_clear(state);
return FALSE;
@@ -572,7 +581,7 @@ gboolean Ogg_Tag_Read_File_Tag (gchar *filename, File_Tag *FileTag)
}
vcedit_clear(state);
- fclose(file);
+ g_object_unref (gfile);
g_free(filename_utf8);
return TRUE;
@@ -631,6 +640,8 @@ gboolean Ogg_Tag_Write_File_Tag (ET_File *ETFile)
gchar *string;
GList *list;
Picture *pic;
+ GFile *gfile_in;
+ GError *error = NULL;
g_return_val_if_fail (ETFile != NULL && ETFile->FileTag != NULL, FALSE);
@@ -679,12 +690,17 @@ gboolean Ogg_Tag_Write_File_Tag (ET_File *ETFile)
}
}
+ fclose (file_in);
+
state = vcedit_new_state(); // Allocate memory for 'state'
- if ( vcedit_open(state,file_in) < 0 )
- {
- Log_Print(LOG_ERROR,_("Error: Failed to open file: '%s' as Vorbis
(%s)."),filename_utf8,vcedit_error(state));
- ogg_error_msg = vcedit_error(state);
- fclose(file_in);
+ gfile_in = g_file_new_for_path (filename);
+ if (!vcedit_open (state, gfile_in, &error))
+ {
+ Log_Print (LOG_ERROR,
+ _("Error: Failed to open file: '%s' as Vorbis (%s)."),
+ filename_utf8, error->message);
+ g_object_unref (gfile_in);
+ g_error_free (error);
vcedit_clear(state);
return FALSE;
}
@@ -818,12 +834,14 @@ gboolean Ogg_Tag_Write_File_Tag (ET_File *ETFile)
list = list->next;
}
- /* Write tag, and close also 'file_in' in all cases */
- if ( Ogg_Tag_Write_File(file_in,filename,state) == FALSE )
+ /* Write tag to 'gfile_in' in all cases */
+ if (Ogg_Tag_Write_File (gfile_in, filename, state, &error) == FALSE)
{
- ogg_error_msg = vcedit_error(state);
- Log_Print(LOG_ERROR,_("Error: Failed to write comments to file '%s'
(%s)."),filename_utf8,ogg_error_msg == NULL ? "" : ogg_error_msg);
-
+ Log_Print (LOG_ERROR,
+ _("Error: Failed to write comments to file '%s' (%s)."),
+ filename_utf8, error->message);
+ g_error_free (error);
+ g_object_unref (gfile_in);
vcedit_clear(state);
return FALSE;
}else
@@ -834,6 +852,7 @@ gboolean Ogg_Tag_Write_File_Tag (ET_File *ETFile)
vcedit_clear(state);
}
+ g_object_unref (gfile_in);
return TRUE;
}
@@ -843,44 +862,37 @@ gboolean Ogg_Tag_Write_File_Tag (ET_File *ETFile)
* Write tag information to a new temporary file, and rename it the the initial name.
*/
static gboolean
-Ogg_Tag_Write_File (FILE *file_in, gchar *filename_in, vcedit_state *state)
+Ogg_Tag_Write_File (GFile *file_in, gchar *filename_in, vcedit_state *state,
+ GError **error)
{
gchar *filename_out;
- gint file_mkstemp;
- FILE *file_out;
+ GFile *file_out;
+ GFileIOStream *iostream;
gboolean return_code = TRUE;
+ g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
filename_out = g_strdup_printf("%s.XXXXXX",filename_in);
-
- // Function mkstemp() opens also the file!
- if ((file_mkstemp = mkstemp(filename_out)) < 0)
+ file_out = g_file_new_tmp (filename_out, &iostream, error);
+ if (!file_out)
{
- fclose(file_in);
- close(file_mkstemp);
- g_free(filename_out);
- return FALSE;
- }
- close(file_mkstemp);
-
- if ( (file_out=fopen(filename_out,"wb")) == NULL )
- {
- fclose(file_in);
- remove(filename_out);
g_free(filename_out);
return FALSE;
}
+
+ g_object_unref (iostream);
- if (vcedit_write(state,file_out) < 0)
+ if (vcedit_write (state, file_out, error) < 0)
{
- fclose(file_in);
- fclose(file_out);
- remove(filename_out);
+ g_assert (error == NULL || *error != NULL);
+ g_file_delete (file_out, NULL, error);
+ g_object_unref (file_out);
g_free(filename_out);
return FALSE;
}
- fclose(file_in);
- fclose(file_out);
+
+ g_assert (error == NULL || *error == NULL);
+ g_object_unref (file_out);
// Some platforms fail to rename a file if the new name already
// exists, so we need to remove, then rename...
diff --git a/src/vcedit.c b/src/vcedit.c
index e687db4..5162b5f 100644
--- a/src/vcedit.c
+++ b/src/vcedit.c
@@ -9,10 +9,10 @@
* last modified: $Id: vcedit.c,v 1.23 2003/09/03 07:58:05 calc Exp $
*/
-#include <config.h> // For definition of ENABLE_OGG
+#include "config.h" /* For definition of ENABLE_OGG. */
#ifdef ENABLE_OGG
-
+#include <gtk/gtk.h>
#include <glib/gi18n-lib.h>
#include <stdio.h>
#include <stdlib.h>
@@ -22,14 +22,10 @@
#include <vorbis/codec.h>
#include "vcedit.h"
-
+#include "ogg_header.h"
#define CHUNKSIZE 4096
-static int vcedit_open_callbacks(vcedit_state *state, void *in,
- vcedit_read_func read_func,
- vcedit_write_func write_func);
-
vcedit_state *vcedit_new_state(void)
{
vcedit_state *state = malloc(sizeof(vcedit_state));
@@ -39,11 +35,6 @@ vcedit_state *vcedit_new_state(void)
return state;
}
-char *vcedit_error(vcedit_state *state)
-{
- return state->lasterror;
-}
-
vorbis_comment *vcedit_comments(vcedit_state *state)
{
return state->vc;
@@ -51,7 +42,6 @@ vorbis_comment *vcedit_comments(vcedit_state *state)
static void vcedit_clear_internals(vcedit_state *state)
{
- char *tmp;
if(state->vc)
{
vorbis_comment_clear(state->vc);
@@ -77,10 +67,8 @@ static void vcedit_clear_internals(vcedit_state *state)
vorbis_info_clear(state->vi);
free(state->vi);
}
-
- tmp = state->lasterror;
+ g_object_unref (state->in);
memset(state, 0, sizeof(*state));
- state->lasterror = tmp;
}
void vcedit_clear(vcedit_state *state)
@@ -170,11 +158,14 @@ static int _blocksize(vcedit_state *s, ogg_packet *p)
}
static gboolean
-_fetch_next_packet (vcedit_state *s, ogg_packet *p, ogg_page *page)
+_fetch_next_packet (vcedit_state *s, ogg_packet *p, ogg_page *page,
+ GError **error)
{
int result;
char *buffer;
- int bytes;
+ gssize bytes;
+
+ g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
result = ogg_stream_packetout(s->os, p);
@@ -183,26 +174,45 @@ _fetch_next_packet (vcedit_state *s, ogg_packet *p, ogg_page *page)
else
{
if(s->eosin)
+ {
+ g_set_error (error, ET_OGG_ERROR, ET_OGG_ERROR_EOS,
+ "Page reached end of logical bitstream");
+ g_assert (error == NULL || *error != NULL);
return FALSE;
+ }
while(ogg_sync_pageout(s->oy, page) <= 0)
{
buffer = ogg_sync_buffer(s->oy, CHUNKSIZE);
- bytes = s->read(buffer,1, CHUNKSIZE, s->in);
+ bytes = g_input_stream_read (G_INPUT_STREAM (s->in), buffer,
+ CHUNKSIZE, NULL, error);
ogg_sync_wrote(s->oy, bytes);
if(bytes == 0)
+ {
+ g_set_error (error, ET_OGG_ERROR, ET_OGG_ERROR_EOF,
+ "Reached end of file");
+ g_assert (error == NULL || *error != NULL);
return FALSE;
+ }
+ else if (bytes == -1)
+ {
+ g_assert (error == NULL || *error != NULL);
+ return FALSE;
+ }
}
if(ogg_page_eos(page))
s->eosin = 1;
else if(ogg_page_serialno(page) != s->serial)
{
+ g_set_error (error, ET_OGG_ERROR, ET_OGG_ERROR_SN,
+ "Page serial number and state serial number doesn't match");
s->eosin = 1;
s->extrapage = 1;
+ g_assert (error == NULL || *error != NULL);
return FALSE;
}
-
+ g_assert (error == NULL || *error == NULL);
ogg_stream_pagein(s->os, page);
- return _fetch_next_packet(s, p, page);
+ return _fetch_next_packet(s, p, page, error);
}
}
@@ -250,19 +260,12 @@ err_out:
return(1);
}
-int vcedit_open(vcedit_state *state, FILE *in)
+gboolean
+vcedit_open(vcedit_state *state, GFile *file, GError **error)
{
- return vcedit_open_callbacks(state, (void *)in,
- (vcedit_read_func)fread, (vcedit_write_func)fwrite);
-}
-
-static int
-vcedit_open_callbacks(vcedit_state *state, void *in,
- vcedit_read_func read_func, vcedit_write_func write_func)
-{
-
char *buffer;
- int bytes,i;
+ gssize bytes;
+ int i;
int chunks = 0;
int headerpackets = 0;
oggpack_buffer opb;
@@ -271,10 +274,18 @@ vcedit_open_callbacks(vcedit_state *state, void *in,
ogg_packet header_comments;
ogg_packet header_codebooks;
ogg_page og;
+ GFileInputStream *istream;
+
+ g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+
+ istream = g_file_read (file, NULL, error);
+ if (!istream)
+ {
+ g_assert (error == NULL || *error != NULL);
+ return FALSE;
+ }
- state->in = in;
- state->read = read_func;
- state->write = write_func;
+ state->in = g_data_input_stream_new (G_INPUT_STREAM (istream));
state->oy = malloc(sizeof(ogg_sync_state));
ogg_sync_init(state->oy);
@@ -282,7 +293,12 @@ vcedit_open_callbacks(vcedit_state *state, void *in,
while(1)
{
buffer = ogg_sync_buffer(state->oy, CHUNKSIZE);
- bytes = state->read(buffer, 1, CHUNKSIZE, state->in);
+ bytes = g_input_stream_read (G_INPUT_STREAM (state->in), buffer,
+ CHUNKSIZE, NULL, error);
+ if (bytes == -1)
+ {
+ goto err;
+ }
ogg_sync_wrote(state->oy, bytes);
@@ -292,9 +308,11 @@ vcedit_open_callbacks(vcedit_state *state, void *in,
if(chunks++ >= 10) /* Bail if we don't find data in the first 40 kB */
{
if(bytes<CHUNKSIZE)
- state->lasterror = _("Input truncated or empty.");
+ g_set_error (error, ET_OGG_ERROR, ET_OGG_ERROR_TRUNC,
+ "Input truncated or empty");
else
- state->lasterror = _("Input is not an Ogg bitstream.");
+ g_set_error (error, ET_OGG_ERROR, ET_OGG_ERROR_NOTOGG,
+ "Input is not an OGG bitstream");
goto err;
}
}
@@ -312,13 +330,15 @@ vcedit_open_callbacks(vcedit_state *state, void *in,
if(ogg_stream_pagein(state->os, &og) < 0)
{
- state->lasterror = _("Error reading first page of Ogg bitstream.");
+ g_set_error (error, ET_OGG_ERROR, ET_OGG_ERROR_PAGE,
+ "Error reading first page of OGG bitstream");
goto err;
}
if(ogg_stream_packetout(state->os, &header_main) != 1)
{
- state->lasterror = _("Error reading initial header packet.");
+ g_set_error (error, ET_OGG_ERROR, ET_OGG_ERROR_HEADER,
+ "Error reading initial header packet");
goto err;
}
@@ -345,7 +365,8 @@ vcedit_open_callbacks(vcedit_state *state, void *in,
if (state->oggtype == VCEDIT_IS_UNKNOWN)
{
- state->lasterror = _("Ogg bitstream contains neither Speex or Vorbis data.");
+ g_set_error (error, ET_OGG_ERROR, ET_OGG_ERROR_INVALID,
+ "OGG bitstream contains neither Speex nor Vorbis data");
goto err;
}
@@ -378,7 +399,8 @@ vcedit_open_callbacks(vcedit_state *state, void *in,
if(result == 0) break;
if(result == -1)
{
- state->lasterror = _("Corrupt secondary header.");
+ g_set_error (error, ET_OGG_ERROR, ET_OGG_ERROR_CORRUPT,
+ "Corrupt secondary header");
goto err;
}
switch (state->oggtype)
@@ -407,8 +429,9 @@ vcedit_open_callbacks(vcedit_state *state, void *in,
oggpack_readinit(&opb,header->packet,header->bytes);
_speex_unpack_comment(state->vc,&opb);
break;
- default:
- state->lasterror = _("Need to save extra headers"); /* FIXME. */
+ default: /* FIXME. */
+ g_set_error (error, ET_OGG_ERROR, ET_OGG_ERROR_EXTRA,
+ "Need to save extra headers");
goto err;
break;
}
@@ -419,10 +442,17 @@ vcedit_open_callbacks(vcedit_state *state, void *in,
}
buffer = ogg_sync_buffer(state->oy, CHUNKSIZE);
- bytes = state->read(buffer, 1, CHUNKSIZE, state->in);
+ bytes = g_input_stream_read (G_INPUT_STREAM (state->in), buffer,
+ CHUNKSIZE, NULL, error);
+ if (bytes == -1)
+ {
+ goto err;
+ }
+
if(bytes == 0 && i < 2)
{
- state->lasterror = _("EOF before end of Vorbis headers.");
+ g_set_error (error, ET_OGG_ERROR, ET_OGG_ERROR_VORBIS,
+ "EOF before end of Vorbis headers");
goto err;
}
ogg_sync_wrote(state->oy, bytes);
@@ -433,14 +463,20 @@ vcedit_open_callbacks(vcedit_state *state, void *in,
strcpy(state->vendor, state->vc->vendor);
/* Headers are done! */
- return 0;
+ g_assert (error == NULL || *error == NULL);
+
+ g_object_unref (istream);
+ return TRUE;
err:
+ g_assert (error == NULL || *error != NULL);
+ g_object_unref (istream);
vcedit_clear_internals(state);
- return -1;
+ return FALSE;
}
-int vcedit_write(vcedit_state *state, void *out)
+gboolean
+vcedit_write(vcedit_state *state, GFile *file, GError **error)
{
ogg_stream_state streamout;
ogg_packet header_main;
@@ -454,6 +490,21 @@ int vcedit_write(vcedit_state *state, void *out)
char *buffer;
int bytes;
int needflush=0, needout=0;
+ GFileOutputStream *ostream;
+ GDataOutputStream *dostream;
+
+ g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+
+ ostream = g_file_replace (file, NULL, FALSE, G_FILE_CREATE_NONE,
+ NULL, error);
+
+ if (!ostream)
+ {
+ g_assert (error == NULL || *error != NULL);
+ return FALSE;
+ }
+
+ dostream = g_data_output_stream_new (G_OUTPUT_STREAM (ostream));
state->eosin = 0;
state->extrapage = 0;
@@ -482,38 +533,62 @@ int vcedit_write(vcedit_state *state, void *out)
while((result = ogg_stream_flush(&streamout, &ogout)))
{
- if(state->write(ogout.header,1,ogout.header_len, out) !=
- (size_t) ogout.header_len)
+ if (g_output_stream_write (G_OUTPUT_STREAM (dostream), ogout.header,
+ ogout.header_len, NULL, error)
+ != (gssize) ogout.header_len)
+ {
+ g_assert (error == NULL || *error != NULL);
goto cleanup;
- if(state->write(ogout.body,1,ogout.body_len, out) !=
- (size_t) ogout.body_len)
+ }
+
+ if (g_output_stream_write (G_OUTPUT_STREAM (dostream), ogout.body,
+ ogout.body_len, NULL, error)
+ != (gssize) ogout.body_len)
+ {
+ g_assert (error == NULL || *error != NULL);
goto cleanup;
+ }
}
- while(_fetch_next_packet(state, &op, &ogin))
+ while (_fetch_next_packet (state, &op, &ogin, error))
{
if(needflush)
{
- if(ogg_stream_flush(&streamout, &ogout))
+ if (g_output_stream_write (G_OUTPUT_STREAM (dostream), ogout.header,
+ ogout.header_len, NULL, error)
+ != (gssize) ogout.header_len)
{
- if(state->write(ogout.header,1,ogout.header_len,
- out) != (size_t) ogout.header_len)
- goto cleanup;
- if(state->write(ogout.body,1,ogout.body_len,
- out) != (size_t) ogout.body_len)
- goto cleanup;
+ g_assert (error == NULL || *error != NULL);
+ goto cleanup;
+ }
+
+ if (g_output_stream_write (G_OUTPUT_STREAM (dostream), ogout.body,
+ ogout.body_len, NULL, error)
+ != (gssize) ogout.body_len)
+ {
+ g_assert (error == NULL || *error != NULL);
+ goto cleanup;
}
}
else if(needout)
{
if(ogg_stream_pageout(&streamout, &ogout))
{
- if(state->write(ogout.header,1,ogout.header_len,
- out) != (size_t) ogout.header_len)
+ if (g_output_stream_write (G_OUTPUT_STREAM (dostream), ogout.header,
+ ogout.header_len, NULL, error)
+ != (gssize) ogout.header_len)
+ {
+ g_assert (error == NULL || *error != NULL);
goto cleanup;
- if(state->write(ogout.body,1,ogout.body_len,
- out) != (size_t) ogout.body_len)
+ }
+
+ if (g_output_stream_write (G_OUTPUT_STREAM (dostream), ogout.body,
+ ogout.body_len, NULL, error)
+ != (gssize) ogout.body_len)
+ {
+ g_assert (error == NULL || *error != NULL);
goto cleanup;
+ }
}
}
@@ -555,25 +630,48 @@ int vcedit_write(vcedit_state *state, void *out)
}
}
+ if (error == NULL || *error != NULL)
+ {
+ goto cleanup;
+ }
+
streamout.e_o_s = 1;
while(ogg_stream_flush(&streamout, &ogout))
{
- if(state->write(ogout.header,1,ogout.header_len,
- out) != (size_t) ogout.header_len)
+ if (g_output_stream_write (G_OUTPUT_STREAM (dostream), ogout.header,
+ ogout.header_len, NULL, error)
+ != (gssize) ogout.header_len)
+ {
+ g_assert (error == NULL || *error != NULL);
goto cleanup;
- if(state->write(ogout.body,1,ogout.body_len,
- out) != (size_t) ogout.body_len)
+ }
+
+ if (g_output_stream_write (G_OUTPUT_STREAM (dostream), ogout.body,
+ ogout.body_len, NULL, error)
+ != (gssize) ogout.body_len)
+ {
+ g_assert (error == NULL || *error != NULL);
goto cleanup;
+ }
}
if (state->extrapage)
{
- if(state->write(ogin.header,1,ogin.header_len,
- out) != (size_t) ogin.header_len)
+ if (g_output_stream_write (G_OUTPUT_STREAM (dostream), ogout.header,
+ ogout.header_len, NULL, error)
+ != (gssize) ogout.header_len)
+ {
+ g_assert (error == NULL || *error != NULL);
goto cleanup;
- if (state->write(ogin.body,1,ogin.body_len, out) !=
- (size_t) ogin.body_len)
+ }
+
+ if (g_output_stream_write (G_OUTPUT_STREAM (dostream), ogout.body,
+ ogout.body_len, NULL, error)
+ != (gssize) ogout.body_len)
+ {
+ g_assert (error == NULL || *error != NULL);
goto cleanup;
+ }
}
state->eosin=0; /* clear it, because not all paths to here do */
@@ -587,23 +685,43 @@ int vcedit_write(vcedit_state *state, void *out)
if(result==0)
break;
if(result<0)
- state->lasterror = _("Corrupt or missing data, continuing…");
+ {
+ g_set_error (error, ET_OGG_ERROR, ET_OGG_ERROR_FAILED,
+ "Corrupt or missing data, continuing…");
+ goto cleanup;
+ }
else
{
/* Don't bother going through the rest, we can just
* write the page out now */
- if(state->write(ogout.header,1,ogout.header_len,
- out) != (size_t) ogout.header_len) {
+ if (g_output_stream_write (G_OUTPUT_STREAM (dostream), ogout.header,
+ ogout.header_len, NULL, error)
+ != (gssize) ogout.header_len)
+ {
+ g_assert (error == NULL || *error != NULL);
goto cleanup;
}
- if(state->write(ogout.body,1,ogout.body_len, out) !=
- (size_t) ogout.body_len) {
+
+ if (g_output_stream_write (G_OUTPUT_STREAM (dostream), ogout.body,
+ ogout.body_len, NULL, error)
+ != (gssize) ogout.body_len)
+ {
+ g_assert (error == NULL || *error != NULL);
goto cleanup;
}
}
}
buffer = ogg_sync_buffer(state->oy, CHUNKSIZE);
- bytes = state->read(buffer,1, CHUNKSIZE, state->in);
+
+ bytes = g_input_stream_read (G_INPUT_STREAM (state->in), buffer,
+ CHUNKSIZE, NULL, error);
+
+ if (bytes == -1)
+ {
+ g_assert (error == NULL || *error != NULL);
+ goto cleanup;
+ }
+
ogg_sync_wrote(state->oy, bytes);
if(bytes == 0)
{
@@ -621,14 +739,19 @@ cleanup:
free(state->bookbuf);
state->mainbuf = state->bookbuf = NULL;
- if(!state->eosin)
+ if (!state->eosin)
{
- state->lasterror =
- _("Error writing stream to output. "
- "Output stream may be corrupted or truncated.");
- return -1;
+ g_set_error (error, ET_OGG_ERROR, ET_OGG_ERROR_OUTPUT,
+ "Error writing stream to output. Output stream may be corrupted or truncated");
}
+ g_object_unref (ostream);
+ g_object_unref (dostream);
+
+ if (error == NULL || *error != NULL)
+ return FALSE;
+
+ g_assert (error == NULL || *error == NULL);
return 0;
}
diff --git a/src/vcedit.h b/src/vcedit.h
index 3a9e5f9..15321dd 100644
--- a/src/vcedit.h
+++ b/src/vcedit.h
@@ -28,9 +28,6 @@ extern "C" {
#define VCEDIT_IS_SPEEX 1
#define VCEDIT_IS_OGGVORBIS 2
-typedef size_t (*vcedit_read_func)(void *, size_t, size_t, void *);
-typedef size_t (*vcedit_write_func)(const void *, size_t, size_t, void *);
-
typedef struct {
ogg_sync_state *oy;
ogg_stream_state *os;
@@ -42,16 +39,12 @@ typedef struct {
SpeexHeader *si;
#endif
- vcedit_read_func read;
- vcedit_write_func write;
-
- void *in;
+ GDataInputStream *in;
long serial;
unsigned char *mainbuf;
unsigned char *bookbuf;
int mainlen;
int booklen;
- char *lasterror;
char *vendor;
int prevW;
int extrapage;
@@ -61,13 +54,11 @@ typedef struct {
extern vcedit_state *vcedit_new_state(void);
extern void vcedit_clear(vcedit_state *state);
extern vorbis_comment *vcedit_comments(vcedit_state *state);
-extern int vcedit_open(vcedit_state *state, FILE *in);
-extern int vcedit_write(vcedit_state *state, void *out);
-extern char *vcedit_error(vcedit_state *state);
+extern int vcedit_open(vcedit_state *state, GFile *in, GError **error);
+extern int vcedit_write(vcedit_state *state, GFile *file, GError **error);
#ifdef __cplusplus
}
#endif
#endif /* __VCEDIT_H */
-
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]