1 /*
2 * 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
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * 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 */
17 package org.apache.commons.compress.archivers.zip;
18
19 import java.io.Serializable;
20
21 import org.apache.commons.compress.utils.ByteUtils;
22
23 /**
24 * Utility class that represents a two byte integer with conversion rules for the little-endian byte order of ZIP files.
25 *
26 * @Immutable
27 */
28 public final class ZipShort implements Cloneable, Serializable {
29 /**
30 * ZipShort with a value of 0.
31 *
32 * @since 1.14
33 */
34 public static final ZipShort ZERO = new ZipShort(0);
35
36 private static final long serialVersionUID = 1L;
37
38 /**
39 * Gets value as two bytes in big-endian byte order.
40 *
41 * @param value the Java int to convert to bytes
42 * @return the converted int as a byte array in big-endian byte order
43 */
44 public static byte[] getBytes(final int value) {
45 final byte[] result = new byte[2];
46 putShort(value, result, 0);
47 return result;
48 }
49
50 /**
51 * Helper method to get the value as a Java int from a two-byte array
52 *
53 * @param bytes the array of bytes
54 * @return the corresponding Java int value
55 */
56 public static int getValue(final byte[] bytes) {
57 return getValue(bytes, 0);
58 }
59
60 /**
61 * Helper method to get the value as a Java int from two bytes starting at given array offset
62 *
63 * @param bytes the array of bytes
64 * @param offset the offset to start
65 * @return the corresponding Java int value
66 */
67 public static int getValue(final byte[] bytes, final int offset) {
68 return (int) ByteUtils.fromLittleEndian(bytes, offset, 2);
69 }
70
71 /**
72 * put the value as two bytes in big-endian byte order.
73 *
74 * @param value the Java int to convert to bytes
75 * @param buf the output buffer
76 * @param offset The offset within the output buffer of the first byte to be written. must be non-negative and no larger than {@code buf.length-2}
77 */
78 public static void putShort(final int value, final byte[] buf, final int offset) {
79 ByteUtils.toLittleEndian(buf, value, offset, 2);
80 }
81
82 private final int value;
83
84 /**
85 * Constructs a new instance from bytes.
86 *
87 * @param bytes the bytes to store as a ZipShort
88 */
89 public ZipShort(final byte[] bytes) {
90 this(bytes, 0);
91 }
92
93 /**
94 * Constructs a new instance from the two bytes starting at offset.
95 *
96 * @param bytes the bytes to store as a ZipShort
97 * @param offset the offset to start
98 */
99 public ZipShort(final byte[] bytes, final int offset) {
100 value = getValue(bytes, offset);
101 }
102
103 /**
104 * Constructs a new instance from a number.
105 *
106 * @param value the int to store as a ZipShort
107 */
108 public ZipShort(final int value) {
109 this.value = value;
110 }
111
112 @Override
113 public Object clone() {
114 try {
115 return super.clone();
116 } catch (final CloneNotSupportedException cnfe) {
117 // impossible
118 throw new UnsupportedOperationException(cnfe); // NOSONAR
119 }
120 }
121
122 /**
123 * Override to make two instances with same value equal.
124 *
125 * @param o an object to compare
126 * @return true if the objects are equal
127 */
128 @Override
129 public boolean equals(final Object o) {
130 if (!(o instanceof ZipShort)) {
131 return false;
132 }
133 return value == ((ZipShort) o).getValue();
134 }
135
136 /**
137 * Gets value as two bytes in big-endian byte order.
138 *
139 * @return the value as a two byte array in big-endian byte order
140 */
141 public byte[] getBytes() {
142 final byte[] result = new byte[2];
143 ByteUtils.toLittleEndian(result, value, 0, 2);
144 return result;
145 }
146
147 /**
148 * Gets value as Java int.
149 *
150 * @return value as a Java int
151 */
152 public int getValue() {
153 return value;
154 }
155
156 /**
157 * Override to make two instances with same value equal.
158 *
159 * @return the value stored in the ZipShort
160 */
161 @Override
162 public int hashCode() {
163 return value;
164 }
165
166 @Override
167 public String toString() {
168 return "ZipShort value: " + value;
169 }
170 }