content: /*
   * Copyright 2002-2012 Drew Noakes
   *
   *    Licensed under the Apache License, Version 2.0 (the "License");
   *    you may not use this file except in compliance with the License.
   *    You may obtain a copy of the License at
   *
   *        http://www.apache.org/licenses/LICENSE-2.0
   *
   *    Unless required by applicable law or agreed to in writing, software
   *    distributed under the License is distributed on an "AS IS" BASIS,
   *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   *    See the License for the specific language governing permissions and
   *    limitations under the License.
   *
   * More information about this project is available at:
   *
   *    http://drewnoakes.com/code/exif/
   *    http://code.google.com/p/metadata-extractor/
   */
  package com.almalence.util.exifreader.metadata;
  
  import com.almalence.util.exifreader.lang.annotations.NotNull;
  import com.almalence.util.exifreader.lang.annotations.Nullable;
  
  import java.lang.reflect.Array;
  
  /**
   * Abstract base class for all tag descriptor classes.  Implementations are responsible for
   * providing the human-readable string representation of tag values stored in a directory.
   * The directory is provided to the tag descriptor via its constructor.
   *
   * @author Drew Noakes http://drewnoakes.com
   */
  public abstract class TagDescriptor<T extends Directory>
  {
      @NotNull
      protected final T _directory;
  
      public TagDescriptor(@NotNull T directory)
      {
          _directory = directory;
      }
  
      /**
       * Returns a descriptive value of the the specified tag for this image.
       * Where possible, known values will be substituted here in place of the raw
       * tokens actually kept in the metadata segment.  If no substitution is
       * available, the value provided by <code>getString(tagType)</code> will be returned.
       * 
       * @param tagType the tag to find a description for
       * @return a description of the image's value for the specified tag, or
       *         <code>null</code> if the tag hasn't been defined.
       */
      @Nullable
      public String getDescription(int tagType)
      {
          Object object = _directory.getObject(tagType);
  
          if (object==null)
              return null;
  
          // special presentation for long arrays
          if (object.getClass().isArray()) {
              final int length = Array.getLength(object);
              if (length > 16) {
                  final String componentTypeName = object.getClass().getComponentType().getName();
                  return String.format("[%d %s%s]", length, componentTypeName, length==1 ? "" : "s");
              }
          }
  
          // no special handling required, so use default conversion to a string
          return _directory.getString(tagType);
      }
  
      /**
       * Takes a series of 4 bytes from the specified offset, and converts these to a
       * well-known version number, where possible.
       * <p/>
       * Two different formats are processed:
       * <ul>
       *     <li>[30 32 31 30] -&gt; 2.10</li>
       *     <li>[0 1 0 0] -&gt; 1.00</li>
       * </ul>
       * @param components the four version values
       * @param majorDigits the number of components to be 
       * @return the version as a string of form "2.10" or null if the argument cannot be converted
       */
      @Nullable
      public static String convertBytesToVersionString(@Nullable int[] components, final int majorDigits)
      {
          if (components==null)
              return null;
          StringBuilder version = new StringBuilder();
          for (int i = 0; i < 4 && i < components.length; i++) {
              if (i == majorDigits)
                  version.append('.');
              char c = (char)components[i];
              if (c < '0')
                  c += '0';
              if (i == 0 && c=='0')
                  continue;
              version.append(c);
          }
          return version.toString();
      }
  }
  