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