001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * https://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, 013 * software distributed under the License is distributed on an 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 * KIND, either express or implied. See the License for the 016 * specific language governing permissions and limitations 017 * under the License. 018 */ 019package org.apache.commons.compress.archivers.zip; 020 021import static org.apache.commons.compress.archivers.zip.ZipConstants.WORD; 022 023import java.io.Serializable; 024 025import org.apache.commons.compress.utils.ByteUtils; 026 027/** 028 * Utility class that represents a four byte integer with conversion rules for the little-endian byte order of ZIP files. 029 * 030 * @Immutable 031 */ 032public final class ZipLong implements Cloneable, Serializable { 033 034 private static final long serialVersionUID = 1L; 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> 046 * Actually, PKWARE uses this as marker for split/spanned archives and other archivers have started to use it as Data Descriptor signature (as well). 047 * </p> 048 * 049 * @since 1.1 050 */ 051 public static final ZipLong DD_SIG = new ZipLong(0X08074B50L); 052 053 /** 054 * Value stored in size and similar fields if ZIP64 extensions are used. 055 * 056 * @since 1.3 057 */ 058 static final ZipLong ZIP64_MAGIC = new ZipLong(ZipConstants.ZIP64_MAGIC); 059 060 /** 061 * 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). 062 * 063 * <p> 064 * This is the "PK00" prefix found in some archives. 065 * </p> 066 * 067 * @since 1.5 068 */ 069 public static final ZipLong SINGLE_SEGMENT_SPLIT_MARKER = new ZipLong(0X30304B50L); 070 071 /** 072 * Archive extra data record signature. 073 * 074 * @since 1.5 075 */ 076 public static final ZipLong AED_SIG = new ZipLong(0X08064B50L); 077 078 /** 079 * Gets value as four bytes in big-endian byte order. 080 * 081 * @param value the value to convert 082 * @return value as four bytes in big-endian byte order 083 */ 084 public static byte[] getBytes(final long value) { 085 final byte[] result = new byte[WORD]; 086 putLong(value, result, 0); 087 return result; 088 } 089 090 /** 091 * Helper method to get the value as a Java long from a four-byte array 092 * 093 * @param bytes the array of bytes 094 * @return the corresponding Java long value 095 */ 096 public static long getValue(final byte[] bytes) { 097 return getValue(bytes, 0); 098 } 099 100 /** 101 * Helper method to get the value as a Java long from four bytes starting at given array offset 102 * 103 * @param bytes the array of bytes 104 * @param offset the offset to start 105 * @return the corresponding Java long value 106 */ 107 public static long getValue(final byte[] bytes, final int offset) { 108 return ByteUtils.fromLittleEndian(bytes, offset, 4); 109 } 110 111 /** 112 * Puts a long value in a buffer as four bytes in little-endian byte order. 113 * 114 * @param value the Java long to convert to bytes 115 * @param buf the output buffer 116 * @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} 117 */ 118 public static void putLong(final long value, final byte[] buf, final int offset) { 119 ByteUtils.toLittleEndian(buf, value, offset, 4); 120 } 121 122 private final long value; 123 124 /** 125 * Constructs a new instance from bytes. 126 * 127 * @param bytes the bytes to store as a ZipLong 128 */ 129 public ZipLong(final byte[] bytes) { 130 this(bytes, 0); 131 } 132 133 /** 134 * Creates instance from the four bytes starting at offset. 135 * 136 * @param bytes the bytes to store as a ZipLong 137 * @param offset the offset to start 138 */ 139 public ZipLong(final byte[] bytes, final int offset) { 140 value = getValue(bytes, offset); 141 } 142 143 /** 144 * create instance from a Java int. 145 * 146 * @param value the int to store as a ZipLong 147 * @since 1.15 148 */ 149 public ZipLong(final int value) { 150 this.value = value; 151 } 152 153 /** 154 * Creates instance from a number. 155 * 156 * @param value the long to store as a ZipLong 157 */ 158 public ZipLong(final long value) { 159 this.value = value; 160 } 161 162 @Override 163 public Object clone() { 164 try { 165 return super.clone(); 166 } catch (final CloneNotSupportedException cnfe) { 167 // impossible 168 throw new UnsupportedOperationException(cnfe); // NOSONAR 169 } 170 } 171 172 /** 173 * Override to make two instances with same value equal. 174 * 175 * @param o an object to compare 176 * @return true if the objects are equal 177 */ 178 @Override 179 public boolean equals(final Object o) { 180 if (!(o instanceof ZipLong)) { 181 return false; 182 } 183 return value == ((ZipLong) o).getValue(); 184 } 185 186 /** 187 * Gets value as four bytes in big-endian byte order. 188 * 189 * @return value as four bytes in big-endian order 190 */ 191 public byte[] getBytes() { 192 return getBytes(value); 193 } 194 195 /** 196 * Gets value as a (signed) Java int 197 * 198 * @return value as int 199 * @since 1.15 200 */ 201 public int getIntValue() { 202 return (int) value; 203 } 204 205 /** 206 * Gets value as Java long. 207 * 208 * @return value as a long 209 */ 210 public long getValue() { 211 return value; 212 } 213 214 /** 215 * Override to make two instances with same value equal. 216 * 217 * @return the value stored in the ZipLong 218 */ 219 @Override 220 public int hashCode() { 221 return (int) value; 222 } 223 224 /** 225 * Puts this long value in a buffer as four bytes in little-endian byte order. 226 * 227 * @param buf the output buffer 228 * @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} 229 */ 230 public void putLong(final byte[] buf, final int offset) { 231 putLong(value, buf, offset); 232 } 233 234 @Override 235 public String toString() { 236 return "ZipLong value: " + value; 237 } 238}