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 */ 018 package org.apache.commons.compress.archivers.zip; 019 020 import java.io.Serializable; 021 022 import static org.apache.commons.compress.archivers.zip.ZipConstants.BYTE_MASK; 023 024 /** 025 * Utility class that represents a two byte integer with conversion 026 * rules for the big endian byte order of ZIP files. 027 * @Immutable 028 */ 029 public final class ZipShort implements Cloneable, Serializable { 030 private static final long serialVersionUID = 1L; 031 032 private static final int BYTE_1_MASK = 0xFF00; 033 private static final int BYTE_1_SHIFT = 8; 034 035 private final int value; 036 037 /** 038 * Create instance from a number. 039 * @param value the int to store as a ZipShort 040 */ 041 public ZipShort (int value) { 042 this.value = value; 043 } 044 045 /** 046 * Create instance from bytes. 047 * @param bytes the bytes to store as a ZipShort 048 */ 049 public ZipShort (byte[] bytes) { 050 this(bytes, 0); 051 } 052 053 /** 054 * Create instance from the two bytes starting at offset. 055 * @param bytes the bytes to store as a ZipShort 056 * @param offset the offset to start 057 */ 058 public ZipShort (byte[] bytes, int offset) { 059 value = ZipShort.getValue(bytes, offset); 060 } 061 062 /** 063 * Get value as two bytes in big endian byte order. 064 * @return the value as a a two byte array in big endian byte order 065 */ 066 public byte[] getBytes() { 067 byte[] result = new byte[2]; 068 result[0] = (byte) (value & BYTE_MASK); 069 result[1] = (byte) ((value & BYTE_1_MASK) >> BYTE_1_SHIFT); 070 return result; 071 } 072 073 /** 074 * Get value as Java int. 075 * @return value as a Java int 076 */ 077 public int getValue() { 078 return value; 079 } 080 081 /** 082 * Get value as two bytes in big endian byte order. 083 * @param value the Java int to convert to bytes 084 * @return the converted int as a byte array in big endian byte order 085 */ 086 public static byte[] getBytes(int value) { 087 byte[] result = new byte[2]; 088 result[0] = (byte) (value & BYTE_MASK); 089 result[1] = (byte) ((value & BYTE_1_MASK) >> BYTE_1_SHIFT); 090 return result; 091 } 092 093 /** 094 * Helper method to get the value as a java int from two bytes starting at given array offset 095 * @param bytes the array of bytes 096 * @param offset the offset to start 097 * @return the corresponding java int value 098 */ 099 public static int getValue(byte[] bytes, int offset) { 100 int value = (bytes[offset + 1] << BYTE_1_SHIFT) & BYTE_1_MASK; 101 value += (bytes[offset] & BYTE_MASK); 102 return value; 103 } 104 105 /** 106 * Helper method to get the value as a java int from a two-byte array 107 * @param bytes the array of bytes 108 * @return the corresponding java int value 109 */ 110 public static int getValue(byte[] bytes) { 111 return getValue(bytes, 0); 112 } 113 114 /** 115 * Override to make two instances with same value equal. 116 * @param o an object to compare 117 * @return true if the objects are equal 118 */ 119 @Override 120 public boolean equals(Object o) { 121 if (o == null || !(o instanceof ZipShort)) { 122 return false; 123 } 124 return value == ((ZipShort) o).getValue(); 125 } 126 127 /** 128 * Override to make two instances with same value equal. 129 * @return the value stored in the ZipShort 130 */ 131 @Override 132 public int hashCode() { 133 return value; 134 } 135 136 @Override 137 public Object clone() { 138 try { 139 return super.clone(); 140 } catch (CloneNotSupportedException cnfe) { 141 // impossible 142 throw new RuntimeException(cnfe); 143 } 144 } 145 146 @Override 147 public String toString() { 148 return "ZipShort value: " + value; 149 } 150 }