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