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 */
018 package org.apache.commons.compress.archivers.zip;
019
020 /**
021 * Utility class that represents a four byte integer with conversion
022 * rules for the big endian byte order of ZIP files.
023 * @Immutable
024 */
025 public final class ZipLong implements Cloneable {
026
027 private static final int WORD = 4;
028 //private static final int BYTE_BIT_SIZE = 8;
029 private static final int BYTE_MASK = 0xFF;
030
031 private static final int BYTE_1 = 1;
032 private static final int BYTE_1_MASK = 0xFF00;
033 private static final int BYTE_1_SHIFT = 8;
034
035 private static final int BYTE_2 = 2;
036 private static final int BYTE_2_MASK = 0xFF0000;
037 private static final int BYTE_2_SHIFT = 16;
038
039 private static final int BYTE_3 = 3;
040 private static final long BYTE_3_MASK = 0xFF000000L;
041 private static final int BYTE_3_SHIFT = 24;
042
043 private final long value;
044
045 /** Central File Header Signature */
046 public static final ZipLong CFH_SIG = new ZipLong(0X02014B50L);
047
048 /** Local File Header Signature */
049 public static final ZipLong LFH_SIG = new ZipLong(0X04034B50L);
050
051 /**
052 * Create instance from a number.
053 * @param value the long to store as a ZipLong
054 */
055 public ZipLong(long value) {
056 this.value = value;
057 }
058
059 /**
060 * Create instance from bytes.
061 * @param bytes the bytes to store as a ZipLong
062 */
063 public ZipLong (byte[] bytes) {
064 this(bytes, 0);
065 }
066
067 /**
068 * Create instance from the four bytes starting at offset.
069 * @param bytes the bytes to store as a ZipLong
070 * @param offset the offset to start
071 */
072 public ZipLong (byte[] bytes, int offset) {
073 value = ZipLong.getValue(bytes, offset);
074 }
075
076 /**
077 * Get value as four bytes in big endian byte order.
078 * @return value as four bytes in big endian order
079 */
080 public byte[] getBytes() {
081 return ZipLong.getBytes(value);
082 }
083
084 /**
085 * Get value as Java long.
086 * @return value as a long
087 */
088 public long getValue() {
089 return value;
090 }
091
092 /**
093 * Get value as four bytes in big endian byte order.
094 * @param value the value to convert
095 * @return value as four bytes in big endian byte order
096 */
097 public static byte[] getBytes(long value) {
098 byte[] result = new byte[WORD];
099 result[0] = (byte) ((value & BYTE_MASK));
100 result[BYTE_1] = (byte) ((value & BYTE_1_MASK) >> BYTE_1_SHIFT);
101 result[BYTE_2] = (byte) ((value & BYTE_2_MASK) >> BYTE_2_SHIFT);
102 result[BYTE_3] = (byte) ((value & BYTE_3_MASK) >> BYTE_3_SHIFT);
103 return result;
104 }
105
106 /**
107 * Helper method to get the value as a Java long from four bytes starting at given array offset
108 * @param bytes the array of bytes
109 * @param offset the offset to start
110 * @return the correspondanding Java long value
111 */
112 public static long getValue(byte[] bytes, int offset) {
113 long value = (bytes[offset + BYTE_3] << BYTE_3_SHIFT) & BYTE_3_MASK;
114 value += (bytes[offset + BYTE_2] << BYTE_2_SHIFT) & BYTE_2_MASK;
115 value += (bytes[offset + BYTE_1] << BYTE_1_SHIFT) & BYTE_1_MASK;
116 value += (bytes[offset] & BYTE_MASK);
117 return value;
118 }
119
120 /**
121 * Helper method to get the value as a Java long from a four-byte array
122 * @param bytes the array of bytes
123 * @return the correspondanding Java long value
124 */
125 public static long getValue(byte[] bytes) {
126 return getValue(bytes, 0);
127 }
128
129 /**
130 * Override to make two instances with same value equal.
131 * @param o an object to compare
132 * @return true if the objects are equal
133 */
134 public boolean equals(Object o) {
135 if (o == null || !(o instanceof ZipLong)) {
136 return false;
137 }
138 return value == ((ZipLong) o).getValue();
139 }
140
141 /**
142 * Override to make two instances with same value equal.
143 * @return the value stored in the ZipLong
144 */
145 public int hashCode() {
146 return (int) value;
147 }
148
149 public Object clone() {
150 try {
151 return super.clone();
152 } catch (CloneNotSupportedException cnfe) {
153 // impossible
154 throw new RuntimeException(cnfe);
155 }
156 }
157 }