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 private static final int MAX_ALIGNMENT = Short.MAX_VALUE;
41
42
43
44
45 public static final ZipShort ID = new ZipShort(0xa11e);
46
47
48
49
50 public static final int BASE_SIZE = 2;
51
52 private static final int ALLOW_METHOD_MESSAGE_CHANGE_FLAG = 0x8000;
53
54 private short alignment;
55
56 private boolean allowMethodChange;
57
58 private int padding;
59
60
61
62
63 public ResourceAlignmentExtraField() {
64 }
65
66
67
68
69
70
71 public ResourceAlignmentExtraField(final int alignment) {
72 this(alignment, false);
73 }
74
75
76
77
78
79
80
81 public ResourceAlignmentExtraField(final int alignment, final boolean allowMethodChange) {
82 this(alignment, allowMethodChange, 0);
83 }
84
85
86
87
88
89
90
91
92 public ResourceAlignmentExtraField(final int alignment, final boolean allowMethodChange, final int padding) {
93 if (alignment < 0 || alignment > MAX_ALIGNMENT) {
94 throw new IllegalArgumentException("Alignment must be between 0 and 0x7fff, was: " + alignment);
95 }
96 if (padding < 0) {
97 throw new IllegalArgumentException("Padding must not be negative, was: " + padding);
98 }
99 this.alignment = (short) alignment;
100 this.allowMethodChange = allowMethodChange;
101 this.padding = padding;
102 }
103
104
105
106
107
108
109 public boolean allowMethodChange() {
110 return allowMethodChange;
111 }
112
113
114
115
116
117
118 public short getAlignment() {
119 return alignment;
120 }
121
122 @Override
123 public byte[] getCentralDirectoryData() {
124 return ZipShort.getBytes(alignment | (allowMethodChange ? ALLOW_METHOD_MESSAGE_CHANGE_FLAG : 0));
125 }
126
127 @Override
128 public ZipShort getCentralDirectoryLength() {
129 return new ZipShort(BASE_SIZE);
130 }
131
132 @Override
133 public ZipShort getHeaderId() {
134 return ID;
135 }
136
137 @Override
138 public byte[] getLocalFileDataData() {
139 final byte[] content = new byte[BASE_SIZE + padding];
140 ZipShort.putShort(alignment | (allowMethodChange ? ALLOW_METHOD_MESSAGE_CHANGE_FLAG : 0), content, 0);
141 return content;
142 }
143
144 @Override
145 public ZipShort getLocalFileDataLength() {
146 return new ZipShort(BASE_SIZE + padding);
147 }
148
149 @Override
150 public void parseFromCentralDirectoryData(final byte[] buffer, final int offset, final int length) throws ZipException {
151 if (length < BASE_SIZE) {
152 throw new ZipException("Too short content for ResourceAlignmentExtraField (0xa11e): " + length);
153 }
154 final int alignmentValue = ZipShort.getValue(buffer, offset);
155 this.alignment = (short) (alignmentValue & ALLOW_METHOD_MESSAGE_CHANGE_FLAG - 1);
156 this.allowMethodChange = (alignmentValue & ALLOW_METHOD_MESSAGE_CHANGE_FLAG) != 0;
157 }
158
159 @Override
160 public void parseFromLocalFileData(final byte[] buffer, final int offset, final int length) throws ZipException {
161 parseFromCentralDirectoryData(buffer, offset, length);
162 this.padding = length - BASE_SIZE;
163 }
164 }