ZipLong.java

  1. /*
  2.  *  Licensed to the Apache Software Foundation (ASF) under one or more
  3.  *  contributor license agreements.  See the NOTICE file distributed with
  4.  *  this work for additional information regarding copyright ownership.
  5.  *  The ASF licenses this file to You under the Apache License, Version 2.0
  6.  *  (the "License"); you may not use this file except in compliance with
  7.  *  the License.  You may obtain a copy of the License at
  8.  *
  9.  *      http://www.apache.org/licenses/LICENSE-2.0
  10.  *
  11.  *  Unless required by applicable law or agreed to in writing, software
  12.  *  distributed under the License is distributed on an "AS IS" BASIS,
  13.  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14.  *  See the License for the specific language governing permissions and
  15.  *  limitations under the License.
  16.  */
  17. package org.apache.commons.compress.archivers.zip;

  18. import static org.apache.commons.compress.archivers.zip.ZipConstants.WORD;

  19. import java.io.Serializable;

  20. import org.apache.commons.compress.utils.ByteUtils;

  21. /**
  22.  * Utility class that represents a four byte integer with conversion rules for the little-endian byte order of ZIP files.
  23.  *
  24.  * @Immutable
  25.  */
  26. public final class ZipLong implements Cloneable, Serializable {

  27.     private static final long serialVersionUID = 1L;

  28.     /** Central File Header Signature */
  29.     public static final ZipLong CFH_SIG = new ZipLong(0X02014B50L);

  30.     /** Local File Header Signature */
  31.     public static final ZipLong LFH_SIG = new ZipLong(0X04034B50L);

  32.     /**
  33.      * Data Descriptor signature.
  34.      *
  35.      * <p>
  36.      * Actually, PKWARE uses this as marker for split/spanned archives and other archivers have started to use it as Data Descriptor signature (as well).
  37.      * </p>
  38.      *
  39.      * @since 1.1
  40.      */
  41.     public static final ZipLong DD_SIG = new ZipLong(0X08074B50L);

  42.     /**
  43.      * Value stored in size and similar fields if ZIP64 extensions are used.
  44.      *
  45.      * @since 1.3
  46.      */
  47.     static final ZipLong ZIP64_MAGIC = new ZipLong(ZipConstants.ZIP64_MAGIC);

  48.     /**
  49.      * 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).
  50.      *
  51.      * <p>
  52.      * This is the "PK00" prefix found in some archives.
  53.      * </p>
  54.      *
  55.      * @since 1.5
  56.      */
  57.     public static final ZipLong SINGLE_SEGMENT_SPLIT_MARKER = new ZipLong(0X30304B50L);

  58.     /**
  59.      * Archive extra data record signature.
  60.      *
  61.      * @since 1.5
  62.      */
  63.     public static final ZipLong AED_SIG = new ZipLong(0X08064B50L);

  64.     /**
  65.      * Gets value as four bytes in big-endian byte order.
  66.      *
  67.      * @param value the value to convert
  68.      * @return value as four bytes in big-endian byte order
  69.      */
  70.     public static byte[] getBytes(final long value) {
  71.         final byte[] result = new byte[WORD];
  72.         putLong(value, result, 0);
  73.         return result;
  74.     }

  75.     /**
  76.      * Helper method to get the value as a Java long from a four-byte array
  77.      *
  78.      * @param bytes the array of bytes
  79.      * @return the corresponding Java long value
  80.      */
  81.     public static long getValue(final byte[] bytes) {
  82.         return getValue(bytes, 0);
  83.     }

  84.     /**
  85.      * Helper method to get the value as a Java long from four bytes starting at given array offset
  86.      *
  87.      * @param bytes  the array of bytes
  88.      * @param offset the offset to start
  89.      * @return the corresponding Java long value
  90.      */
  91.     public static long getValue(final byte[] bytes, final int offset) {
  92.         return ByteUtils.fromLittleEndian(bytes, offset, 4);
  93.     }

  94.     /**
  95.      * put the value as four bytes in big-endian byte order.
  96.      *
  97.      * @param value  the Java long to convert to bytes
  98.      * @param buf    the output buffer
  99.      * @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}
  100.      */

  101.     public static void putLong(final long value, final byte[] buf, final int offset) {
  102.         ByteUtils.toLittleEndian(buf, value, offset, 4);
  103.     }

  104.     private final long value;

  105.     /**
  106.      * Constructs a new instance from bytes.
  107.      *
  108.      * @param bytes the bytes to store as a ZipLong
  109.      */
  110.     public ZipLong(final byte[] bytes) {
  111.         this(bytes, 0);
  112.     }

  113.     /**
  114.      * Creates instance from the four bytes starting at offset.
  115.      *
  116.      * @param bytes  the bytes to store as a ZipLong
  117.      * @param offset the offset to start
  118.      */
  119.     public ZipLong(final byte[] bytes, final int offset) {
  120.         value = getValue(bytes, offset);
  121.     }

  122.     /**
  123.      * create instance from a Java int.
  124.      *
  125.      * @param value the int to store as a ZipLong
  126.      * @since 1.15
  127.      */
  128.     public ZipLong(final int value) {
  129.         this.value = value;
  130.     }

  131.     /**
  132.      * Creates instance from a number.
  133.      *
  134.      * @param value the long to store as a ZipLong
  135.      */
  136.     public ZipLong(final long value) {
  137.         this.value = value;
  138.     }

  139.     @Override
  140.     public Object clone() {
  141.         try {
  142.             return super.clone();
  143.         } catch (final CloneNotSupportedException cnfe) {
  144.             // impossible
  145.             throw new UnsupportedOperationException(cnfe); // NOSONAR
  146.         }
  147.     }

  148.     /**
  149.      * Override to make two instances with same value equal.
  150.      *
  151.      * @param o an object to compare
  152.      * @return true if the objects are equal
  153.      */
  154.     @Override
  155.     public boolean equals(final Object o) {
  156.         if (!(o instanceof ZipLong)) {
  157.             return false;
  158.         }
  159.         return value == ((ZipLong) o).getValue();
  160.     }

  161.     /**
  162.      * Gets value as four bytes in big-endian byte order.
  163.      *
  164.      * @return value as four bytes in big-endian order
  165.      */
  166.     public byte[] getBytes() {
  167.         return getBytes(value);
  168.     }

  169.     /**
  170.      * Gets value as a (signed) Java int
  171.      *
  172.      * @return value as int
  173.      * @since 1.15
  174.      */
  175.     public int getIntValue() {
  176.         return (int) value;
  177.     }

  178.     /**
  179.      * Gets value as Java long.
  180.      *
  181.      * @return value as a long
  182.      */
  183.     public long getValue() {
  184.         return value;
  185.     }

  186.     /**
  187.      * Override to make two instances with same value equal.
  188.      *
  189.      * @return the value stored in the ZipLong
  190.      */
  191.     @Override
  192.     public int hashCode() {
  193.         return (int) value;
  194.     }

  195.     public void putLong(final byte[] buf, final int offset) {
  196.         putLong(value, buf, offset);
  197.     }

  198.     @Override
  199.     public String toString() {
  200.         return "ZipLong value: " + value;
  201.     }
  202. }