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