88
88
* Split the array into ExtraFields and populate them with the
89
* given data as local file data.
89
* given data as local file data, throwing an exception if the
90
* data cannot be parsed.
90
91
* @param data an array of bytes as it appears in local file data
91
92
* @return an array of ExtraFields
92
93
* @throws ZipException on error
94
95
public static ZipExtraField[] parse(byte[] data) throws ZipException {
95
return parse(data, true);
96
return parse(data, true, UnparseableExtraField.THROW);
100
* Split the array into ExtraFields and populate them with the
101
* given data, throwing an exception if the data cannot be parsed.
102
* @param data an array of bytes
103
* @param local whether data originates from the local file data
104
* or the central directory
105
* @return an array of ExtraFields
106
* @throws ZipException on error
108
public static ZipExtraField[] parse(byte[] data, boolean local)
109
throws ZipException {
110
return parse(data, local, UnparseableExtraField.THROW);
101
116
* @param data an array of bytes
102
117
* @param local whether data originates from the local file data
103
118
* or the central directory
119
* @param onUnparseableData what to do if the extra field data
104
121
* @return an array of ExtraFields
105
122
* @throws ZipException on error
124
* @since Apache Commons Compress 1.1
107
public static ZipExtraField[] parse(byte[] data, boolean local)
126
public static ZipExtraField[] parse(byte[] data, boolean local,
127
UnparseableExtraField onUnparseableData)
108
128
throws ZipException {
109
129
List v = new ArrayList();
111
132
while (start <= data.length - WORD) {
112
133
ZipShort headerId = new ZipShort(data, start);
113
134
int length = (new ZipShort(data, start + 2)).getValue();
114
135
if (start + WORD + length > data.length) {
115
throw new ZipException("data starting at " + start
116
+ " is in unknown format");
136
switch(onUnparseableData.getKey()) {
137
case UnparseableExtraField.THROW_KEY:
138
throw new ZipException("bad extra field starting at "
139
+ start + ". Block length of "
140
+ length + " bytes exceeds remaining"
142
+ (data.length - start - WORD)
144
case UnparseableExtraField.READ_KEY:
145
UnparseableExtraFieldData field =
146
new UnparseableExtraFieldData();
148
field.parseFromLocalFileData(data, start,
149
data.length - start);
151
field.parseFromCentralDirectoryData(data, start,
152
data.length - start);
156
case UnparseableExtraField.SKIP_KEY:
157
// since we cannot parse the data we must assume
158
// the extra field consumes the whole rest of the
162
throw new ZipException("unknown UnparseableExtraField key: "
163
+ onUnparseableData.getKey());
119
167
ZipExtraField ze = createExtraField(headerId);
142
190
* @return an array of bytes
144
192
public static byte[] mergeLocalFileDataData(ZipExtraField[] data) {
145
int sum = WORD * data.length;
193
final boolean lastIsUnparseableHolder = data.length > 0
194
&& data[data.length - 1] instanceof UnparseableExtraFieldData;
195
int regularExtraFieldCount =
196
lastIsUnparseableHolder ? data.length - 1 : data.length;
198
int sum = WORD * regularExtraFieldCount;
146
199
for (int i = 0; i < data.length; i++) {
147
200
sum += data[i].getLocalFileDataLength().getValue();
149
203
byte[] result = new byte[sum];
151
for (int i = 0; i < data.length; i++) {
205
for (int i = 0; i < regularExtraFieldCount; i++) {
152
206
System.arraycopy(data[i].getHeaderId().getBytes(),
153
207
0, result, start, 2);
154
208
System.arraycopy(data[i].getLocalFileDataLength().getBytes(),
157
211
System.arraycopy(local, 0, result, start + WORD, local.length);
158
212
start += (local.length + WORD);
214
if (lastIsUnparseableHolder) {
215
byte[] local = data[data.length - 1].getLocalFileDataData();
216
System.arraycopy(local, 0, result, start, local.length);
166
224
* @return an array of bytes
168
226
public static byte[] mergeCentralDirectoryData(ZipExtraField[] data) {
169
int sum = WORD * data.length;
227
final boolean lastIsUnparseableHolder = data.length > 0
228
&& data[data.length - 1] instanceof UnparseableExtraFieldData;
229
int regularExtraFieldCount =
230
lastIsUnparseableHolder ? data.length - 1 : data.length;
232
int sum = WORD * regularExtraFieldCount;
170
233
for (int i = 0; i < data.length; i++) {
171
234
sum += data[i].getCentralDirectoryLength().getValue();
173
236
byte[] result = new byte[sum];
175
for (int i = 0; i < data.length; i++) {
238
for (int i = 0; i < regularExtraFieldCount; i++) {
176
239
System.arraycopy(data[i].getHeaderId().getBytes(),
177
240
0, result, start, 2);
178
241
System.arraycopy(data[i].getCentralDirectoryLength().getBytes(),
181
244
System.arraycopy(local, 0, result, start + WORD, local.length);
182
245
start += (local.length + WORD);
247
if (lastIsUnparseableHolder) {
248
byte[] local = data[data.length - 1].getCentralDirectoryData();
249
System.arraycopy(local, 0, result, start, local.length);
255
* "enum" for the possible actions to take if the extra field
258
* @since Apache Commons Compress 1.1
260
public static final class UnparseableExtraField {
262
* Key for "throw an exception" action.
264
public static final int THROW_KEY = 0;
266
* Key for "skip" action.
268
public static final int SKIP_KEY = 1;
270
* Key for "read" action.
272
public static final int READ_KEY = 2;
275
* Throw an exception if field cannot be parsed.
277
public static final UnparseableExtraField THROW
278
= new UnparseableExtraField(THROW_KEY);
281
* Skip the extra field entirely and don't make its data
282
* available - effectively removing the extra field data.
284
public static final UnparseableExtraField SKIP
285
= new UnparseableExtraField(SKIP_KEY);
288
* Read the extra field data into an instance of {@link
289
* UnparseableExtraFieldData UnparseableExtraFieldData}.
291
public static final UnparseableExtraField READ
292
= new UnparseableExtraField(READ_KEY);
294
private final int key;
296
private UnparseableExtraField(int k) {
301
* Key of the action to take.
303
public int getKey() { return key; }