Clover coverage report - Ant Coverage
Coverage timestamp: Tue Apr 8 2003 20:43:55 EST
file stats: LOC: 206   Methods: 5
NCLOC: 100   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
ExtraFieldUtils.java 93.8% 89.5% 100% 91%
 1   
 /*
 2   
  * The Apache Software License, Version 1.1
 3   
  *
 4   
  * Copyright (c) 2001-2002 The Apache Software Foundation.  All rights
 5   
  * reserved.
 6   
  *
 7   
  * Redistribution and use in source and binary forms, with or without
 8   
  * modification, are permitted provided that the following conditions
 9   
  * are met:
 10   
  *
 11   
  * 1. Redistributions of source code must retain the above copyright
 12   
  *    notice, this list of conditions and the following disclaimer.
 13   
  *
 14   
  * 2. Redistributions in binary form must reproduce the above copyright
 15   
  *    notice, this list of conditions and the following disclaimer in
 16   
  *    the documentation and/or other materials provided with the
 17   
  *    distribution.
 18   
  *
 19   
  * 3. The end-user documentation included with the redistribution, if
 20   
  *    any, must include the following acknowlegement:
 21   
  *       "This product includes software developed by the
 22   
  *        Apache Software Foundation (http://www.apache.org/)."
 23   
  *    Alternately, this acknowlegement may appear in the software itself,
 24   
  *    if and wherever such third-party acknowlegements normally appear.
 25   
  *
 26   
  * 4. The names "Ant" and "Apache Software
 27   
  *    Foundation" must not be used to endorse or promote products derived
 28   
  *    from this software without prior written permission. For written
 29   
  *    permission, please contact apache@apache.org.
 30   
  *
 31   
  * 5. Products derived from this software may not be called "Apache"
 32   
  *    nor may "Apache" appear in their names without prior written
 33   
  *    permission of the Apache Group.
 34   
  *
 35   
  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 36   
  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 37   
  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 38   
  * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 39   
  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 40   
  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 41   
  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 42   
  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 43   
  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 44   
  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 45   
  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 46   
  * SUCH DAMAGE.
 47   
  * ====================================================================
 48   
  *
 49   
  * This software consists of voluntary contributions made by many
 50   
  * individuals on behalf of the Apache Software Foundation.  For more
 51   
  * information on the Apache Software Foundation, please see
 52   
  * <http://www.apache.org/>.
 53   
  */
 54   
 
 55   
 package org.apache.tools.zip;
 56   
 
 57   
 import java.util.Hashtable;
 58   
 import java.util.Vector;
 59   
 import java.util.zip.ZipException;
 60   
 
 61   
 /**
 62   
  * ZipExtraField related methods
 63   
  *
 64   
  * @author Stefan Bodewig
 65   
  * @version $Revision: 1.4 $
 66   
  */
 67   
 public class ExtraFieldUtils {
 68   
 
 69   
     /**
 70   
      * Static registry of known extra fields.
 71   
      *
 72   
      * @since 1.1
 73   
      */
 74   
     private static Hashtable implementations;
 75   
 
 76   
     static {
 77  3
         implementations = new Hashtable();
 78  3
         register(AsiExtraField.class);
 79   
     }
 80   
 
 81   
     /**
 82   
      * Register a ZipExtraField implementation.
 83   
      *
 84   
      * <p>The given class must have a no-arg constructor and implement
 85   
      * the {@link ZipExtraField ZipExtraField interface}.</p>
 86   
      *
 87   
      * @since 1.1
 88   
      */
 89  3
     public static void register(Class c) {
 90  3
         try {
 91  3
             ZipExtraField ze = (ZipExtraField) c.newInstance();
 92  3
             implementations.put(ze.getHeaderId(), c);
 93   
         } catch (ClassCastException cc) {
 94  0
             throw new RuntimeException(c + 
 95   
                                        " doesn\'t implement ZipExtraField");
 96   
         } catch (InstantiationException ie) {
 97  0
             throw new RuntimeException(c + " is not a concrete class");
 98   
         } catch (IllegalAccessException ie) {
 99  0
             throw new RuntimeException(c + 
 100   
                                        "\'s no-arg constructor is not public");
 101   
         }
 102   
     }
 103   
 
 104   
     /**
 105   
      * Create an instance of the approriate ExtraField, falls back to
 106   
      * {@link UnrecognizedExtraField UnrecognizedExtraField}.
 107   
      *
 108   
      * @since 1.1
 109   
      */
 110  3
     public static ZipExtraField createExtraField(ZipShort headerId)
 111   
         throws InstantiationException, IllegalAccessException {
 112  3
         Class c = (Class) implementations.get(headerId);
 113  3
         if (c != null) {
 114  2
             return (ZipExtraField) c.newInstance();
 115   
         }
 116  1
         UnrecognizedExtraField u = new UnrecognizedExtraField();
 117  1
         u.setHeaderId(headerId);
 118  1
         return u;
 119   
     }
 120   
 
 121   
     /**
 122   
      * Split the array into ExtraFields and populate them with the
 123   
      * give data.
 124   
      *
 125   
      * @since 1.1
 126   
      */
 127  2
     public static ZipExtraField[] parse(byte[] data) throws ZipException {
 128  2
         Vector v = new Vector();
 129  2
         int start = 0;
 130  2
         while (start <= data.length - 4) {
 131  3
             ZipShort headerId = new ZipShort(data, start);
 132  3
             int length = (new ZipShort(data, start + 2)).getValue();
 133  3
             if (start + 4 + length > data.length) {
 134  0
                 throw new ZipException("data starting at " + start
 135   
                     + " is in unknown format");
 136   
             }
 137  3
             try {
 138  3
                 ZipExtraField ze = createExtraField(headerId);
 139  3
                 ze.parseFromLocalFileData(data, start + 4, length);
 140  3
                 v.addElement(ze);
 141   
             } catch (InstantiationException ie) {
 142  0
                 throw new ZipException(ie.getMessage());
 143   
             } catch (IllegalAccessException iae) {
 144  0
                 throw new ZipException(iae.getMessage());
 145   
             }
 146  3
             start += (length + 4);
 147   
         }
 148  2
         if (start != data.length) { // array not exhausted
 149  1
             throw new ZipException("data starting at " + start
 150   
                 + " is in unknown format");
 151   
         }
 152   
         
 153  1
         ZipExtraField[] result = new ZipExtraField[v.size()];
 154  1
         v.copyInto(result);
 155  1
         return result;
 156   
     }
 157   
 
 158   
     /**
 159   
      * Merges the local file data fields of the given ZipExtraFields.
 160   
      *
 161   
      * @since 1.1
 162   
      */
 163  5
     public static byte[] mergeLocalFileDataData(ZipExtraField[] data) {
 164  5
         int sum = 4 * data.length;
 165  5
         for (int i = 0; i < data.length; i++) {
 166  11
             sum += data[i].getLocalFileDataLength().getValue();
 167   
         }
 168  5
         byte[] result = new byte[sum];
 169  5
         int start = 0;
 170  5
         for (int i = 0; i < data.length; i++) {
 171  11
             System.arraycopy(data[i].getHeaderId().getBytes(),
 172   
                              0, result, start, 2);
 173  11
             System.arraycopy(data[i].getLocalFileDataLength().getBytes(),
 174   
                              0, result, start + 2, 2);
 175  11
             byte[] local = data[i].getLocalFileDataData();
 176  11
             System.arraycopy(local, 0, result, start + 4, local.length);
 177  11
             start += (local.length + 4);
 178   
         }
 179  5
         return result;
 180   
     }
 181   
 
 182   
     /**
 183   
      * Merges the central directory fields of the given ZipExtraFields.
 184   
      *
 185   
      * @since 1.1
 186   
      */
 187  1474
     public static byte[] mergeCentralDirectoryData(ZipExtraField[] data) {
 188  1474
         int sum = 4 * data.length;
 189  1474
         for (int i = 0; i < data.length; i++) {
 190  2
             sum += data[i].getCentralDirectoryLength().getValue();
 191   
         }
 192  1474
         byte[] result = new byte[sum];
 193  1474
         int start = 0;
 194  1474
         for (int i = 0; i < data.length; i++) {
 195  2
             System.arraycopy(data[i].getHeaderId().getBytes(),
 196   
                              0, result, start, 2);
 197  2
             System.arraycopy(data[i].getCentralDirectoryLength().getBytes(),
 198   
                              0, result, start + 2, 2);
 199  2
             byte[] local = data[i].getCentralDirectoryData();
 200  2
             System.arraycopy(local, 0, result, start + 4, local.length);
 201  2
             start += (local.length + 4);
 202   
         }
 203  1474
         return result;
 204   
     }
 205   
 }
 206