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