blob: c3815441af7ec4619b5805312627f6e76d5db510 [file] [log] [blame]
Torsten Curdtca165392008-07-10 10:17:44 +00001/*
Torsten Curdtab9ebfc2009-01-12 11:15:34 +00002 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
Torsten Curdtca165392008-07-10 10:17:44 +00008 *
Torsten Curdtab9ebfc2009-01-12 11:15:34 +00009 * http://www.apache.org/licenses/LICENSE-2.0
Torsten Curdtca165392008-07-10 10:17:44 +000010 *
Torsten Curdtab9ebfc2009-01-12 11:15:34 +000011 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
Torsten Curdtca165392008-07-10 10:17:44 +000017 */
18package org.apache.commons.compress.archivers.zip;
19
Julius Daviesccc74412013-01-08 00:01:55 +000020import java.io.Serializable;
21
Stefan Bodewige53e88a2011-07-25 13:28:31 +000022import static org.apache.commons.compress.archivers.zip.ZipConstants.BYTE_MASK;
23import static org.apache.commons.compress.archivers.zip.ZipConstants.WORD;
24
Torsten Curdtca165392008-07-10 10:17:44 +000025/**
Torsten Curdtab9ebfc2009-01-12 11:15:34 +000026 * Utility class that represents a four byte integer with conversion
27 * rules for the big endian byte order of ZIP files.
Sebastian Bazley44dbd932009-03-28 00:03:11 +000028 * @Immutable
Torsten Curdtca165392008-07-10 10:17:44 +000029 */
Julius Daviesccc74412013-01-08 00:01:55 +000030public final class ZipLong implements Cloneable, Serializable {
31 private static final long serialVersionUID = 1L;
Torsten Curdtab9ebfc2009-01-12 11:15:34 +000032
Torsten Curdtab9ebfc2009-01-12 11:15:34 +000033 //private static final int BYTE_BIT_SIZE = 8;
Torsten Curdtab9ebfc2009-01-12 11:15:34 +000034
35 private static final int BYTE_1 = 1;
36 private static final int BYTE_1_MASK = 0xFF00;
37 private static final int BYTE_1_SHIFT = 8;
38
39 private static final int BYTE_2 = 2;
40 private static final int BYTE_2_MASK = 0xFF0000;
41 private static final int BYTE_2_SHIFT = 16;
42
43 private static final int BYTE_3 = 3;
44 private static final long BYTE_3_MASK = 0xFF000000L;
45 private static final int BYTE_3_SHIFT = 24;
46
Sebastian Bazley8fa12b82009-03-13 19:41:42 +000047 private final long value;
Torsten Curdtca165392008-07-10 10:17:44 +000048
Sebastian Bazleyf1d63a62009-03-28 03:18:42 +000049 /** Central File Header Signature */
Stefan Bodewig008ca942009-03-26 22:29:59 +000050 public static final ZipLong CFH_SIG = new ZipLong(0X02014B50L);
Sebastian Bazleyf1d63a62009-03-28 03:18:42 +000051
52 /** Local File Header Signature */
Stefan Bodewig008ca942009-03-26 22:29:59 +000053 public static final ZipLong LFH_SIG = new ZipLong(0X04034B50L);
54
Torsten Curdtca165392008-07-10 10:17:44 +000055 /**
Stefan Bodewig92d8c572013-01-01 10:51:42 +000056 * Data Descriptor signature.
57 *
58 * <p>Actually, PKWARE uses this as marker for split/spanned
59 * archives and other archivers have started to use it as Data
60 * Descriptor signature (as well).</p>
Gary D. Gregory2bd0dd42012-04-01 13:02:39 +000061 * @since 1.1
Stefan Bodewigd7ea9ff2010-03-12 15:35:44 +000062 */
63 public static final ZipLong DD_SIG = new ZipLong(0X08074B50L);
64
65 /**
Stefan Bodewigcb1fdba2011-07-25 16:31:10 +000066 * Value stored in size and similar fields if ZIP64 extensions are
67 * used.
Gary D. Gregory2bd0dd42012-04-01 13:02:39 +000068 * @since 1.3
Stefan Bodewigcb1fdba2011-07-25 16:31:10 +000069 */
Stefan Bodewigfadf6362011-07-29 04:01:05 +000070 static final ZipLong ZIP64_MAGIC = new ZipLong(ZipConstants.ZIP64_MAGIC);
Stefan Bodewigcb1fdba2011-07-25 16:31:10 +000071
72 /**
Stefan Bodewige10ce2c2013-01-01 10:57:23 +000073 * Marks ZIP archives that were supposed to be split or spanned
74 * but only needed a single segment in then end (so are actually
75 * neither split nor spanned).
76 *
77 * <p>This is the "PK00" prefix found in some archives.</p>
78 * @since 1.5
79 */
80 public static final ZipLong SINGLE_SEGMENT_SPLIT_MARKER =
81 new ZipLong(0X30304B50L);
82
83 /**
Stefan Bodewig45e51c22013-12-22 07:03:43 +000084 * Archive extra data record signature.
Stefan Bodewig7181d542013-01-22 12:45:24 +000085 * @since 1.5
86 */
87 public static final ZipLong AED_SIG = new ZipLong(0X08064B50L);
88
89 /**
Torsten Curdtca165392008-07-10 10:17:44 +000090 * Create instance from a number.
Torsten Curdtab9ebfc2009-01-12 11:15:34 +000091 * @param value the long to store as a ZipLong
Torsten Curdtca165392008-07-10 10:17:44 +000092 */
Torsten Curdtab9ebfc2009-01-12 11:15:34 +000093 public ZipLong(long value) {
94 this.value = value;
Torsten Curdtca165392008-07-10 10:17:44 +000095 }
96
97 /**
98 * Create instance from bytes.
Torsten Curdtab9ebfc2009-01-12 11:15:34 +000099 * @param bytes the bytes to store as a ZipLong
Torsten Curdtca165392008-07-10 10:17:44 +0000100 */
Torsten Curdtab9ebfc2009-01-12 11:15:34 +0000101 public ZipLong (byte[] bytes) {
102 this(bytes, 0);
Torsten Curdtca165392008-07-10 10:17:44 +0000103 }
104
105 /**
106 * Create instance from the four bytes starting at offset.
Torsten Curdtab9ebfc2009-01-12 11:15:34 +0000107 * @param bytes the bytes to store as a ZipLong
108 * @param offset the offset to start
Torsten Curdtca165392008-07-10 10:17:44 +0000109 */
Torsten Curdtab9ebfc2009-01-12 11:15:34 +0000110 public ZipLong (byte[] bytes, int offset) {
111 value = ZipLong.getValue(bytes, offset);
Torsten Curdtca165392008-07-10 10:17:44 +0000112 }
113
114 /**
Torsten Curdtab9ebfc2009-01-12 11:15:34 +0000115 * Get value as four bytes in big endian byte order.
Torsten Curdtab9ebfc2009-01-12 11:15:34 +0000116 * @return value as four bytes in big endian order
Torsten Curdtca165392008-07-10 10:17:44 +0000117 */
Torsten Curdtab9ebfc2009-01-12 11:15:34 +0000118 public byte[] getBytes() {
119 return ZipLong.getBytes(value);
120 }
121
122 /**
123 * Get value as Java long.
Torsten Curdtab9ebfc2009-01-12 11:15:34 +0000124 * @return value as a long
125 */
126 public long getValue() {
127 return value;
128 }
129
130 /**
131 * Get value as four bytes in big endian byte order.
132 * @param value the value to convert
133 * @return value as four bytes in big endian byte order
134 */
135 public static byte[] getBytes(long value) {
136 byte[] result = new byte[WORD];
137 result[0] = (byte) ((value & BYTE_MASK));
138 result[BYTE_1] = (byte) ((value & BYTE_1_MASK) >> BYTE_1_SHIFT);
139 result[BYTE_2] = (byte) ((value & BYTE_2_MASK) >> BYTE_2_SHIFT);
140 result[BYTE_3] = (byte) ((value & BYTE_3_MASK) >> BYTE_3_SHIFT);
Torsten Curdtca165392008-07-10 10:17:44 +0000141 return result;
142 }
143
144 /**
Torsten Curdtab9ebfc2009-01-12 11:15:34 +0000145 * Helper method to get the value as a Java long from four bytes starting at given array offset
146 * @param bytes the array of bytes
147 * @param offset the offset to start
Stefan Bodewigec445572011-07-21 08:38:24 +0000148 * @return the corresponding Java long value
Torsten Curdtca165392008-07-10 10:17:44 +0000149 */
Torsten Curdtab9ebfc2009-01-12 11:15:34 +0000150 public static long getValue(byte[] bytes, int offset) {
151 long value = (bytes[offset + BYTE_3] << BYTE_3_SHIFT) & BYTE_3_MASK;
152 value += (bytes[offset + BYTE_2] << BYTE_2_SHIFT) & BYTE_2_MASK;
153 value += (bytes[offset + BYTE_1] << BYTE_1_SHIFT) & BYTE_1_MASK;
154 value += (bytes[offset] & BYTE_MASK);
155 return value;
156 }
157
158 /**
159 * Helper method to get the value as a Java long from a four-byte array
160 * @param bytes the array of bytes
Stefan Bodewigec445572011-07-21 08:38:24 +0000161 * @return the corresponding Java long value
Torsten Curdtab9ebfc2009-01-12 11:15:34 +0000162 */
163 public static long getValue(byte[] bytes) {
164 return getValue(bytes, 0);
Torsten Curdtca165392008-07-10 10:17:44 +0000165 }
166
167 /**
168 * Override to make two instances with same value equal.
Torsten Curdtab9ebfc2009-01-12 11:15:34 +0000169 * @param o an object to compare
170 * @return true if the objects are equal
Torsten Curdtca165392008-07-10 10:17:44 +0000171 */
Stefan Bodewige53e88a2011-07-25 13:28:31 +0000172 @Override
Torsten Curdtab9ebfc2009-01-12 11:15:34 +0000173 public boolean equals(Object o) {
174 if (o == null || !(o instanceof ZipLong)) {
Torsten Curdtca165392008-07-10 10:17:44 +0000175 return false;
176 }
Torsten Curdtab9ebfc2009-01-12 11:15:34 +0000177 return value == ((ZipLong) o).getValue();
Torsten Curdtca165392008-07-10 10:17:44 +0000178 }
179
180 /**
181 * Override to make two instances with same value equal.
Torsten Curdtab9ebfc2009-01-12 11:15:34 +0000182 * @return the value stored in the ZipLong
Torsten Curdtca165392008-07-10 10:17:44 +0000183 */
Stefan Bodewige53e88a2011-07-25 13:28:31 +0000184 @Override
Torsten Curdtab9ebfc2009-01-12 11:15:34 +0000185 public int hashCode() {
186 return (int) value;
Torsten Curdtca165392008-07-10 10:17:44 +0000187 }
Stefan Bodewig5e5804c2009-02-05 12:45:23 +0000188
Stefan Bodewige53e88a2011-07-25 13:28:31 +0000189 @Override
Stefan Bodewig5e5804c2009-02-05 12:45:23 +0000190 public Object clone() {
191 try {
Sebastian Bazley5ccdd3f2009-03-04 00:29:29 +0000192 return super.clone();
Stefan Bodewig5e5804c2009-02-05 12:45:23 +0000193 } catch (CloneNotSupportedException cnfe) {
194 // impossible
195 throw new RuntimeException(cnfe);
196 }
197 }
Stefan Bodewig60e2dec2011-07-21 12:11:06 +0000198
Stefan Bodewige53e88a2011-07-25 13:28:31 +0000199 @Override
Stefan Bodewig60e2dec2011-07-21 12:11:06 +0000200 public String toString() {
201 return "ZipLong value: " + value;
202 }
Torsten Curdtca165392008-07-10 10:17:44 +0000203}