source: other-projects/trunk/gs3-release-maker/apache-ant-1.6.5/src/main/org/apache/tools/zip/ExtraFieldUtils.java@ 14627

Last change on this file since 14627 was 14627, checked in by oranfry, 17 years ago

initial import of the gs3-release-maker

File size: 5.7 KB
Line 
1/*
2 * Copyright 2001-2002,2004-2005 The Apache Software Foundation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 */
17
18package org.apache.tools.zip;
19
20import java.util.Hashtable;
21import java.util.Vector;
22import java.util.zip.ZipException;
23
24/**
25 * ZipExtraField related methods
26 *
27 */
28public class ExtraFieldUtils {
29
30 /**
31 * Static registry of known extra fields.
32 *
33 * @since 1.1
34 */
35 private static Hashtable implementations;
36
37 static {
38 implementations = new Hashtable();
39 register(AsiExtraField.class);
40 register(JarMarker.class);
41 }
42
43 /**
44 * Register a ZipExtraField implementation.
45 *
46 * <p>The given class must have a no-arg constructor and implement
47 * the {@link ZipExtraField ZipExtraField interface}.</p>
48 *
49 * @since 1.1
50 */
51 public static void register(Class c) {
52 try {
53 ZipExtraField ze = (ZipExtraField) c.newInstance();
54 implementations.put(ze.getHeaderId(), c);
55 } catch (ClassCastException cc) {
56 throw new RuntimeException(c + " doesn\'t implement ZipExtraField");
57 } catch (InstantiationException ie) {
58 throw new RuntimeException(c + " is not a concrete class");
59 } catch (IllegalAccessException ie) {
60 throw new RuntimeException(c + "\'s no-arg constructor is not public");
61 }
62 }
63
64 /**
65 * Create an instance of the approriate ExtraField, falls back to
66 * {@link UnrecognizedExtraField UnrecognizedExtraField}.
67 *
68 * @since 1.1
69 */
70 public static ZipExtraField createExtraField(ZipShort headerId)
71 throws InstantiationException, IllegalAccessException {
72 Class c = (Class) implementations.get(headerId);
73 if (c != null) {
74 return (ZipExtraField) c.newInstance();
75 }
76 UnrecognizedExtraField u = new UnrecognizedExtraField();
77 u.setHeaderId(headerId);
78 return u;
79 }
80
81 /**
82 * Split the array into ExtraFields and populate them with the
83 * give data.
84 *
85 * @since 1.1
86 */
87 public static ZipExtraField[] parse(byte[] data) throws ZipException {
88 Vector v = new Vector();
89 int start = 0;
90 while (start <= data.length - 4) {
91 ZipShort headerId = new ZipShort(data, start);
92 int length = (new ZipShort(data, start + 2)).getValue();
93 if (start + 4 + length > data.length) {
94 throw new ZipException("data starting at " + start
95 + " is in unknown format");
96 }
97 try {
98 ZipExtraField ze = createExtraField(headerId);
99 ze.parseFromLocalFileData(data, start + 4, length);
100 v.addElement(ze);
101 } catch (InstantiationException ie) {
102 throw new ZipException(ie.getMessage());
103 } catch (IllegalAccessException iae) {
104 throw new ZipException(iae.getMessage());
105 }
106 start += (length + 4);
107 }
108 if (start != data.length) { // array not exhausted
109 throw new ZipException("data starting at " + start
110 + " is in unknown format");
111 }
112
113 ZipExtraField[] result = new ZipExtraField[v.size()];
114 v.copyInto(result);
115 return result;
116 }
117
118 /**
119 * Merges the local file data fields of the given ZipExtraFields.
120 *
121 * @since 1.1
122 */
123 public static byte[] mergeLocalFileDataData(ZipExtraField[] data) {
124 int sum = 4 * data.length;
125 for (int i = 0; i < data.length; i++) {
126 sum += data[i].getLocalFileDataLength().getValue();
127 }
128 byte[] result = new byte[sum];
129 int start = 0;
130 for (int i = 0; i < data.length; i++) {
131 System.arraycopy(data[i].getHeaderId().getBytes(),
132 0, result, start, 2);
133 System.arraycopy(data[i].getLocalFileDataLength().getBytes(),
134 0, result, start + 2, 2);
135 byte[] local = data[i].getLocalFileDataData();
136 System.arraycopy(local, 0, result, start + 4, local.length);
137 start += (local.length + 4);
138 }
139 return result;
140 }
141
142 /**
143 * Merges the central directory fields of the given ZipExtraFields.
144 *
145 * @since 1.1
146 */
147 public static byte[] mergeCentralDirectoryData(ZipExtraField[] data) {
148 int sum = 4 * data.length;
149 for (int i = 0; i < data.length; i++) {
150 sum += data[i].getCentralDirectoryLength().getValue();
151 }
152 byte[] result = new byte[sum];
153 int start = 0;
154 for (int i = 0; i < data.length; i++) {
155 System.arraycopy(data[i].getHeaderId().getBytes(),
156 0, result, start, 2);
157 System.arraycopy(data[i].getCentralDirectoryLength().getBytes(),
158 0, result, start + 2, 2);
159 byte[] local = data[i].getCentralDirectoryData();
160 System.arraycopy(local, 0, result, start + 4, local.length);
161 start += (local.length + 4);
162 }
163 return result;
164 }
165}
Note: See TracBrowser for help on using the repository browser.