FileDocCategorySizeDatePackage
AsiExtraField.javaAPI DocApache Ant 1.709260Wed Dec 13 06:16:22 GMT 2006org.apache.tools.zip

AsiExtraField

public class AsiExtraField extends Object implements ZipExtraField, Cloneable, UnixStat
Adds Unix file permission and UID/GID fields as well as symbolic link handling.

This class uses the ASi extra field in the format:

Value Size Description
----- ---- -----------
(Unix3) 0x756e Short tag for this extra block type
TSize Short total data size for this block
CRC Long CRC-32 of the remaining data
Mode Short file permissions
SizDev Long symlink'd size OR major/minor dev num
UID Short user ID
GID Short group ID
(var.) variable symbolic link filename
taken from appnote.iz (Info-ZIP note, 981119) found at ftp://ftp.uu.net/pub/archiving/zip/doc/

Short is two bytes and Long is four bytes in big endian byte and word order, device numbers are currently not supported.

Fields Summary
private static final ZipShort
HEADER_ID
private int
mode
Standard Unix stat(2) file mode.
private int
uid
User ID.
private int
gid
Group ID.
private String
link
File this entry points to, if it is a symbolic link.

empty string - if entry is not a symbolic link.

private boolean
dirFlag
Is this an entry for a directory?
private CRC32
crc
Instance used to calculate checksums.
Constructors Summary
public AsiExtraField()
Constructor for AsiExtraField.


        
      
    
Methods Summary
public byte[]getCentralDirectoryData()
Delegate to local file data.

return
the local file data
since
1.1

        return getLocalFileDataData();
    
public ZipShortgetCentralDirectoryLength()
Delegate to local file data.

return
the centralDirectory length
since
1.1

        return getLocalFileDataLength();
    
public intgetGroupId()
Get the group id.

return
the group id
since
1.1

        return gid;
    
public ZipShortgetHeaderId()
The Header-ID.

return
the value for the header id for this extrafield
since
1.1

        return HEADER_ID;
    
public java.lang.StringgetLinkedFile()
Name of linked file

return
name of the file this entry links to if it is a symbolic link, the empty string otherwise.
since
1.1

        return link;
    
public byte[]getLocalFileDataData()
The actual data to put into local file data - without Header-ID or length specifier.

return
get the data
since
1.1

        // CRC will be added later
        byte[] data = new byte[getLocalFileDataLength().getValue() - 4];
        System.arraycopy(ZipShort.getBytes(getMode()), 0, data, 0, 2);

        byte[] linkArray = getLinkedFile().getBytes();
        System.arraycopy(ZipLong.getBytes(linkArray.length),
                         0, data, 2, 4);

        System.arraycopy(ZipShort.getBytes(getUserId()),
                         0, data, 6, 2);
        System.arraycopy(ZipShort.getBytes(getGroupId()),
                         0, data, 8, 2);

        System.arraycopy(linkArray, 0, data, 10, linkArray.length);

        crc.reset();
        crc.update(data);
        long checksum = crc.getValue();

        byte[] result = new byte[data.length + 4];
        System.arraycopy(ZipLong.getBytes(checksum), 0, result, 0, 4);
        System.arraycopy(data, 0, result, 4, data.length);
        return result;
    
public ZipShortgetLocalFileDataLength()
Length of the extra field in the local file data - without Header-ID or length specifier.

return
a ZipShort for the length of the data of this extra field
since
1.1

        return new ZipShort(4         // CRC
                          + 2         // Mode
                          + 4         // SizDev
                          + 2         // UID
                          + 2         // GID
                          + getLinkedFile().getBytes().length);
    
public intgetMode()
File mode of this file.

return
the file mode
since
1.1

        return mode;
    
protected intgetMode(int mode)
Get the file mode for given permissions with the correct file type.

param
mode the mode
return
the type with the mode
since
1.1

        int type = FILE_FLAG;
        if (isLink()) {
            type = LINK_FLAG;
        } else if (isDirectory()) {
            type = DIR_FLAG;
        }
        return type | (mode & PERM_MASK);
    
public intgetUserId()
Get the user id.

return
the user id
since
1.1

        return uid;
    
public booleanisDirectory()
Is this entry a directory?

return
true if this entry is a directory
since
1.1

        return dirFlag && !isLink();
    
public booleanisLink()
Is this entry a symbolic link?

return
true if this is a symbolic link
since
1.1

        return getLinkedFile().length() != 0;
    
public voidparseFromLocalFileData(byte[] data, int offset, int length)
Populate data from this array as if it was in local file data.

param
data an array of bytes
param
offset the start offset
param
length the number of bytes in the array from offset
since
1.1
throws
ZipException on error


        long givenChecksum = ZipLong.getValue(data, offset);
        byte[] tmp = new byte[length - 4];
        System.arraycopy(data, offset + 4, tmp, 0, length - 4);
        crc.reset();
        crc.update(tmp);
        long realChecksum = crc.getValue();
        if (givenChecksum != realChecksum) {
            throw new ZipException("bad CRC checksum "
                                   + Long.toHexString(givenChecksum)
                                   + " instead of "
                                   + Long.toHexString(realChecksum));
        }

        int newMode = ZipShort.getValue(tmp, 0);
        byte[] linkArray = new byte[(int) ZipLong.getValue(tmp, 2)];
        uid = ZipShort.getValue(tmp, 6);
        gid = ZipShort.getValue(tmp, 8);

        if (linkArray.length == 0) {
            link = "";
        } else {
            System.arraycopy(tmp, 10, linkArray, 0, linkArray.length);
            link = new String(linkArray);
        }
        setDirectory((newMode & DIR_FLAG) != 0);
        setMode(newMode);
    
public voidsetDirectory(boolean dirFlag)
Indicate whether this entry is a directory.

param
dirFlag if true, this entry is a directory
since
1.1

        this.dirFlag = dirFlag;
        mode = getMode(mode);
    
public voidsetGroupId(int gid)
Set the group id.

param
gid the group id
since
1.1

        this.gid = gid;
    
public voidsetLinkedFile(java.lang.String name)
Indicate that this entry is a symbolic link to the given filename.

param
name Name of the file this entry links to, empty String if it is not a symbolic link.
since
1.1

        link = name;
        mode = getMode(mode);
    
public voidsetMode(int mode)
File mode of this file.

param
mode the file mode
since
1.1

        this.mode = getMode(mode);
    
public voidsetUserId(int uid)
Set the user id.

param
uid the user id
since
1.1

        this.uid = uid;