View Javadoc
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 = ZipShort.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 }