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 */ 018package org.apache.commons.compress.archivers.zip; 019 020import org.apache.commons.compress.utils.ByteUtils; 021 022import java.io.Serializable; 023 024import static org.apache.commons.compress.archivers.zip.ZipConstants.WORD; 025 026/** 027 * Utility class that represents a four byte integer with conversion 028 * rules for the little endian byte order of ZIP files. 029 * @Immutable 030 */ 031public final class ZipLong implements Cloneable, Serializable { 032 private static final long serialVersionUID = 1L; 033 034 private final long value; 035 036 /** Central File Header Signature */ 037 public static final ZipLong CFH_SIG = new ZipLong(0X02014B50L); 038 039 /** Local File Header Signature */ 040 public static final ZipLong LFH_SIG = new ZipLong(0X04034B50L); 041 042 /** 043 * Data Descriptor signature. 044 * 045 * <p>Actually, PKWARE uses this as marker for split/spanned 046 * archives and other archivers have started to use it as Data 047 * Descriptor signature (as well).</p> 048 * @since 1.1 049 */ 050 public static final ZipLong DD_SIG = new ZipLong(0X08074B50L); 051 052 /** 053 * Value stored in size and similar fields if ZIP64 extensions are 054 * used. 055 * @since 1.3 056 */ 057 static final ZipLong ZIP64_MAGIC = new ZipLong(ZipConstants.ZIP64_MAGIC); 058 059 /** 060 * Marks ZIP archives that were supposed to be split or spanned 061 * but only needed a single segment in then end (so are actually 062 * neither split nor spanned). 063 * 064 * <p>This is the "PK00" prefix found in some archives.</p> 065 * @since 1.5 066 */ 067 public static final ZipLong SINGLE_SEGMENT_SPLIT_MARKER = 068 new ZipLong(0X30304B50L); 069 070 /** 071 * Archive extra data record signature. 072 * @since 1.5 073 */ 074 public static final ZipLong AED_SIG = new ZipLong(0X08064B50L); 075 076 /** 077 * Create instance from a number. 078 * @param value the long to store as a ZipLong 079 */ 080 public ZipLong(final long value) { 081 this.value = value; 082 } 083 084 /** 085 * create instance from a java int. 086 * @param value the int to store as a ZipLong 087 * @since 1.15 088 */ 089 public ZipLong(int value) { 090 this.value = value; 091 } 092 093 /** 094 * Create instance from bytes. 095 * @param bytes the bytes to store as a ZipLong 096 */ 097 public ZipLong (final byte[] bytes) { 098 this(bytes, 0); 099 } 100 101 /** 102 * Create instance from the four bytes starting at offset. 103 * @param bytes the bytes to store as a ZipLong 104 * @param offset the offset to start 105 */ 106 public ZipLong (final byte[] bytes, final int offset) { 107 value = ZipLong.getValue(bytes, offset); 108 } 109 110 /** 111 * Get value as four bytes in big endian byte order. 112 * @return value as four bytes in big endian order 113 */ 114 public byte[] getBytes() { 115 return ZipLong.getBytes(value); 116 } 117 118 /** 119 * Get value as Java long. 120 * @return value as a long 121 */ 122 public long getValue() { 123 return value; 124 } 125 126 /** 127 * Get value as a (signed) java int 128 * @return value as int 129 * @since 1.15 130 */ 131 public int getIntValue() { return (int)value;} 132 133 /** 134 * Get value as four bytes in big endian byte order. 135 * @param value the value to convert 136 * @return value as four bytes in big endian byte order 137 */ 138 public static byte[] getBytes(final long value) { 139 final byte[] result = new byte[WORD]; 140 putLong(value, result, 0); 141 return result; 142 } 143 144 /** 145 * put the value as four bytes in big endian byte order. 146 * @param value the Java long to convert to bytes 147 * @param buf the output buffer 148 * @param offset 149 * The offset within the output buffer of the first byte to be written. 150 * must be non-negative and no larger than <tt>buf.length-4</tt> 151 */ 152 153 public static void putLong(final long value, final byte[] buf, int offset) { 154 ByteUtils.toLittleEndian(buf, value, offset, 4); 155 } 156 157 public void putLong(final byte[] buf, final int offset) { 158 putLong(value, buf, offset); 159 } 160 161 /** 162 * Helper method to get the value as a Java long from four bytes starting at given array offset 163 * @param bytes the array of bytes 164 * @param offset the offset to start 165 * @return the corresponding Java long value 166 */ 167 public static long getValue(final byte[] bytes, final int offset) { 168 return ByteUtils.fromLittleEndian(bytes, offset, 4); 169 } 170 171 /** 172 * Helper method to get the value as a Java long from a four-byte array 173 * @param bytes the array of bytes 174 * @return the corresponding Java long value 175 */ 176 public static long getValue(final byte[] bytes) { 177 return getValue(bytes, 0); 178 } 179 180 /** 181 * Override to make two instances with same value equal. 182 * @param o an object to compare 183 * @return true if the objects are equal 184 */ 185 @Override 186 public boolean equals(final Object o) { 187 if (o == null || !(o instanceof ZipLong)) { 188 return false; 189 } 190 return value == ((ZipLong) o).getValue(); 191 } 192 193 /** 194 * Override to make two instances with same value equal. 195 * @return the value stored in the ZipLong 196 */ 197 @Override 198 public int hashCode() { 199 return (int) value; 200 } 201 202 @Override 203 public Object clone() { 204 try { 205 return super.clone(); 206 } catch (final CloneNotSupportedException cnfe) { 207 // impossible 208 throw new RuntimeException(cnfe); //NOSONAR 209 } 210 } 211 212 @Override 213 public String toString() { 214 return "ZipLong value: " + value; 215 } 216}