? FSQ-child-indexable.diff
? FSQ-hack.diff
? FSQfix-archive-filter.diff
? archive-filter-and-indexable-fix.diff
? archive-filter.diff
? filter-archive_plus-indexable-fix.diff
? lastword-fix.diff
? patch
? Filters/FilterArchive.cs
? Filters/FilterVHDL.cs
? beagled/SUSE-9.3-DVD5-GM-DVD2.iso.prozilla
? beagled/index-helper-command-line
? beagled/test
? beagled/EvolutionDataServerQueryable/EvolutionCalendarQueryable.cs
Index: BeagleClient/Indexable.cs
===================================================================
RCS file: /cvs/gnome/beagle/BeagleClient/Indexable.cs,v
retrieving revision 1.34
diff -u -p -r1.34 Indexable.cs
--- BeagleClient/Indexable.cs	29 Aug 2005 05:34:01 -0000	1.34
+++ BeagleClient/Indexable.cs	1 Sep 2005 18:24:03 -0000
@@ -298,8 +298,17 @@ namespace Beagle {
 		{
 			if (NoContent)
 				return null;
-
-			if (textReader == null)
+			
+			// If we don't have a textReader or
+			// a binary_stream, then try to get it from
+			// the URI. This way we can avoid returning
+			// a TextReader instead of a Stream for 
+			// any binary-content.
+			// Ex: Child indexables of FilterArchive set
+			// binary streams and when TextReader is returned
+			// the "binary" contents don't get indexed.
+			if (textReader == null &&
+			    binary_stream == null)
 				textReader = ReaderFromUri (ContentUri);
 
 			return textReader;
@@ -315,7 +324,10 @@ namespace Beagle {
 			if (NoContent)
 				return null;
 
-			if (hotTextReader == null)
+			// Return a hotTextReader, iff a
+			// textReader is present.
+			if (hotTextReader == null &&
+			    textReader != null)
 				hotTextReader = ReaderFromUri (HotContentUri);
 			return hotTextReader;
 		}
@@ -330,7 +342,11 @@ namespace Beagle {
 			if (NoContent)
 				return null;
 
-			if (binary_stream == null)
+			// Try to generate a Stream from the ContentUri,
+			// iff textReader is null.
+			// See GetTextReader () for a more-detailed-comment. ;-)
+			if (binary_stream == null &&
+			    textReader == null)
 				binary_stream = StreamFromUri (ContentUri);
 
 			return binary_stream;
@@ -483,6 +499,9 @@ namespace Beagle {
 				if (read > 0)
 					bufferedStream.Write (buffer, 0, read);
 			} while (read > 0);
+
+			// Reset the position to point to the start of the stream
+			stream.Seek (0, SeekOrigin.Begin);
 
 			bufferedStream.Close ();
 
Index: Filters/Makefile.am
===================================================================
RCS file: /cvs/gnome/beagle/Filters/Makefile.am,v
retrieving revision 1.47
diff -u -p -r1.47 Makefile.am
--- Filters/Makefile.am	29 Aug 2005 20:09:36 -0000	1.47
+++ Filters/Makefile.am	1 Sep 2005 18:24:03 -0000
@@ -53,7 +53,8 @@ CSFILES = 				\
 	$(srcdir)/FilterDesktop.cs	\
 	$(srcdir)/FilterDirectory.cs	\
 	$(srcdir)/FilterMail.cs		\
-	$(srcdir)/FilterMusic.cs
+	$(srcdir)/FilterMusic.cs	\
+	$(srcdir)/FilterArchive.cs
 
 if ENABLE_GSF_SHARP
 CSFILES += 				\
Index: Util/Archive.cs
===================================================================
RCS file: /cvs/gnome/beagle/Util/Archive.cs,v
retrieving revision 1.2
diff -u -p -r1.2 Archive.cs
--- Util/Archive.cs	24 Jan 2005 04:38:49 -0000	1.2
+++ Util/Archive.cs	1 Sep 2005 18:24:03 -0000
@@ -38,12 +38,115 @@ using ICSharpCode.SharpZipLib.Tar;
 
 namespace Beagle.Util {
 	
+	public class ArchiveEntry {
+		private string name;
+		private long size;
+		private string mimetype;
+		private bool is_directory;
+		private DateTime modified;
+		private MemoryStream stream;
+		private string uri;
+		private string comment;
+		
+		public ArchiveEntry ()
+		{
+			name = null;
+			size = 0;
+			mimetype = null;
+			is_directory = false;
+			modified = new System.DateTime (1970, 1, 1);
+			stream = null;
+			comment = null;
+		}
+
+		public string Name {
+			get {
+				return name;
+			}
+
+			set {
+				name = value;
+			}
+		}
+
+		public string MimeType {
+			get {
+				return mimetype;
+			}
+
+			set {
+				mimetype = value;
+			}
+		}
+
+                public System.DateTime Modified {
+                        get {
+                                return modified;
+                        }
+
+                        set {
+                                modified = value;
+                        }
+                }
+
+                public long Size {
+                        get {
+                                return size;
+                        }
+
+                        set {
+                                size = value;
+                        }
+                }
+
+                public bool IsDirectory {
+                        get {
+                                return is_directory;
+                        }
+
+                        set {
+                                is_directory = value;
+                        }
+                }
+
+		public MemoryStream DataStream {
+			get {
+				return stream;
+			}
+
+			set {
+				stream = value;
+			}
+		}
+
+		public string Uri {
+			get {
+				return uri;
+			}
+
+			set {
+				uri = value;
+			}
+		}
+		
+		public string Comment {
+			get {
+				return comment;
+			}
+			
+			set {
+				comment = value;
+			}
+		}
+	}
+
 	public class Archive : Stream
 	{
-		Stream baseStream;
+		Stream baseStream = null;
 		string uri;
 		string method;
-		delegate string GetNextEntryType ();
+
+		delegate ArchiveEntry GetNextEntryType ();
 		GetNextEntryType getNextEntry;
 		bool first = true;
 
@@ -51,6 +154,19 @@ namespace Beagle.Util {
 			this.uri = StringFu.PathToQuotedFileUri (filename);
 			baseStream = new FileStream (filename,
 						     FileMode.Open);
+			Init (baseStream, mimeType);
+
+		}
+		
+		public Archive (Stream stream, string mimeType) {
+
+			baseStream = stream;
+			
+			Init (baseStream, mimeType);
+		}
+
+		private void Init (Stream stream, string mimeType) {
+
 			switch (mimeType) {
 			case "application/zip":
 				baseStream = new ZipInputStream (baseStream);
@@ -89,35 +205,92 @@ namespace Beagle.Util {
 			}
 		}
 
-		/* Returns the URI of the next string. */
-		public string GetNextEntry () {
-			return getNextEntry();
+		public string GetNextEntrySingleAsUri () {
+			if (first) {
+				first = false;
+				return uri + method;
+			} else
+				return null;
+		}
+
+		/* Returns stream of the next entry */
+		public ArchiveEntry GetNextEntry () 
+		{
+			return getNextEntry ();
 		}
 
-		public string GetNextEntryZip () {
+		private Stream GetEntryData (int size)
+		{			
+			const int BUFFER_SIZE = 8192; // 8KB
+			byte[] data = new byte [BUFFER_SIZE];
+			int bytesRead = 0;
+			MemoryStream ms = new MemoryStream ();
+
+			do {
+				bytesRead = baseStream.Read (data, 0, BUFFER_SIZE);
+				ms.Write (data, 0, bytesRead);
+			} while (bytesRead > 0);
+			
+			ms.Seek (0, SeekOrigin.Begin);
+			return ms;
+		}
+
+		public ArchiveEntry GetNextEntryZip () {
+			MemoryStream ms = null;
+			ArchiveEntry a_entry = null;
+
 			ZipInputStream inputStream = baseStream as ZipInputStream;
 			ZipEntry entry = inputStream.GetNextEntry();
-			if (entry != null)
-				return uri + method + entry.Name;
-			else
-				return null;
+			if (entry != null) {
+				ms = GetEntryData ((int)entry.Size) as MemoryStream;
+				a_entry = new ArchiveEntry ();
+				a_entry.Name = entry.Name;
+				a_entry.Uri = uri + method + entry.Name;
+				a_entry.Size = entry.Size;
+				a_entry.Modified  = entry.DateTime;
+				a_entry.IsDirectory = entry.IsDirectory;
+				a_entry.DataStream = ms;
+				if (!entry.IsDirectory)
+					a_entry.MimeType = Beagle.Util.VFS.Mime.GetMimeTypeFromData (ms.GetBuffer (),
+												     (int)ms.Length,
+												     entry.Name);
+				else
+					a_entry.MimeType = "inode/directory";
+				a_entry.Comment = entry.Comment;
+			}
+			return a_entry;
 		}
 
-		public string GetNextEntrySingle () {
+		public ArchiveEntry GetNextEntrySingle () {
 			if (first) {
 				first = false;
-				return uri + method;
+				return null;
 			} else
 				return null;
 		}
 
-		public string GetNextEntryTar () {
+		public ArchiveEntry GetNextEntryTar () {
+			MemoryStream ms = null;
+			ArchiveEntry a_entry = null;
 			TarInputStream inputStream = baseStream as TarInputStream;
 			TarEntry entry = inputStream.GetNextEntry();
-			if (entry != null)
-				return uri + method + entry.Name;
-			else
-				return null;
+			if (entry != null) {
+				ms = GetEntryData ((int)entry.Size) as MemoryStream;
+				a_entry = new ArchiveEntry ();
+				a_entry.Name = entry.Name;
+				a_entry.Uri = uri + method + entry.Name;
+				a_entry.Size = entry.Size;
+				a_entry.Modified  = entry.ModTime;
+				a_entry.IsDirectory = entry.IsDirectory;
+				a_entry.DataStream = ms;
+				if (!entry.IsDirectory)
+					a_entry.MimeType = Beagle.Util.VFS.Mime.GetMimeTypeFromData (ms.GetBuffer (),
+												     (int)ms.Length,
+												     entry.Name);
+				else
+					a_entry.MimeType = "inode/directory";
+			}
+			return a_entry;
 		}
 
 		public override int Read (byte[] buffer, int offset, int length) {
@@ -163,9 +336,6 @@ namespace Beagle.Util {
 		}
 		public override long Length {
 			get {
-				throw new System.NotSupportedException();
-			}
-			set {
 				throw new System.NotSupportedException();
 			}
 		}
Index: Util/Makefile.am
===================================================================
RCS file: /cvs/gnome/beagle/Util/Makefile.am,v
retrieving revision 1.70
diff -u -p -r1.70 Makefile.am
--- Util/Makefile.am	29 Aug 2005 21:24:31 -0000	1.70
+++ Util/Makefile.am	1 Sep 2005 18:24:03 -0000
@@ -88,7 +88,8 @@ CSFILES = 			        	\
 	$(srcdir)/UnixListener.cs		\
 	$(srcdir)/UriFu.cs			\
 	$(srcdir)/Vfs.cs                        \
-	$(srcdir)/XKeybinder.cs
+	$(srcdir)/XKeybinder.cs			\
+	$(srcdir)/Archive.cs
 
 if HAS_LIBCHM 
 CSFILES += 					\
@@ -99,7 +100,8 @@ ASSEMBLIES =					\
 	$(BEAGLE_UI_LIBS)			\
 	-r:System.Web.Services			\
 	-r:Mono.Data.SqliteClient		\
-	-r:Mono.Posix
+	-r:Mono.Posix				\
+	-r:ICSharpCode.SharpZipLib.dll
 
 if ENABLE_GALAGO
 CSFILES +=					\
Index: beagled/Filter.cs
===================================================================
RCS file: /cvs/gnome/beagle/beagled/Filter.cs,v
retrieving revision 1.33
diff -u -p -r1.33 Filter.cs
--- beagled/Filter.cs	27 Jul 2005 15:42:47 -0000	1.33
+++ beagled/Filter.cs	1 Sep 2005 18:24:04 -0000
@@ -559,14 +559,15 @@ namespace Beagle.Daemon {
 
 			if (tempFile != null)
 				File.Delete (tempFile);
-
-			if (currentInfo != null && this.DeleteContent) {
-				try {
-					currentInfo.Delete ();
-				} catch (Exception e) {
-					Logger.Log.Debug ("Caught exception trying to delete {0} in filter '{1}'",
-							  currentInfo.FullName, Name);
-					Logger.Log.Debug (e);					
+			else {
+				if (currentInfo != null && this.DeleteContent) {
+					try {
+						currentInfo.Delete ();
+					} catch (Exception e) {
+						Logger.Log.Debug ("Caught exception trying to delete {0} in filter '{1}'",
+								  currentInfo.FullName, Name);
+						Logger.Log.Debug (e);					
+					}
 				}
 			}
 		}
--- /dev/null	2005-03-19 12:36:14.000000000 -0700
+++ Filters/FilterArchive.cs	2005-09-01 17:06:36.000000000 -0600
@@ -0,0 +1,120 @@
+//
+// FilterArchive.cs
+//
+// Copyright (C) 2004-2005 Novell, Inc.
+//
+//
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+using System.Collections;
+using System.IO;
+
+using Beagle;
+using Beagle.Daemon;
+using Beagle.Util;
+
+namespace Beagle.Filters {
+
+	public class FilterArchive : Beagle.Daemon.Filter, IDisposable {
+
+		Archive archive = null;
+		ArchiveHandler tarHandler = null;
+
+		public FilterArchive ()
+		{
+			AddSupportedFlavor (FilterFlavor.NewFromMimeType ("application/zip"));
+			AddSupportedFlavor (FilterFlavor.NewFromMimeType ("application/x-bzip-compressed-tar"));
+			AddSupportedFlavor (FilterFlavor.NewFromMimeType ("application/x-compressed-tar"));
+			AddSupportedFlavor (FilterFlavor.NewFromMimeType ("application/x-tar"));
+			//AddSupportedFlavor (FilterFlavor.NewFromMimeType ("application/x-gzip"));
+			//AddSupportedFlavor (FilterFlavor.NewFromMimeType ("application/x-bzip"));
+		}
+		
+		protected override void DoOpen (FileInfo info)
+		{
+			archive = new Archive (Stream, MimeType);
+		}
+		
+		protected override void DoPullProperties ()
+		{
+			// Fetch the archive properties.
+		}
+
+		protected override void DoPullSetup ()
+		{
+			this.tarHandler = new ArchiveHandler (this);
+			this.tarHandler.OnEachEntry (archive);
+
+			AddChildIndexables (this.tarHandler.ChildIndexables);
+		}
+		
+		protected override void DoClose () 
+		{
+			Dispose ();
+		}
+
+		public void Dispose ()
+		{
+			if (this.archive != null)
+				archive.Close ();
+		}
+
+		private class ArchiveHandler {
+			private Beagle.Daemon.Filter filter;
+			private ArrayList child_indexables = new ArrayList ();
+			private int count = 0; // entries handled so far
+
+			public ArchiveHandler (Beagle.Daemon.Filter filter)
+			{
+				this.filter = filter;
+			}
+
+			public void OnEachEntry (Beagle.Util.Archive archive)
+			{
+				ArchiveEntry a_entry = null;
+
+				while ((a_entry = archive.GetNextEntry ()) != null) {
+					string sub_uri = this.filter.Uri.ToString () + "#" + a_entry.Uri;
+					Indexable child = new Indexable (new Uri (sub_uri));
+
+					child.CacheContent = false;
+					child.MimeType = a_entry.MimeType;
+
+					//Console.WriteLine ("Name: {0}, MimeType: {1}", sub_uri, child.MimeType);
+
+					if (a_entry.Comment != null)
+						child.AddProperty (Property.New ("fixme:comment", a_entry.Comment));
+					child.AddProperty (Property.New ("fixme:entry-uri", a_entry.Uri));
+
+					child.SetBinaryStream (a_entry.DataStream);
+
+					this.child_indexables.Add (child);
+					this.count++;
+				}
+			}
+
+			public ICollection ChildIndexables {
+				get { return this.child_indexables; }
+			}
+		}
+	}	
+}
