libgsf r1026 - in trunk: . gsf



Author: mortenw
Date: Thu Dec 25 02:54:22 2008
New Revision: 1026
URL: http://svn.gnome.org/viewvc/libgsf?rev=1026&view=rev

Log:
2008-12-24  Morten Welinder  <terra gnome org>

	* gsf/gsf-input-gio.c (make_local_copy): Use larger buffer.
	(gsf_input_gio_new, gsf_input_gio_new_for_path,
	gsf_input_gio_new_for_uri): Use g_return_val_if_fail as
	appropriate.

	* gsf/gsf-input-stdio.c (make_local_copy): New function.
	(gsf_input_stdio_new, gsf_input_stdio_new_FILE): Use
	make_local_copy for non-regular files.



Modified:
   trunk/ChangeLog
   trunk/NEWS
   trunk/gsf/gsf-input-gio.c
   trunk/gsf/gsf-input-stdio.c

Modified: trunk/NEWS
==============================================================================
--- trunk/NEWS	(original)
+++ trunk/NEWS	Thu Dec 25 02:54:22 2008
@@ -5,6 +5,7 @@
 
 Morten:
 	* Solaris compilation issue.  [#558253]
+	* Handle non-seekable files in gsf_input_stdio_new.  [#154417]
 
 Pedro Fragoso:
 	* Clean up glib includes.  [#564004]

Modified: trunk/gsf/gsf-input-gio.c
==============================================================================
--- trunk/gsf/gsf-input-gio.c	(original)
+++ trunk/gsf/gsf-input-gio.c	Thu Dec 25 02:54:22 2008
@@ -54,15 +54,15 @@
 	GsfOutput *out;
 	GsfInput  *copy;
 	GFileInfo *info;
-	
+
 	out = gsf_output_memory_new ();
 
 	while (1) {
-		guint8 buf[1024];
+		guint8 buf[4096];
 		gssize nread;
-		
+
 		nread = g_input_stream_read (stream, buf, sizeof(buf), NULL, NULL);
-		
+
 		if (nread > 0) {
 			if (!gsf_output_write (out, nread, buf)) {
 				copy = NULL;
@@ -77,24 +77,25 @@
 		}
 	}
 
-	copy = gsf_input_memory_new_clone (gsf_output_memory_get_bytes (GSF_OUTPUT_MEMORY (out)),
-					   gsf_output_size (out));
+	copy = gsf_input_memory_new_clone
+		(gsf_output_memory_get_bytes (GSF_OUTPUT_MEMORY (out)),
+		 gsf_output_size (out));
 
 	if (copy != NULL) {
 		info = g_file_query_info (file, G_FILE_ATTRIBUTE_STANDARD_NAME, 0, NULL, NULL);
 		if (info) {
 			gsf_input_set_name (GSF_INPUT (copy), g_file_info_get_name (info));
-			g_object_unref (G_OBJECT (info));
+			g_object_unref (info);
 		}
 	}
 
  cleanup_and_exit:
 
 	gsf_output_close (out);
-	g_object_unref (G_OBJECT (out));
-	
+	g_object_unref (out);
+
 	g_input_stream_close (stream, NULL, NULL);
-	g_object_unref (G_OBJECT (stream));
+	g_object_unref (stream);
 	return copy;
 }
 
@@ -112,12 +113,7 @@
 	GInputStream *stream;
 	GFileInfo    *info;
 
-	if (file == NULL) {
-		if (err != NULL)
-			*err = g_error_new (gsf_input_error_id (), 0,
-					    "file is NULL");
-		return NULL;
-	}
+	g_return_val_if_fail (file != NULL, NULL);
 
 	stream = (GInputStream *)g_file_read (file, NULL, err);
 	if (stream == NULL)
@@ -127,18 +123,18 @@
 		return make_local_copy (file, stream);
 
 	info = g_file_query_info (file, G_FILE_ATTRIBUTE_STANDARD_SIZE, 0, NULL, NULL);
-	if (!info) 
+	if (!info)
 		return make_local_copy (file, stream);
 
 	input = g_object_new (GSF_INPUT_GIO_TYPE, NULL);
 	if (G_UNLIKELY (NULL == input)) {
 		g_input_stream_close (stream, NULL, NULL);
-		g_object_unref (G_OBJECT (stream));
+		g_object_unref (stream);
 		return NULL;
 	}
-	
+
 	gsf_input_set_size (GSF_INPUT (input), g_file_info_get_size (info));
-	g_object_unref (G_OBJECT (info));
+	g_object_unref (info);
 
 	g_object_ref (G_OBJECT (file));
 
@@ -150,7 +146,7 @@
 	info = g_file_query_info (file, G_FILE_ATTRIBUTE_STANDARD_NAME, 0, NULL, NULL);
 	if (info) {
 		gsf_input_set_name (GSF_INPUT (input), g_file_info_get_name (info));
-		g_object_unref (G_OBJECT (info));
+		g_object_unref (info);
 	}
 
 	return GSF_INPUT (input);
@@ -169,17 +165,12 @@
 	GFile *file;
 	GsfInput *input;
 
-	if (path == NULL) {
-		if (err != NULL)
-			*err = g_error_new (gsf_input_error_id (), 0,
-					    "path is NULL");
-		return NULL;
-	}
+	g_return_val_if_fail (path != NULL, NULL);
 
 	file = g_file_new_for_path (path);
 	input = gsf_input_gio_new (file, err);
-	g_object_unref (G_OBJECT (file));
-	
+	g_object_unref (file);
+
 	return input;
 }
 
@@ -196,17 +187,12 @@
 	GFile *file;
 	GsfInput *input;
 
-	if (uri == NULL) {
-		if (err != NULL)
-			*err = g_error_new (gsf_input_error_id (), 0,
-					    "uri is NULL");
-		return NULL;
-	}
+	g_return_val_if_fail (uri != NULL, NULL);
 
 	file = g_file_new_for_uri (uri);
 	input = gsf_input_gio_new (file, err);
-	g_object_unref (G_OBJECT (file));
-	
+	g_object_unref (file);
+
 	return input;
 }
 
@@ -217,10 +203,10 @@
 	GsfInputGio *input = (GsfInputGio *)obj;
 
 	g_input_stream_close (input->stream, NULL, NULL);
-	g_object_unref (G_OBJECT (input->stream));
+	g_object_unref (input->stream);
 	input->stream = NULL;
 
-	g_object_unref (G_OBJECT (input->file));
+	g_object_unref (input->file);
 	input->file = NULL;
 
 	if (input->buf != NULL) {
@@ -245,11 +231,14 @@
 
 	clone = g_file_dup (src->file);
 	if (clone != NULL) {
-		GsfInput *dst;
+		GsfInput *dst = gsf_input_gio_new (clone, err);
+
+		/*
+		 * gsf_input_gio_new() adds a ref, or fails to create a new
+		 * file.  in any case, we need to unref the clone
+		 */
+	        g_object_unref (clone);
 
-		dst = gsf_input_gio_new (clone, err);
-	        g_object_unref (G_OBJECT (clone)); /* gsf_input_gio_new() adds a ref, or fails to create a new file. 
-						      in any case, we need to unref the clone */
 		return dst;
 	}
 
@@ -257,8 +246,7 @@
 }
 
 static guint8 const *
-gsf_input_gio_read (GsfInput *input, size_t num_bytes,
-		     guint8 *buffer)
+gsf_input_gio_read (GsfInput *input, size_t num_bytes, guint8 *buffer)
 {
 	GsfInputGio *gio = GSF_INPUT_GIO (input);
 	size_t total_read = 0;
@@ -277,9 +265,9 @@
 
 	while (1) {
 		gssize nread;
-		
+
 		nread = g_input_stream_read (gio->stream, (buffer + total_read), (num_bytes - total_read), NULL, NULL);
-		
+
 		if (nread >= 0) {
 			total_read += nread;
 			if ((size_t) total_read == num_bytes) {

Modified: trunk/gsf/gsf-input-stdio.c
==============================================================================
--- trunk/gsf/gsf-input-stdio.c	(original)
+++ trunk/gsf/gsf-input-stdio.c	Thu Dec 25 02:54:22 2008
@@ -24,6 +24,8 @@
 #include <gsf/gsf-input-impl.h>
 #include <gsf/gsf-impl-utils.h>
 #include <gsf/gsf-utils.h>
+#include <gsf/gsf-input-memory.h>
+#include <gsf/gsf-output-memory.h>
 #include <glib/gstdio.h>
 
 #include <stdio.h>
@@ -50,6 +52,58 @@
 	GsfInputClass input_class;
 } GsfInputStdioClass;
 
+static GsfInput *
+make_local_copy (FILE *stream, const char *filename, GError **err)
+{
+	GsfOutput *out;
+	GsfInput *copy = NULL;
+
+	out = gsf_output_memory_new ();
+
+	while (1) {
+		guint8 buf[4096];
+		gssize nread;
+
+		nread = fread (buf, 1, sizeof(buf), stream);
+
+		if (nread > 0) {
+			if (!gsf_output_write (out, nread, buf))
+				goto error;
+		} else if (nread == 0)
+			break;
+		else
+			goto error;
+	}
+
+	copy = gsf_input_memory_new_clone
+		(gsf_output_memory_get_bytes (GSF_OUTPUT_MEMORY (out)),
+		 gsf_output_size (out));
+
+	gsf_output_close (out);
+	g_object_unref (out);
+
+	if (filename)
+		gsf_input_set_name_from_filename (GSF_INPUT (copy), filename);
+
+	return copy;
+
+error:
+	if (err) {
+		char *utf8name = filename
+			? g_filename_display_name (filename)
+			: g_strdup ("?");
+		g_set_error (err, gsf_input_error_id (), 0,
+			     "%s: not a regular file",
+			     utf8name);
+		g_free (utf8name);
+	}
+
+	gsf_output_close (out);
+	g_object_unref (out);
+
+	return NULL;
+}
+
 /**
  * gsf_input_stdio_new :
  * @filename : in utf8.
@@ -69,7 +123,7 @@
 	g_return_val_if_fail (filename != NULL, NULL);
 
 	file = g_fopen (filename, "rb");
-	if (file == NULL || fstat (fileno (file), &st) < 0) {
+	if (file == NULL) {
 		if (err) {
 			int save_errno = errno;
 			char *utf8name = g_filename_display_name (filename);
@@ -80,20 +134,13 @@
 				     utf8name, g_strerror (save_errno));
 			g_free (utf8name);
 		}
-		if (file) fclose (file); /* Just in case.  */
 		return NULL;
 	}
 
-	if (!S_ISREG (st.st_mode)) {
-		if (err) {
-			char *utf8name = g_filename_display_name (filename);
-			g_set_error (err, gsf_input_error_id (), 0,
-				     "%s: not a regular file",
-				     utf8name);
-			g_free (utf8name);
-		}
+	if (fstat (fileno (file), &st) < 0 || !S_ISREG (st.st_mode)) {
+		GsfInput *res = make_local_copy (file, filename, err);
 		fclose (file);
-		return NULL;
+		return res;
 	}
 
 	size = st.st_size;
@@ -120,11 +167,11 @@
  * @file      : an existing stdio FILE *
  * @keep_open : Should @file be closed when the wrapper is closed
  *
- * Assumes ownership of @file.  If @keep_open is true, ownership reverts
- * to caller when the GsfObject is closed.
+ * Assumes ownership of @file when succeeding.  If @keep_open is true,
+ * ownership reverts to caller when the GsfObject is closed.
  *
- * Returns: a new GsfInput wrapper for @file.  Note: the file must be
- * 	seekable, so this will not work for stdin when that is a tty or pipe.
+ * Returns: a new GsfInput wrapper for @file.  Note that if the file is not
+ * 	seekable, this function will make a local copy of the entire file.
  **/
 GsfInput *
 gsf_input_stdio_new_FILE (char const *filename, FILE *file, gboolean keep_open)
@@ -136,11 +183,10 @@
 	g_return_val_if_fail (filename != NULL, NULL);
 	g_return_val_if_fail (file != NULL, NULL);
 
-	if (fstat (fileno (file), &st) < 0)
-		return NULL;
-	if (!S_ISREG (st.st_mode))
-		/* It's not that we really care, but we need st.st_size to be sane.  */
-		return NULL;
+	if (fstat (fileno (file), &st) < 0 || !S_ISREG (st.st_mode)) {
+		return make_local_copy (file, filename, NULL);
+	}
+
 	size = st.st_size;
 
 	stdio = g_object_new (GSF_INPUT_STDIO_TYPE, NULL);



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]