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);
}
}
}