001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 * 017 */ 018package org.apache.commons.compress.archivers.zip; 019 020import java.io.Serializable; 021 022import org.apache.commons.compress.utils.ByteUtils; 023 024/** 025 * Utility class that represents a two byte integer with conversion 026 * rules for the little endian byte order of ZIP files. 027 * @Immutable 028 */ 029public final class ZipShort implements Cloneable, Serializable { 030 /** 031 * ZipShort with a value of 0. 032 * @since 1.14 033 */ 034 public static final ZipShort ZERO = new ZipShort(0); 035 036 private static final long serialVersionUID = 1L; 037 038 private final int value; 039 040 /** 041 * Create instance from a number. 042 * @param value the int to store as a ZipShort 043 */ 044 public ZipShort (final int value) { 045 this.value = value; 046 } 047 048 /** 049 * Create instance from bytes. 050 * @param bytes the bytes to store as a ZipShort 051 */ 052 public ZipShort (final byte[] bytes) { 053 this(bytes, 0); 054 } 055 056 /** 057 * Create instance from the two bytes starting at offset. 058 * @param bytes the bytes to store as a ZipShort 059 * @param offset the offset to start 060 */ 061 public ZipShort (final byte[] bytes, final int offset) { 062 value = ZipShort.getValue(bytes, offset); 063 } 064 065 /** 066 * Get value as two bytes in big endian byte order. 067 * @return the value as a a two byte array in big endian byte order 068 */ 069 public byte[] getBytes() { 070 final byte[] result = new byte[2]; 071 ByteUtils.toLittleEndian(result, value, 0, 2); 072 return result; 073 } 074 075 /** 076 * Get value as Java int. 077 * @return value as a Java int 078 */ 079 public int getValue() { 080 return value; 081 } 082 083 /** 084 * Get value as two bytes in big endian byte order. 085 * @param value the Java int to convert to bytes 086 * @return the converted int as a byte array in big endian byte order 087 */ 088 public static byte[] getBytes(final int value) { 089 final byte[] result = new byte[2]; 090 putShort(value, result, 0); 091 return result; 092 } 093 094 /** 095 * put the value as two bytes in big endian byte order. 096 * @param value the Java int to convert to bytes 097 * @param buf the output buffer 098 * @param offset 099 * The offset within the output buffer of the first byte to be written. 100 * must be non-negative and no larger than <tt>buf.length-2</tt> 101 */ 102 public static void putShort(final int value, final byte[] buf, final int offset) { 103 ByteUtils.toLittleEndian(buf, value, offset, 2); 104 } 105 106 /** 107 * Helper method to get the value as a java int from two bytes starting at given array offset 108 * @param bytes the array of bytes 109 * @param offset the offset to start 110 * @return the corresponding java int value 111 */ 112 public static int getValue(final byte[] bytes, final int offset) { 113 return (int) ByteUtils.fromLittleEndian(bytes, offset, 2); 114 } 115 116 /** 117 * Helper method to get the value as a java int from a two-byte array 118 * @param bytes the array of bytes 119 * @return the corresponding java int value 120 */ 121 public static int getValue(final byte[] bytes) { 122 return getValue(bytes, 0); 123 } 124 125 /** 126 * Override to make two instances with same value equal. 127 * @param o an object to compare 128 * @return true if the objects are equal 129 */ 130 @Override 131 public boolean equals(final Object o) { 132 if (o == null || !(o instanceof ZipShort)) { 133 return false; 134 } 135 return value == ((ZipShort) o).getValue(); 136 } 137 138 /** 139 * Override to make two instances with same value equal. 140 * @return the value stored in the ZipShort 141 */ 142 @Override 143 public int hashCode() { 144 return value; 145 } 146 147 @Override 148 public Object clone() { 149 try { 150 return super.clone(); 151 } catch (final CloneNotSupportedException cnfe) { 152 // impossible 153 throw new RuntimeException(cnfe); //NOSONAR 154 } 155 } 156 157 @Override 158 public String toString() { 159 return "ZipShort value: " + value; 160 } 161}