Skip to main content
aboutsummaryrefslogtreecommitdiffstats
blob: 033d3b6e03b9e44eda2ed495df9ffe714a4ee7a1 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
/*******************************************************************************
 * Copyright (c) 2007, 2018 compeople AG and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * 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;
	}

}

Back to the top