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