[tracker/miner-extractor-ipc: 4/4] tracker-extract, miners/fs: Allow array of uris/mimes in extractor IPC



commit cb58bfc4024a351043d179066b25c8db57fc75fc
Author: Philip Van Hoof <philip codeminded be>
Date:   Thu Feb 24 14:41:56 2011 +0100

    tracker-extract, miners/fs: Allow array of uris/mimes in extractor IPC
    
    We don't use it yet in miner-fs, miner-fs just passes one uri/mime
    although tracker-extract can with this commit accept multiple. In
    next commit we'll make miner-fs pass multiple uri/mime combos.

 src/miners/fs/tracker-miner-files.c   |   69 ++++++++++---
 src/tracker-extract/tracker-extract.c |  169 ++++++++++++++++++++++-----------
 2 files changed, 167 insertions(+), 71 deletions(-)
---
diff --git a/src/miners/fs/tracker-miner-files.c b/src/miners/fs/tracker-miner-files.c
index bac1e9b..9ed07f5 100644
--- a/src/miners/fs/tracker-miner-files.c
+++ b/src/miners/fs/tracker-miner-files.c
@@ -2050,42 +2050,71 @@ extractor_skip_embedded_metadata_idle (gpointer user_data)
 	return FALSE;
 }
 
+static guint32
+read_uint32 (const guint8 *data)
+{
+	return data[0] << 24 |
+	       data[1] << 16 |
+	       data[2] << 8 |
+	       data[3];
+}
+
 static void
 get_metadata_fast_async_callback (SendAndSpliceData *data)
 {
 	if (!data->error) {
-		void *buffer;
+		const gchar *preupdate = NULL;
+		const gchar *sparql = NULL;
+		const gchar *buffer;
 		gssize buffer_size;
 		gsize preupdate_length;
 		GError *error = NULL;
-		const gchar *preupdate = NULL;
-		const gchar *sparql = NULL;
+		gint32 code;
 
 		buffer = g_memory_output_stream_get_data (G_MEMORY_OUTPUT_STREAM (data->output_stream));
 		buffer_size = g_memory_output_stream_get_data_size (G_MEMORY_OUTPUT_STREAM (data->output_stream));
 
 		if (buffer_size == 0) {
-			(* data->callback) (NULL, NULL, NULL, data->user_data);
+			error = g_error_new_literal (miner_files_error_quark,
+			                             0,
+			                             "Invalid data received from GetMetadataFast");
 		} else {
-			preupdate = buffer;
-			preupdate_length = strnlen (preupdate, buffer_size);
+			code = read_uint32 (buffer);
+
+			if (code >= 0) {
+
+				/* This still works atm because we still work one by one at
+				 * flush_extract_queue_shared. We need to read only one result,
+				 * no need for a loop yet. */
 
-			if (preupdate_length < buffer_size && preupdate[buffer_size - 1] == '\0') {
-				/* sparql is stored just after preupdate in the original buffer */
-				sparql = preupdate + preupdate_length + 1;
+				preupdate = buffer + 4;
+				preupdate_length = strnlen (preupdate, buffer_size);
+
+				if (preupdate_length < buffer_size && preupdate[buffer_size - 1] == '\0') {
+					/* sparql is stored just after preupdate in the original buffer */
+					sparql = preupdate + preupdate_length + 1;
+				} else {
+					preupdate = NULL;
+					error = g_error_new_literal (miner_files_error_quark,
+					                             0,
+					                             "Invalid data received from GetMetadataFast");
+				}
 			} else {
-				preupdate = NULL;
+				const gchar *error_message;
+
+				error_message = buffer + 4;
 				error = g_error_new_literal (miner_files_error_quark,
 				                             0,
-				                             "Invalid data received from GetMetadataFast");
+				                             error_message);
 			}
-
-			(* data->callback) (preupdate, sparql, error, data->user_data);
 		}
 
+		(* data->callback) (preupdate, sparql, error, data->user_data);
+
 		g_clear_error (&error);
 
 	} else {
+		/* D-Bus or request-wide error */
 		(* data->callback) (NULL, NULL, data->error, data->user_data);
 	}
 
@@ -2176,6 +2205,8 @@ get_metadata_fast_async (GDBusConnection *connection,
 	GDBusMessage *message;
 	GUnixFDList *fd_list;
 	int pipefd[2];
+	const gchar *uris[2];
+	const gchar *mime_types[2];
 
 	g_return_if_fail (connection);
 	g_return_if_fail (uri);
@@ -2194,9 +2225,15 @@ get_metadata_fast_async (GDBusConnection *connection,
 
 	fd_list = g_unix_fd_list_new ();
 
-	g_dbus_message_set_body (message, g_variant_new ("(ssh)",
-	                                                 uri,
-	                                                 mime_type,
+	uris[0] = uri;
+	uris[1] = NULL;
+
+	mime_types[0] = mime_type;
+	mime_types[1] = NULL;
+
+	g_dbus_message_set_body (message, g_variant_new ("(^as^ash)",
+	                                                 uris,
+	                                                 mime_types,
 	                                                 g_unix_fd_list_append (fd_list,
 	                                                                        pipefd[1],
 	                                                                        NULL)));
diff --git a/src/tracker-extract/tracker-extract.c b/src/tracker-extract/tracker-extract.c
index dd0cee3..7bed431 100644
--- a/src/tracker-extract/tracker-extract.c
+++ b/src/tracker-extract/tracker-extract.c
@@ -61,8 +61,8 @@ static const gchar introspection_xml[] =
   "      <arg type='s' name='embedded' direction='out' />"
   "    </method>"
   "    <method name='GetMetadataFast'>"
-  "      <arg type='s' name='uri' direction='in' />"
-  "      <arg type='s' name='mime' direction='in' />"
+  "      <arg type='as' name='uri' direction='in' />"
+  "      <arg type='as' name='mime' direction='in' />"
   "      <arg type='h' name='fd' direction='in' />"
   "    </method>"
   "  </interface>"
@@ -772,30 +772,25 @@ handle_method_call_get_metadata_fast (TrackerExtract        *object,
 	TrackerDBusRequest *request;
 	TrackerExtractPrivate *priv;
 	GDBusMessage *reply;
-	const gchar *uri, *mime;
+	gchar **uris = NULL, **mimes = NULL;
 	int fd, index_fd;
-	GOutputStream *unix_output_stream;
+	GOutputStream *unix_output_stream = NULL;
 	GOutputStream *buffered_output_stream;
 	GDataOutputStream *data_output_stream;
 	GError *error = NULL;
-	TrackerSparqlBuilder *sparql, *preupdate;
-	gboolean extracted = FALSE;
 	GDBusMessage *method_message;
 	GDBusConnection *connection;
 	GUnixFDList *fd_list;
+	guint i;
 
 	connection = g_dbus_method_invocation_get_connection (invocation);
 	method_message = g_dbus_method_invocation_get_message (invocation);
 
-	g_variant_get (parameters, "(&s&sh)", &uri, &mime, &index_fd);
+	g_variant_get (parameters, "(^a&s^a&sh)", &uris, &mimes, &index_fd);
 
 	fd_list = g_dbus_message_get_unix_fd_list (method_message);
 
-	request = tracker_g_dbus_request_begin (invocation,
-	                                        "%s(uri:'%s', mime:%s)",
-	                                        __FUNCTION__,
-	                                        uri,
-	                                        mime);
+	request = tracker_g_dbus_request_begin (invocation, "%s", __FUNCTION__);
 
 	if ((fd = g_unix_fd_list_get (fd_list, index_fd, &error)) == -1) {
 		tracker_dbus_request_end (request, error);
@@ -806,8 +801,7 @@ handle_method_call_get_metadata_fast (TrackerExtract        *object,
 		goto bail_out;
 	}
 
-	tracker_dbus_request_debug (request,
-	                            "  Resetting shutdown timeout");
+	tracker_dbus_request_debug (request, "  Resetting shutdown timeout");
 
 	priv = TRACKER_EXTRACT_GET_PRIVATE (object);
 
@@ -816,83 +810,148 @@ handle_method_call_get_metadata_fast (TrackerExtract        *object,
 		alarm (MAX_EXTRACT_TIME);
 	}
 
-	extracted = get_file_metadata (object, request, NULL, uri, mime, &preupdate, &sparql);
+	unix_output_stream = g_unix_output_stream_new (fd, TRUE);
+	buffered_output_stream = g_buffered_output_stream_new_sized (unix_output_stream,
+	                                                             64*1024);
+	data_output_stream = g_data_output_stream_new (buffered_output_stream);
+	g_data_output_stream_set_byte_order (G_DATA_OUTPUT_STREAM (data_output_stream),
+	                                     G_DATA_STREAM_BYTE_ORDER_HOST_ENDIAN);
 
-	if (extracted) {
-		unix_output_stream = g_unix_output_stream_new (fd, TRUE);
-		buffered_output_stream = g_buffered_output_stream_new_sized (unix_output_stream,
-		                                                             64*1024);
-		data_output_stream = g_data_output_stream_new (buffered_output_stream);
-		g_data_output_stream_set_byte_order (G_DATA_OUTPUT_STREAM (data_output_stream),
-		                                     G_DATA_STREAM_BYTE_ORDER_HOST_ENDIAN);
+	for (i = 0; uris[i] != NULL && mimes[i] != NULL && error == NULL; i++) {
+		gboolean extracted = FALSE;
+		const gchar *uri = (const gchar *) uris[i];
+		const gchar *mime = (const gchar *) mimes[i];
+		TrackerSparqlBuilder *sparql, *preupdate;
 
-		if (tracker_sparql_builder_get_length (sparql) > 0) {
-			const gchar *preupdate_str = NULL;
+		extracted = get_file_metadata (object, request, NULL, uri, mime, &preupdate, &sparql);
 
-			if (tracker_sparql_builder_get_length (preupdate) > 0) {
-				preupdate_str = tracker_sparql_builder_get_result (preupdate);
-			}
+		if (extracted) {
+			gint32 len = tracker_sparql_builder_get_length (sparql);
 
-			g_data_output_stream_put_string (data_output_stream,
-			                                 preupdate_str ? preupdate_str : "",
+			/* Anything >= 0 is error-free reply, 0 just means no metadata
+			 * (which isn't an error) */
+
+			g_data_output_stream_put_int32  (data_output_stream,
+			                                 len,
 			                                 NULL,
 			                                 &error);
 
-			if (!error) {
+			if (error) {
+				break;
+			}
+
+			if (len > 0) {
+				const gchar *preupdate_str = NULL;
+
+				if (tracker_sparql_builder_get_length (preupdate) > 0) {
+					preupdate_str = tracker_sparql_builder_get_result (preupdate);
+				}
+
+				g_data_output_stream_put_string (data_output_stream,
+				                                 preupdate_str ? preupdate_str : "",
+				                                 NULL,
+				                                 &error);
+
+				if (error) {
+					break;
+				}
+
 				g_data_output_stream_put_byte (data_output_stream,
 				                               0,
 				                               NULL,
 				                               &error);
-			}
 
-			if (!error) {
+				if (error) {
+					break;
+				}
+
 				g_data_output_stream_put_string (data_output_stream,
 				                                 tracker_sparql_builder_get_result (sparql),
 				                                 NULL,
 				                                 &error);
-			}
 
-			if (!error) {
+				if (error) {
+					break;
+				}
+
 				g_data_output_stream_put_byte (data_output_stream,
 				                               0,
 				                               NULL,
 				                               &error);
+
+				if (error) {
+					break;
+				}
 			}
-		}
 
-		g_object_unref (sparql);
-		g_object_unref (preupdate);
-		g_object_unref (data_output_stream);
-		g_object_unref (buffered_output_stream);
-		g_object_unref (unix_output_stream);
-
-		if (error) {
-			tracker_dbus_request_end (request, error);
-			reply = g_dbus_message_new_method_error_literal (method_message,
-			                                                 TRACKER_EXTRACT_SERVICE ".GetMetadataFastError",
-			                                                 error->message);
-			g_error_free (error);
+			g_object_unref (sparql);
+			g_object_unref (preupdate);
+
 		} else {
-			tracker_dbus_request_end (request, NULL);
-			reply = g_dbus_message_new_method_reply (method_message);
+			GError *internal_error;
+
+			/* Anything < 0 is error reply, error's message follows */
+			g_data_output_stream_put_int32  (data_output_stream,
+			                                 -1,
+			                                 NULL,
+			                                 &error);
+
+			if (error) {
+				break;
+			}
+
+			internal_error = g_error_new (TRACKER_DBUS_ERROR, 0,
+			                              "Could not get any metadata for uri:'%s' and mime:'%s'",
+			                              uri, mime);
+			g_data_output_stream_put_string (data_output_stream,
+			                                 internal_error->message,
+			                                 NULL,
+			                                 &error);
+			g_error_free (internal_error);
+
+			if (error) {
+				break;
+			}
+
+			g_data_output_stream_put_byte (data_output_stream,
+			                               0,
+			                               NULL,
+			                               &error);
+
+			if (error) {
+				break;
+			}
 		}
-	} else {
-		error = g_error_new (TRACKER_DBUS_ERROR, 0,
-		                     "Could not get any metadata for uri:'%s' and mime:'%s'", uri, mime);
+	}
+
+	g_object_unref (data_output_stream);
+	g_object_unref (buffered_output_stream);
+	g_object_unref (unix_output_stream);
+
+bail_out:
+
+	if (!unix_output_stream) {
+		close (fd);
+	}
+
+	if (error) {
 		tracker_dbus_request_end (request, error);
 		reply = g_dbus_message_new_method_error_literal (method_message,
 		                                                 TRACKER_EXTRACT_SERVICE ".GetMetadataFastError",
 		                                                 error->message);
 		g_error_free (error);
-		close (fd);
+	} else {
+		tracker_dbus_request_end (request, NULL);
+		reply = g_dbus_message_new_method_reply (method_message);
 	}
 
-bail_out:
-
 	g_dbus_connection_send_message (connection, reply,
 	                                G_DBUS_SEND_MESSAGE_FLAGS_NONE,
 	                                NULL, NULL);
 
+	g_free (uris);
+	g_free (mimes);
+
 	g_object_unref (fd_list);
 	g_object_unref (reply);
 



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