SVG Filter



I dug this one up from bug 333408, its sanitized now. The original
code was almost impossible to understand (please indent properly!) and
I added a few more keywords/meta stuff to look for. Let me know what
you think, I have been running it over some 200 assorted SVG's and for
the time being it seems to be working fine.

Just a note, apply the diff from within the Filters directory, I have
a ton of changes in my local copy right now and I'm slowly breaking
them down into individual thoughts/patches.

--
Cheers,
Kevin Kubasik
http://blog.kubasik.net/
//
// FilterSVG.cs
//
using System;
using System.IO;
using System.Xml;
using System.Text;

using Beagle.Util;
using Beagle.Daemon;

namespace Beagle.Filters 
{
	public class FilterSVG : Filter 
	{
		StringBuilder sb;
		
		enum rdf_grab_modes {
				title_mode = 0,
				description_mode,
				date_mode,
				num
		};
		
		enum rdf_nongrab_modes {
				creator_mode = 0,
				contributer_mode,
				publisher_mode,
				rights_mode,
				num
		};
		
		static string [] rdf_grab_strings = { "title", "description", 
			"date", "source", "subject", "License" };
		static string [] rdf_nongrab_strings = { "creator", "contributor",
			"publisher", "rights" };
		
		public FilterSVG ()
		{
			SnippetMode = false;
			SetVersion (1);
			
			sb = new StringBuilder();
			
			AddSupportedFlavor (FilterFlavor.NewFromMimeType ("image/svg+xml"));
			AddSupportedFlavor (FilterFlavor.NewFromExtension (".svg"));
		}

		override protected void DoPullProperties ()
		{
			XmlTextReader reader = new XmlTextReader (Stream);
			reader.XmlResolver = null;
			
			int depth = 0;
			bool grab_text = false;
			string text = "";
			
			try {
				while (reader.Read ()) {
					switch (reader.NodeType) {
						case XmlNodeType.Element:
							if (!grab_text) {
								if (reader.LocalName == "title" ||
									reader.LocalName == "desc") {
									grab_text = true;
									depth = reader.Depth;
								} else if (reader.LocalName == "RDF") {
									PullRDFProperties(reader, reader.Depth);
								}
							}
							break;
						case XmlNodeType.Text:
							text = reader.Value.Trim();
							if (text != "") {
								if (grab_text) {
									sb.Append(text);
								} else {
									AppendText(text);
									AppendStructuralBreak();
								}
							}
							break;
							
						case XmlNodeType.Comment:
							AppendText(reader.Value.Trim());
							AppendStructuralBreak();
							break;
							
						case XmlNodeType.EndElement:
							if (grab_text && depth == reader.Depth) {
								grab_text = false;
								if (reader.LocalName == "title") {
									AddProperty (Property.New 
										("dc:title", sb.ToString()));
										
									sb.Length = 0;
								} else if (reader.LocalName == "desc") {
									AddProperty (Property.New 
										("dc:description", sb.ToString()));
										
									sb.Length = 0;
								}
							}
						break;
					}
				}
			} catch (System.Xml.XmlException) {
				System.Console.WriteLine("FilterSVG: error parsing xml file");
				Error();
			}
			
			Finished();
		}
		
		protected void PullRDFProperties(XmlTextReader reader, int depth)
		{
			int grab_mode = -1, nongrab_mode = -1;
			bool grab_text = false, agent_mode = false;

			string text = "";
			
			try {
				while (reader.Read ()) {
					if (depth == reader.Depth) {
						return;
					}
					
					switch (reader.NodeType) {
						case XmlNodeType.Element:
							if (grab_text) {
								break;
								
							} else if (reader.LocalName == "Agent") {
								grab_text = agent_mode = true;
								
							} else {
								for (int i=0; i<(int)rdf_grab_modes.num; i++) {
									if (reader.LocalName == rdf_grab_strings[i]) {
										grab_text = true;
										grab_mode = i;
										break;
									}
								}
								for (int i=0; i<(int)rdf_nongrab_modes.num; i++) {
									if (reader.LocalName == rdf_nongrab_strings[i]) {
										grab_text = false;
										nongrab_mode = i;
										break;
										
									}
								}
							}
							break;
							
							case XmlNodeType.Text:
							text = reader.Value.Trim();
							if (text != "") {
								if (grab_text) {
									sb.Append(text);
								} else {
									AppendText(text);
									AppendStructuralBreak();
								}
							}
							break;
							
							case XmlNodeType.EndElement:
								if (agent_mode) {
									if(reader.LocalName ==  "Agent") {
										agent_mode = grab_text = false;
										
										AddProperty (Property.New ("dc:" +
											rdf_nongrab_strings[nongrab_mode],
											 sb.ToString()));
										
										sb.Length = 0;
									}
								}else if (grab_mode >= 0 && 
											reader.LocalName == 
											rdf_grab_strings[grab_mode]) {
											
								if (grab_mode == (int)rdf_grab_modes.date_mode) {
									try {
									
										AddProperty (Property.NewDate 
											("dc:date", System.Convert.ToDateTime
											(sb.ToString())));
											
									} catch (FormatException) {
										AddProperty (Property.New 
											("dc:date", sb.ToString()));
									}
								} else {
									AddProperty (Property.New 
										("dc:" + rdf_grab_strings[grab_mode],
										 sb.ToString()));
								}
								sb.Length = 0;
								grab_mode = -1;
								grab_text = false;
							} else if (nongrab_mode >= 0 && 
								reader.LocalName == 
								rdf_nongrab_strings[nongrab_mode]) {
								
								nongrab_mode = -1;
								grab_text = false;
							}
							break;
					}
				}
			} catch (System.Xml.XmlException) {
				System.Console.WriteLine("FilterSVG: error parsing embedded RDF");
				Error();
			}
		}
	}
}

? FilterSVG.cs
? FilterTar.cs
? FilterZip.cs
? FilterZipFull.cs
? filterSVG.diff
Index: Makefile.am
===================================================================
RCS file: /cvs/gnome/beagle/Filters/Makefile.am,v
retrieving revision 1.63
diff -u -r1.63 Makefile.am
--- Makefile.am	22 Mar 2006 20:41:41 -0000	1.63
+++ Makefile.am	26 Mar 2006 12:37:56 -0000
@@ -61,6 +61,7 @@
 	$(srcdir)/FilterRuby.cs		\
 	$(srcdir)/FilterMPlayerVideo.cs	\
 	$(srcdir)/FilterBmp.cs		\
+	$(srcdir)/FilterSVG.cs	\
 	$(srcdir)/FilterExternal.cs
 
 if ENABLE_GSF_SHARP



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