~ubuntu-branches/ubuntu/saucy/libcommons-compress-java/saucy-proposed

« back to all changes in this revision

Viewing changes to src/main/java/org/apache/commons/compress/archivers/zip/ExtraFieldUtils.java

  • Committer: Bazaar Package Importer
  • Author(s): Torsten Werner
  • Date: 2011-08-07 01:56:15 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20110807015615-cvbmhuv10g12fpz1
Tags: 1.2-1
* New upstream release
* Clean up Depends and Suggests fields.
* Switch to source format 3.0.

Show diffs side-by-side

added added

removed removed

Lines of Context:
86
86
 
87
87
    /**
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
93
94
     */
94
95
    public static ZipExtraField[] parse(byte[] data) throws ZipException {
95
 
        return parse(data, true);
 
96
        return parse(data, true, UnparseableExtraField.THROW);
 
97
    }
 
98
 
 
99
    /**
 
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
 
107
     */
 
108
    public static ZipExtraField[] parse(byte[] data, boolean local)
 
109
        throws ZipException {
 
110
        return parse(data, local, UnparseableExtraField.THROW);
96
111
    }
97
112
 
98
113
    /**
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
 
120
     * cannot be parsed.
104
121
     * @return an array of ExtraFields
105
122
     * @throws ZipException on error
 
123
     *
 
124
     * @since Apache Commons Compress 1.1
106
125
     */
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();
110
130
        int start = 0;
 
131
        LOOP:
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"
 
141
                                           + " data of "
 
142
                                           + (data.length - start - WORD)
 
143
                                           + " bytes.");
 
144
                case UnparseableExtraField.READ_KEY:
 
145
                    UnparseableExtraFieldData field =
 
146
                        new UnparseableExtraFieldData();
 
147
                    if (local) {
 
148
                        field.parseFromLocalFileData(data, start,
 
149
                                                     data.length - start);
 
150
                    } else {
 
151
                        field.parseFromCentralDirectoryData(data, start,
 
152
                                                            data.length - start);
 
153
                    }
 
154
                    v.add(field);
 
155
                    //$FALL-THROUGH$
 
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
 
159
                    // available data
 
160
                    break LOOP;
 
161
                default:
 
162
                    throw new ZipException("unknown UnparseableExtraField key: "
 
163
                                           + onUnparseableData.getKey());
 
164
                }
117
165
            }
118
166
            try {
119
167
                ZipExtraField ze = createExtraField(headerId);
142
190
     * @return an array of bytes
143
191
     */
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;
 
197
 
 
198
        int sum = WORD * regularExtraFieldCount;
146
199
        for (int i = 0; i < data.length; i++) {
147
200
            sum += data[i].getLocalFileDataLength().getValue();
148
201
        }
 
202
 
149
203
        byte[] result = new byte[sum];
150
204
        int start = 0;
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);
159
213
        }
 
214
        if (lastIsUnparseableHolder) {
 
215
            byte[] local = data[data.length - 1].getLocalFileDataData();
 
216
            System.arraycopy(local, 0, result, start, local.length);
 
217
        }
160
218
        return result;
161
219
    }
162
220
 
166
224
     * @return an array of bytes
167
225
     */
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;
 
231
 
 
232
        int sum = WORD * regularExtraFieldCount;
170
233
        for (int i = 0; i < data.length; i++) {
171
234
            sum += data[i].getCentralDirectoryLength().getValue();
172
235
        }
173
236
        byte[] result = new byte[sum];
174
237
        int start = 0;
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);
183
246
        }
 
247
        if (lastIsUnparseableHolder) {
 
248
            byte[] local = data[data.length - 1].getCentralDirectoryData();
 
249
            System.arraycopy(local, 0, result, start, local.length);
 
250
        }
184
251
        return result;
185
252
    }
 
253
 
 
254
    /**
 
255
     * "enum" for the possible actions to take if the extra field
 
256
     * cannot be parsed.
 
257
     *
 
258
     * @since Apache Commons Compress 1.1
 
259
     */
 
260
    public static final class UnparseableExtraField {
 
261
        /**
 
262
         * Key for "throw an exception" action.
 
263
         */
 
264
        public static final int THROW_KEY = 0;
 
265
        /**
 
266
         * Key for "skip" action.
 
267
         */
 
268
        public static final int SKIP_KEY = 1;
 
269
        /**
 
270
         * Key for "read" action.
 
271
         */
 
272
        public static final int READ_KEY = 2;
 
273
 
 
274
        /**
 
275
         * Throw an exception if field cannot be parsed.
 
276
         */
 
277
        public static final UnparseableExtraField THROW
 
278
            = new UnparseableExtraField(THROW_KEY);
 
279
 
 
280
        /**
 
281
         * Skip the extra field entirely and don't make its data
 
282
         * available - effectively removing the extra field data.
 
283
         */
 
284
        public static final UnparseableExtraField SKIP
 
285
            = new UnparseableExtraField(SKIP_KEY);
 
286
 
 
287
        /**
 
288
         * Read the extra field data into an instance of {@link
 
289
         * UnparseableExtraFieldData UnparseableExtraFieldData}.
 
290
         */
 
291
        public static final UnparseableExtraField READ
 
292
            = new UnparseableExtraField(READ_KEY);
 
293
 
 
294
        private final int key;
 
295
 
 
296
        private UnparseableExtraField(int k) {
 
297
            key = k;
 
298
        }
 
299
 
 
300
        /**
 
301
         * Key of the action to take.
 
302
         */
 
303
        public int getKey() { return key; }
 
304
    }
186
305
}