KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > sourceforge > groboutils > codecoverage > v2 > ant > zip > AsiExtraField


1 /*
2  * Copyright 2001-2002,2004 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
18 package net.sourceforge.groboutils.codecoverage.v2.ant.zip;
19
20 import java.util.zip.CRC32 JavaDoc;
21 import java.util.zip.ZipException JavaDoc;
22
23 /**
24  * Adds Unix file permission and UID/GID fields as well as symbolic
25  * link handling.
26  *
27  * <p>This class uses the ASi extra field in the format:
28  * <pre>
29  * Value Size Description
30  * ----- ---- -----------
31  * (Unix3) 0x756e Short tag for this extra block type
32  * TSize Short total data size for this block
33  * CRC Long CRC-32 of the remaining data
34  * Mode Short file permissions
35  * SizDev Long symlink'd size OR major/minor dev num
36  * UID Short user ID
37  * GID Short group ID
38  * (var.) variable symbolic link filename
39  * </pre>
40  * taken from appnote.iz (Info-ZIP note, 981119) found at <a
41  * HREF="ftp://ftp.uu.net/pub/archiving/zip/doc/">ftp://ftp.uu.net/pub/archiving/zip/doc/</a></p>
42
43  *
44  * <p>Short is two bytes and Long is four bytes in big endian byte and
45  * word order, device numbers are currently not supported.</p>
46  *
47  * @author Stefan Bodewig
48  * @version $Revision: 1.1 $
49  */

50 public class AsiExtraField implements ZipExtraField, UnixStat, Cloneable JavaDoc {
51
52     private static final ZipShort HEADER_ID = new ZipShort(0x756E);
53
54     /**
55      * Standard Unix stat(2) file mode.
56      *
57      * @since 1.1
58      */

59     private int mode = 0;
60     /**
61      * User ID.
62      *
63      * @since 1.1
64      */

65     private int uid = 0;
66     /**
67      * Group ID.
68      *
69      * @since 1.1
70      */

71     private int gid = 0;
72     /**
73      * File this entry points to, if it is a symbolic link.
74      *
75      * <p>empty string - if entry is not a symbolic link.</p>
76      *
77      * @since 1.1
78      */

79     private String JavaDoc link = "";
80     /**
81      * Is this an entry for a directory?
82      *
83      * @since 1.1
84      */

85     private boolean dirFlag = false;
86
87     /**
88      * Instance used to calculate checksums.
89      *
90      * @since 1.1
91      */

92     private CRC32 JavaDoc crc = new CRC32 JavaDoc();
93
94     public AsiExtraField() {
95     }
96
97     /**
98      * The Header-ID.
99      *
100      * @since 1.1
101      */

102     public ZipShort getHeaderId() {
103         return HEADER_ID;
104     }
105
106     /**
107      * Length of the extra field in the local file data - without
108      * Header-ID or length specifier.
109      *
110      * @since 1.1
111      */

112     public ZipShort getLocalFileDataLength() {
113         return new ZipShort(4 // CRC
114
+ 2 // Mode
115
+ 4 // SizDev
116
+ 2 // UID
117
+ 2 // GID
118
+ getLinkedFile().getBytes().length);
119     }
120
121     /**
122      * Delegate to local file data.
123      *
124      * @since 1.1
125      */

126     public ZipShort getCentralDirectoryLength() {
127         return getLocalFileDataLength();
128     }
129
130     /**
131      * The actual data to put into local file data - without Header-ID
132      * or length specifier.
133      *
134      * @since 1.1
135      */

136     public byte[] getLocalFileDataData() {
137         // CRC will be added later
138
byte[] data = new byte[getLocalFileDataLength().getValue() - 4];
139         System.arraycopy((new ZipShort(getMode())).getBytes(), 0, data, 0, 2);
140
141         byte[] linkArray = getLinkedFile().getBytes();
142         System.arraycopy((new ZipLong(linkArray.length)).getBytes(),
143                          0, data, 2, 4);
144
145         System.arraycopy((new ZipShort(getUserId())).getBytes(),
146                          0, data, 6, 2);
147         System.arraycopy((new ZipShort(getGroupId())).getBytes(),
148                          0, data, 8, 2);
149
150         System.arraycopy(linkArray, 0, data, 10, linkArray.length);
151
152         crc.reset();
153         crc.update(data);
154         long checksum = crc.getValue();
155
156         byte[] result = new byte[data.length + 4];
157         System.arraycopy((new ZipLong(checksum)).getBytes(), 0, result, 0, 4);
158         System.arraycopy(data, 0, result, 4, data.length);
159         return result;
160     }
161
162     /**
163      * Delegate to local file data.
164      *
165      * @since 1.1
166      */

167     public byte[] getCentralDirectoryData() {
168         return getLocalFileDataData();
169     }
170
171     /**
172      * Set the user id.
173      *
174      * @since 1.1
175      */

176     public void setUserId(int uid) {
177         this.uid = uid;
178     }
179
180     /**
181      * Get the user id.
182      *
183      * @since 1.1
184      */

185     public int getUserId() {
186         return uid;
187     }
188
189     /**
190      * Set the group id.
191      *
192      * @since 1.1
193      */

194     public void setGroupId(int gid) {
195         this.gid = gid;
196     }
197
198     /**
199      * Get the group id.
200      *
201      * @since 1.1
202      */

203     public int getGroupId() {
204         return gid;
205     }
206
207     /**
208      * Indicate that this entry is a symbolic link to the given filename.
209      *
210      * @param name Name of the file this entry links to, empty String
211      * if it is not a symbolic link.
212      *
213      * @since 1.1
214      */

215     public void setLinkedFile(String JavaDoc name) {
216         link = name;
217         mode = getMode(mode);
218     }
219
220     /**
221      * Name of linked file
222      *
223      * @return name of the file this entry links to if it is a
224      * symbolic link, the empty string otherwise.
225      *
226      * @since 1.1
227      */

228     public String JavaDoc getLinkedFile() {
229         return link;
230     }
231
232     /**
233      * Is this entry a symbolic link?
234      *
235      * @since 1.1
236      */

237     public boolean isLink() {
238         return getLinkedFile().length() != 0;
239     }
240
241     /**
242      * File mode of this file.
243      *
244      * @since 1.1
245      */

246     public void setMode(int mode) {
247         this.mode = getMode(mode);
248     }
249
250     /**
251      * File mode of this file.
252      *
253      * @since 1.1
254      */

255     public int getMode() {
256         return mode;
257     }
258
259     /**
260      * Indicate whether this entry is a directory.
261      *
262      * @since 1.1
263      */

264     public void setDirectory(boolean dirFlag) {
265         this.dirFlag = dirFlag;
266         mode = getMode(mode);
267     }
268
269     /**
270      * Is this entry a directory?
271      *
272      * @since 1.1
273      */

274     public boolean isDirectory() {
275         return dirFlag && !isLink();
276     }
277
278     /**
279      * Populate data from this array as if it was in local file data.
280      *
281      * @since 1.1
282      */

283     public void parseFromLocalFileData(byte[] data, int offset, int length)
284         throws ZipException JavaDoc {
285
286         long givenChecksum = (new ZipLong(data, offset)).getValue();
287         byte[] tmp = new byte[length - 4];
288         System.arraycopy(data, offset + 4, tmp, 0, length - 4);
289         crc.reset();
290         crc.update(tmp);
291         long realChecksum = crc.getValue();
292         if (givenChecksum != realChecksum) {
293             throw new ZipException JavaDoc("bad CRC checksum "
294                                    + Long.toHexString(givenChecksum)
295                                    + " instead of "
296                                    + Long.toHexString(realChecksum));
297         }
298
299         int newMode = (new ZipShort(tmp, 0)).getValue();
300         byte[] linkArray = new byte[(int) (new ZipLong(tmp, 2)).getValue()];
301         uid = (new ZipShort(tmp, 6)).getValue();
302         gid = (new ZipShort(tmp, 8)).getValue();
303
304         if (linkArray.length == 0) {
305             link = "";
306         } else {
307             System.arraycopy(tmp, 10, linkArray, 0, linkArray.length);
308             link = new String JavaDoc(linkArray);
309         }
310         setDirectory((newMode & DIR_FLAG) != 0);
311         setMode(newMode);
312     }
313
314     /**
315      * Get the file mode for given permissions with the correct file type.
316      *
317      * @since 1.1
318      */

319     protected int getMode(int mode) {
320         int type = FILE_FLAG;
321         if (isLink()) {
322             type = LINK_FLAG;
323         } else if (isDirectory()) {
324             type = DIR_FLAG;
325         }
326         return type | (mode & PERM_MASK);
327     }
328
329 }
330
Popular Tags