using System; using System.IO; using System.Text; using System.Collections; using System.Reflection; using System.Globalization; /// /// This class was first written by Drew Noakes in Java. /// /// This is public domain software - that is, you can do whatever you want /// with it, and include it software that is licensed under the GNU or the /// BSD license, or whatever other licence you choose, including proprietary /// closed source licenses. I do ask that you leave this header in tact. /// /// If you make modifications to this code that you think would benefit the /// wider community, please send me a copy and I'll post it on my site. /// /// If you make use of this code, Drew Noakes will appreciate hearing /// about it: drew@drewnoakes.com /// /// Latest Java version of this software kept at /// http://drewnoakes.com/ /// /// Created on 28 April 2002, 17:40 /// Modified 04 Aug 2002 /// - Adjusted javadoc /// - Added /// Modified 29 Oct 2002 (v1.2) /// - Stored IFD directories in separate tag-spaces /// - iterator() now returns an Iterator over a list of TagValue objects /// - More get///Description() methods to detail GPS tags, among others /// - Put spaces between words of tag name for presentation reasons (they had no significance in compound form) /// /// The C# class was made by Ferret Renaud: /// renaud91@free.fr /// If you find a bug in the C# code, feel free to mail me. /// namespace com.drew.metadata { [Serializable] public sealed class Metadata { private IDictionary directoryMap; /// /// List of Directory objects set against this object. /// Keeping a list handy makes creation of an Iterator and counting tags simple. /// private IList directoryList; /// /// Creates a new instance of Metadata. /// public Metadata() : base() { // Create a Hashtable using a case-insensitive code provider and a case-insensitive comparer, // based on the Spanish culture (es-AR), where "I" is not the uppercase version of "i". CultureInfo myCul = new CultureInfo( "es-AR" ); directoryMap = new Hashtable( new CaseInsensitiveHashCodeProvider( myCul ), new CaseInsensitiveComparer( myCul )); directoryList = new ArrayList(); } /// /// Creates an Iterator over the tag types set against this image, preserving the /// order in which they were set. Should the same tag have been set more than once, /// it's first position is maintained, even though the final value is used. /// /// an Iterator of tag types set for this image public IEnumerator GetDirectoryIterator() { return directoryList.GetEnumerator(); } /// /// Returns a count of unique directories in this metadata collection. /// /// the number of unique directory types set for this metadata collection public int GetDirectoryCount() { return directoryList.Count; } /// /// Gets a directory regarding its type /// /// the type you are looking for /// the directory found /// if aType is not a Directory like class public Directory GetDirectory(Type aType) { if (!Type.GetType("com.drew.metadata.Directory").IsAssignableFrom(aType)) { throw new ArgumentException("Class type passed to GetDirectory must be an implementation of com.drew.metadata.Directory"); } // check if we've already issued this type of directory if (directoryMap.Contains(aType)) { return (Directory) directoryMap[aType]; } object directory; try { ConstructorInfo[] ci = aType.GetConstructors(); directory = ci[0].Invoke(null); } catch (Exception e) { throw new SystemException( "Cannot instantiate provided Directory type: " + aType.ToString(), e); } // store the directory in case it's requested later directoryMap.Add(aType, directory); directoryList.Add(directory); return (Directory) directory; } /// /// Indicates whether a given directory type has been created in this metadata repository. /// Directories are created by calling getDirectory(Class). /// /// the Directory type /// true if the metadata directory has been created public bool ContainsDirectory(Type aType) { return directoryMap.Contains(aType); } } }