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 * Data Descriptor signature 053 * @since Apache Commons Compress 1.1 054 */ 055 public static final ZipLong DD_SIG = new ZipLong(0X08074B50L); 056 057 /** 058 * Create instance from a number. 059 * @param value the long to store as a ZipLong 060 */ 061 public ZipLong(long value) { 062 this.value = value; 063 } 064 065 /** 066 * Create instance from bytes. 067 * @param bytes the bytes to store as a ZipLong 068 */ 069 public ZipLong (byte[] bytes) { 070 this(bytes, 0); 071 } 072 073 /** 074 * Create instance from the four bytes starting at offset. 075 * @param bytes the bytes to store as a ZipLong 076 * @param offset the offset to start 077 */ 078 public ZipLong (byte[] bytes, int offset) { 079 value = ZipLong.getValue(bytes, offset); 080 } 081 082 /** 083 * Get value as four bytes in big endian byte order. 084 * @return value as four bytes in big endian order 085 */ 086 public byte[] getBytes() { 087 return ZipLong.getBytes(value); 088 } 089 090 /** 091 * Get value as Java long. 092 * @return value as a long 093 */ 094 public long getValue() { 095 return value; 096 } 097 098 /** 099 * Get value as four bytes in big endian byte order. 100 * @param value the value to convert 101 * @return value as four bytes in big endian byte order 102 */ 103 public static byte[] getBytes(long value) { 104 byte[] result = new byte[WORD]; 105 result[0] = (byte) ((value & BYTE_MASK)); 106 result[BYTE_1] = (byte) ((value & BYTE_1_MASK) >> BYTE_1_SHIFT); 107 result[BYTE_2] = (byte) ((value & BYTE_2_MASK) >> BYTE_2_SHIFT); 108 result[BYTE_3] = (byte) ((value & BYTE_3_MASK) >> BYTE_3_SHIFT); 109 return result; 110 } 111 112 /** 113 * Helper method to get the value as a Java long from four bytes starting at given array offset 114 * @param bytes the array of bytes 115 * @param offset the offset to start 116 * @return the corresponding Java long value 117 */ 118 public static long getValue(byte[] bytes, int offset) { 119 long value = (bytes[offset + BYTE_3] << BYTE_3_SHIFT) & BYTE_3_MASK; 120 value += (bytes[offset + BYTE_2] << BYTE_2_SHIFT) & BYTE_2_MASK; 121 value += (bytes[offset + BYTE_1] << BYTE_1_SHIFT) & BYTE_1_MASK; 122 value += (bytes[offset] & BYTE_MASK); 123 return value; 124 } 125 126 /** 127 * Helper method to get the value as a Java long from a four-byte array 128 * @param bytes the array of bytes 129 * @return the corresponding Java long value 130 */ 131 public static long getValue(byte[] bytes) { 132 return getValue(bytes, 0); 133 } 134 135 /** 136 * Override to make two instances with same value equal. 137 * @param o an object to compare 138 * @return true if the objects are equal 139 */ 140 public boolean equals(Object o) { 141 if (o == null || !(o instanceof ZipLong)) { 142 return false; 143 } 144 return value == ((ZipLong) o).getValue(); 145 } 146 147 /** 148 * Override to make two instances with same value equal. 149 * @return the value stored in the ZipLong 150 */ 151 public int hashCode() { 152 return (int) value; 153 } 154 155 public Object clone() { 156 try { 157 return super.clone(); 158 } catch (CloneNotSupportedException cnfe) { 159 // impossible 160 throw new RuntimeException(cnfe); 161 } 162 } 163 164 public String toString() { 165 return "ZipLong value: " + value; 166 } 167 }