1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.commons.compress.archivers.zip;
20
21 import java.util.zip.ZipException;
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38 public class ResourceAlignmentExtraField implements ZipExtraField {
39
40
41
42
43 public static final ZipShort ID = new ZipShort(0xa11e);
44
45 public static final int BASE_SIZE = 2;
46
47 private static final int ALLOW_METHOD_MESSAGE_CHANGE_FLAG = 0x8000;
48
49 private short alignment;
50
51 private boolean allowMethodChange;
52
53 private int padding;
54
55 public ResourceAlignmentExtraField() {
56 }
57
58 public ResourceAlignmentExtraField(final int alignment) {
59 this(alignment, false);
60 }
61
62 public ResourceAlignmentExtraField(final int alignment, final boolean allowMethodChange) {
63 this(alignment, allowMethodChange, 0);
64 }
65
66 public ResourceAlignmentExtraField(final int alignment, final boolean allowMethodChange, final int padding) {
67 if (alignment < 0 || alignment > 0x7fff) {
68 throw new IllegalArgumentException("Alignment must be between 0 and 0x7fff, was: " + alignment);
69 }
70 if (padding < 0) {
71 throw new IllegalArgumentException("Padding must not be negative, was: " + padding);
72 }
73 this.alignment = (short) alignment;
74 this.allowMethodChange = allowMethodChange;
75 this.padding = padding;
76 }
77
78
79
80
81
82
83 public boolean allowMethodChange() {
84 return allowMethodChange;
85 }
86
87
88
89
90
91
92 public short getAlignment() {
93 return alignment;
94 }
95
96 @Override
97 public byte[] getCentralDirectoryData() {
98 return ZipShort.getBytes(alignment | (allowMethodChange ? ALLOW_METHOD_MESSAGE_CHANGE_FLAG : 0));
99 }
100
101 @Override
102 public ZipShort getCentralDirectoryLength() {
103 return new ZipShort(BASE_SIZE);
104 }
105
106 @Override
107 public ZipShort getHeaderId() {
108 return ID;
109 }
110
111 @Override
112 public byte[] getLocalFileDataData() {
113 final byte[] content = new byte[BASE_SIZE + padding];
114 ZipShort.putShort(alignment | (allowMethodChange ? ALLOW_METHOD_MESSAGE_CHANGE_FLAG : 0), content, 0);
115 return content;
116 }
117
118 @Override
119 public ZipShort getLocalFileDataLength() {
120 return new ZipShort(BASE_SIZE + padding);
121 }
122
123 @Override
124 public void parseFromCentralDirectoryData(final byte[] buffer, final int offset, final int length) throws ZipException {
125 if (length < BASE_SIZE) {
126 throw new ZipException("Too short content for ResourceAlignmentExtraField (0xa11e): " + length);
127 }
128 final int alignmentValue = ZipShort.getValue(buffer, offset);
129 this.alignment = (short) (alignmentValue & ALLOW_METHOD_MESSAGE_CHANGE_FLAG - 1);
130 this.allowMethodChange = (alignmentValue & ALLOW_METHOD_MESSAGE_CHANGE_FLAG) != 0;
131 }
132
133 @Override
134 public void parseFromLocalFileData(final byte[] buffer, final int offset, final int length) throws ZipException {
135 parseFromCentralDirectoryData(buffer, offset, length);
136 this.padding = length - BASE_SIZE;
137 }
138 }