| /******************************************************************************* |
| * Copyright (c) 2007, 2018 compeople AG and others. |
| * |
| * This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License 2.0 |
| * which accompanies this distribution, and is available at |
| * https://www.eclipse.org/legal/epl-2.0/ |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| * |
| * Contributors: |
| * compeople AG (Stefan Liebig) - initial API and implementation |
| * IBM Corporation - bug fixes and enhancements |
| *******************************************************************************/ |
| package org.eclipse.equinox.internal.p2.sar; |
| |
| import java.io.IOException; |
| import java.util.*; |
| import java.util.zip.ZipEntry; |
| |
| /** |
| * A SarEntry is the header information for an entry within a |
| * org.eclipse.equinox.p2.sar stream.<br> |
| * <b>Note: </b>The setTime() and getTime() methods of ZipEntry (our super |
| * class) perform time zone dependent (!) conversions. For our serialization and |
| * deserialization the stored time has to be time zone neutral. Therefore it is |
| * necessary to invert those calculations. This is also the reason for |
| * duplicating the javaToDosTime() and dosToJavaTime() methods. |
| */ |
| public class SarEntry extends ZipEntry { |
| |
| private boolean isEof; |
| private boolean isZip; |
| |
| /** |
| * The name of the eof org.eclipse.equinox.p2.sar entry. |
| */ |
| private static final String EOF_ENTRY_NAME = "<eof-org.eclipse.equinox.p2.sar>"; //$NON-NLS-1$ |
| |
| private static final boolean DEBUG = SarConstants.DEBUG; |
| |
| /** |
| * Creates an eof org.eclipse.equinox.p2.sar entry |
| */ |
| public SarEntry() { |
| super(EOF_ENTRY_NAME); |
| setMethod(ZipEntry.DEFLATED); |
| this.isEof = true; |
| this.isZip = false; |
| } |
| |
| /** |
| * @param zipEntry |
| */ |
| public SarEntry(ZipEntry zipEntry) { |
| super(zipEntry); |
| this.isZip = false; |
| this.isEof = false; |
| } |
| |
| /** |
| * @param zipEntry |
| * @param isZip |
| */ |
| public SarEntry(ZipEntry zipEntry, boolean isZip) { |
| super(zipEntry); |
| this.isZip = isZip; |
| this.isEof = false; |
| } |
| |
| /** |
| * @param sarInputStream |
| * @throws IOException |
| */ |
| public SarEntry(SarInputStream sarInputStream) throws IOException { |
| // read name! |
| super(sarInputStream.readString()); |
| |
| String comment = sarInputStream.readString(); |
| long compressedSize = sarInputStream.readLong(); |
| long crc = sarInputStream.readLong(); |
| byte[] extra = sarInputStream.readBytes(); |
| int method = sarInputStream.readInt(); |
| long size = sarInputStream.readLong(); |
| long dosTime = sarInputStream.readLong(); |
| boolean eof = sarInputStream.readBoolean(); |
| boolean zip = sarInputStream.readBoolean(); |
| |
| if (DEBUG) { |
| System.out.println(getName() + ',' + comment + ',' + compressedSize + ',' + crc + ',' + extra + ',' + method |
| + ',' + size + ',' + dosTime + ',' + eof + ',' + zip); |
| } |
| |
| if (method == ZipEntry.STORED) { |
| setCompressedSize(compressedSize); |
| setCrc(crc); |
| setSize(size); |
| } |
| |
| setComment(comment); |
| setExtra(extra); |
| setMethod(method); |
| setTime(dosToJavaTime(dosTime)); |
| setEof(eof); |
| setZip(zip); |
| } |
| |
| /** |
| * @param sarOutputStream |
| * @throws IOException |
| */ |
| public void writeTo(SarOutputStream sarOutputStream) throws IOException { |
| String comment = this.getComment(); |
| long compressedSize = this.getCompressedSize(); |
| long crc = this.getCrc(); |
| byte[] extra = this.getExtra(); |
| int method = this.getMethod(); |
| String name = this.getName(); |
| long size = this.getSize(); |
| long dosTime = javaToDosTime(this.getTime()); |
| boolean zip = this.isZip(); |
| boolean eof = this.isEof(); |
| |
| if (DEBUG) { |
| System.out.println(name + ',' + comment + ',' + compressedSize + ',' + crc + ',' + extra + ',' + method |
| + ',' + size + ',' + dosTime + ',' + eof + ',' + zip); |
| } |
| |
| sarOutputStream.writeString(name); |
| sarOutputStream.writeString(comment); |
| sarOutputStream.writeLong(compressedSize); |
| sarOutputStream.writeLong(crc); |
| sarOutputStream.writeBytes(extra); |
| sarOutputStream.writeInt(method); |
| sarOutputStream.writeLong(size); |
| sarOutputStream.writeLong(dosTime); |
| sarOutputStream.writeBool(eof); |
| sarOutputStream.writeBool(zip); |
| } |
| |
| /** |
| * Is this the eof org.eclipse.equinox.p2.sar entry? |
| * |
| * @return the answer |
| */ |
| public boolean isEof() { |
| return isEof; |
| } |
| |
| private void setEof(boolean isEof) { |
| this.isEof = isEof; |
| } |
| |
| /** |
| * @return boolean |
| */ |
| public boolean isZip() { |
| return isZip; |
| } |
| |
| /** |
| * @param isZip |
| */ |
| private void setZip(boolean isZip) { |
| this.isZip = isZip; |
| } |
| |
| /* |
| * Converts DOS time to Java time (number of milliseconds since epoch). |
| */ |
| public final static long dosToJavaTime(long dtime) { |
| GregorianCalendar cal = new GregorianCalendar((int) (((dtime >> 25) & 0x7f) + 80) + 1900, |
| (int) (((dtime >> 21) & 0x0f) - 1), (int) ((dtime >> 16) & 0x1f), (int) ((dtime >> 11) & 0x1f), |
| (int) ((dtime >> 5) & 0x3f), (int) ((dtime << 1) & 0x3e)); |
| return cal.getTime().getTime(); |
| } |
| |
| /* |
| * Converts Java time to DOS time. |
| */ |
| public final static long javaToDosTime(long time) { |
| GregorianCalendar cal = new GregorianCalendar(); |
| cal.setTime(new Date(time)); |
| int year = cal.get(Calendar.YEAR); |
| if (year < 1980) |
| return (1 << 21) | (1 << 16); |
| int month = cal.get(Calendar.MONTH); |
| int date = cal.get(Calendar.DAY_OF_MONTH); |
| int hours = cal.get(Calendar.HOUR_OF_DAY); |
| int minutes = cal.get(Calendar.MINUTE); |
| int seconds = cal.get(Calendar.SECOND); |
| return (year - 1980) << 25 | (month + 1) << 21 | date << 16 | hours << 11 | minutes << 5 | seconds >> 1; |
| } |
| |
| } |