History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/com/sun/java/util/jar/pack/AdaptiveCoding.java (1 of 18352 files). Show all

Unified · Split

java/pkg/com/sun/java/util/jar/pack/AdaptiveCoding.java+298−0
@@ -0,0 +1,298 @@
1+/*
2+ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
3+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+ *
5+ * This code is free software; you can redistribute it and/or modify it
6+ * under the terms of the GNU General Public License version 2 only, as
7+ * published by the Free Software Foundation. Oracle designates this
8+ * particular file as subject to the "Classpath" exception as provided
9+ * by Oracle in the LICENSE file that accompanied this code.
10+ *
11+ * This code is distributed in the hope that it will be useful, but WITHOUT
12+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+ * version 2 for more details (a copy is included in the LICENSE file that
15+ * accompanied this code).
16+ *
17+ * You should have received a copy of the GNU General Public License version
18+ * 2 along with this work; if not, write to the Free Software Foundation,
19+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+ *
21+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+ * or visit www.oracle.com if you need additional information or have any
23+ * questions.
24+ */
25+
26+package com.sun.java.util.jar.pack;
27+
28+import java.io.ByteArrayOutputStream;
29+import java.io.IOException;
30+import java.io.InputStream;
31+import java.io.OutputStream;
32+import static com.sun.java.util.jar.pack.Constants.*;
33+
34+/**
35+ * Adaptive coding.
36+ * See the section "Adaptive Encodings" in the Pack200 spec.
37+ * @author John Rose
38+ */
39+class AdaptiveCoding implements CodingMethod {
40+ CodingMethod headCoding;
41+ int headLength;
42+ CodingMethod tailCoding;
43+
44+ public AdaptiveCoding(int headLength, CodingMethod headCoding, CodingMethod tailCoding) {
45+ assert(isCodableLength(headLength));
46+ this.headLength = headLength;
47+ this.headCoding = headCoding;
48+ this.tailCoding = tailCoding;
49+ }
50+
51+ public void setHeadCoding(CodingMethod headCoding) {
52+ this.headCoding = headCoding;
53+ }
54+ public void setHeadLength(int headLength) {
55+ assert(isCodableLength(headLength));
56+ this.headLength = headLength;
57+ }
58+ public void setTailCoding(CodingMethod tailCoding) {
59+ this.tailCoding = tailCoding;
60+ }
61+
62+ public boolean isTrivial() {
63+ return headCoding == tailCoding;
64+ }
65+
66+ // CodingMethod methods.
67+ public void writeArrayTo(OutputStream out, int[] a, int start, int end) throws IOException {
68+ writeArray(this, out, a, start, end);
69+ }
70+ // writeArrayTo must be coded iteratively, not recursively:
71+ private static void writeArray(AdaptiveCoding run, OutputStream out, int[] a, int start, int end) throws IOException {
72+ for (;;) {
73+ int mid = start+run.headLength;
74+ assert(mid <= end);
75+ run.headCoding.writeArrayTo(out, a, start, mid);
76+ start = mid;
77+ if (run.tailCoding instanceof AdaptiveCoding) {
78+ run = (AdaptiveCoding) run.tailCoding;
79+ continue;
80+ }
81+ break;
82+ }
83+ run.tailCoding.writeArrayTo(out, a, start, end);
84+ }
85+
86+ public void readArrayFrom(InputStream in, int[] a, int start, int end) throws IOException {
87+ readArray(this, in, a, start, end);
88+ }
89+ private static void readArray(AdaptiveCoding run, InputStream in, int[] a, int start, int end) throws IOException {
90+ for (;;) {
91+ int mid = start+run.headLength;
92+ assert(mid <= end);
93+ run.headCoding.readArrayFrom(in, a, start, mid);
94+ start = mid;
95+ if (run.tailCoding instanceof AdaptiveCoding) {
96+ run = (AdaptiveCoding) run.tailCoding;
97+ continue;
98+ }
99+ break;
100+ }
101+ run.tailCoding.readArrayFrom(in, a, start, end);
102+ }
103+
104+ public static final int KX_MIN = 0;
105+ public static final int KX_MAX = 3;
106+ public static final int KX_LG2BASE = 4;
107+ public static final int KX_BASE = 16;
108+
109+ public static final int KB_MIN = 0x00;
110+ public static final int KB_MAX = 0xFF;
111+ public static final int KB_OFFSET = 1;
112+ public static final int KB_DEFAULT = 3;
113+
114+ static int getKXOf(int K) {
115+ for (int KX = KX_MIN; KX <= KX_MAX; KX++) {
116+ if (((K - KB_OFFSET) & ~KB_MAX) == 0)
117+ return KX;
118+ K >>>= KX_LG2BASE;
119+ }
120+ return -1;
121+ }
122+
123+ static int getKBOf(int K) {
124+ int KX = getKXOf(K);
125+ if (KX < 0) return -1;
126+ K >>>= (KX * KX_LG2BASE);
127+ return K-1;
128+ }
129+
130+ static int decodeK(int KX, int KB) {
131+ assert(KX_MIN <= KX && KX <= KX_MAX);
132+ assert(KB_MIN <= KB && KB <= KB_MAX);
133+ return (KB+KB_OFFSET) << (KX * KX_LG2BASE);
134+ }
135+
136+ static int getNextK(int K) {
137+ if (K <= 0) return 1; // 1st K value
138+ int KX = getKXOf(K);
139+ if (KX < 0) return Integer.MAX_VALUE;
140+ // This is the increment we expect to apply:
141+ int unit = 1 << (KX * KX_LG2BASE);
142+ int mask = KB_MAX << (KX * KX_LG2BASE);
143+ int K1 = K + unit;
144+ K1 &= ~(unit-1); // cut off stray low-order bits
145+ if (((K1 - unit) & ~mask) == 0) {
146+ assert(getKXOf(K1) == KX);
147+ return K1;
148+ }
149+ if (KX == KX_MAX) return Integer.MAX_VALUE;
150+ KX += 1;
151+ int mask2 = KB_MAX << (KX * KX_LG2BASE);
152+ K1 |= (mask & ~mask2);
153+ K1 += unit;
154+ assert(getKXOf(K1) == KX);
155+ return K1;
156+ }
157+
158+ // Is K of the form ((KB:[0..255])+1) * 16^(KX:{0..3])?
159+ public static boolean isCodableLength(int K) {
160+ int KX = getKXOf(K);
161+ if (KX < 0) return false;
162+ int unit = 1 << (KX * KX_LG2BASE);
163+ int mask = KB_MAX << (KX * KX_LG2BASE);
164+ return ((K - unit) & ~mask) == 0;
165+ }
166+
167+ public byte[] getMetaCoding(Coding dflt) {
168+ //assert(!isTrivial()); // can happen
169+ // See the isCodableLength restriction in CodingChooser.
170+ ByteArrayOutputStream bytes = new ByteArrayOutputStream(10);
171+ try {
172+ makeMetaCoding(this, dflt, bytes);
173+ } catch (IOException ee) {
174+ throw new RuntimeException(ee);
175+ }
176+ return bytes.toByteArray();
177+ }
178+ private static void makeMetaCoding(AdaptiveCoding run, Coding dflt,
179+ ByteArrayOutputStream bytes)
180+ throws IOException {
181+ for (;;) {
182+ CodingMethod headCoding = run.headCoding;
183+ int headLength = run.headLength;
184+ CodingMethod tailCoding = run.tailCoding;
185+ int K = headLength;
186+ assert(isCodableLength(K));
187+ int ADef = (headCoding == dflt)?1:0;
188+ int BDef = (tailCoding == dflt)?1:0;
189+ if (ADef+BDef > 1) BDef = 0; // arbitrary choice
190+ int ABDef = 1*ADef + 2*BDef;
191+ assert(ABDef < 3);
192+ int KX = getKXOf(K);
193+ int KB = getKBOf(K);
194+ assert(decodeK(KX, KB) == K);
195+ int KBFlag = (KB != KB_DEFAULT)?1:0;
196+ bytes.write(_meta_run + KX + 4*KBFlag + 8*ABDef);
197+ if (KBFlag != 0) bytes.write(KB);
198+ if (ADef == 0) bytes.write(headCoding.getMetaCoding(dflt));
199+ if (tailCoding instanceof AdaptiveCoding) {
200+ run = (AdaptiveCoding) tailCoding;
201+ continue; // tail call, to avoid deep stack recursion
202+ }
203+ if (BDef == 0) bytes.write(tailCoding.getMetaCoding(dflt));
204+ break;
205+ }
206+ }
207+ public static int parseMetaCoding(byte[] bytes, int pos, Coding dflt, CodingMethod res[]) {
208+ int op = bytes[pos++] & 0xFF;
209+ if (op < _meta_run || op >= _meta_pop) return pos-1; // backup
210+ AdaptiveCoding prevc = null;
211+ for (boolean keepGoing = true; keepGoing; ) {
212+ keepGoing = false;
213+ assert(op >= _meta_run);
214+ op -= _meta_run;
215+ int KX = op % 4;
216+ int KBFlag = (op / 4) % 2;
217+ int ABDef = (op / 8);
218+ assert(ABDef < 3);
219+ int ADef = (ABDef & 1);
220+ int BDef = (ABDef & 2);
221+ CodingMethod[] ACode = {dflt}, BCode = {dflt};
222+ int KB = KB_DEFAULT;
223+ if (KBFlag != 0)
224+ KB = bytes[pos++] & 0xFF;
225+ if (ADef == 0) {
226+ pos = BandStructure.parseMetaCoding(bytes, pos, dflt, ACode);
227+ }
228+ if (BDef == 0 &&
229+ ((op = bytes[pos] & 0xFF) >= _meta_run) && op < _meta_pop) {
230+ pos++;
231+ keepGoing = true;
232+ } else if (BDef == 0) {
233+ pos = BandStructure.parseMetaCoding(bytes, pos, dflt, BCode);
234+ }
235+ AdaptiveCoding newc = new AdaptiveCoding(decodeK(KX, KB),
236+ ACode[0], BCode[0]);
237+ if (prevc == null) {
238+ res[0] = newc;
239+ } else {
240+ prevc.tailCoding = newc;
241+ }
242+ prevc = newc;
243+ }
244+ return pos;
245+ }
246+
247+ private String keyString(CodingMethod m) {
248+ if (m instanceof Coding)
249+ return ((Coding)m).keyString();
250+ return m.toString();
251+ }
252+ public String toString() {
253+ StringBuilder res = new StringBuilder(20);
254+ AdaptiveCoding run = this;
255+ res.append("run(");
256+ for (;;) {
257+ res.append(run.headLength).append("*");
258+ res.append(keyString(run.headCoding));
259+ if (run.tailCoding instanceof AdaptiveCoding) {
260+ run = (AdaptiveCoding) run.tailCoding;
261+ res.append(" ");
262+ continue;
263+ }
264+ break;
265+ }
266+ res.append(" **").append(keyString(run.tailCoding));
267+ res.append(")");
268+ return res.toString();
269+ }
270+
271+/*
272+ public static void main(String av[]) {
273+ int[][] samples = {
274+ {1,2,3,4,5},
275+ {254,255,256,256+1*16,256+2*16},
276+ {0xfd,0xfe,0xff,0x100,0x110,0x120,0x130},
277+ {0xfd0,0xfe0,0xff0,0x1000,0x1100,0x1200,0x1300},
278+ {0xfd00,0xfe00,0xff00,0x10000,0x11000,0x12000,0x13000},
279+ {0xfd000,0xfe000,0xff000,0x100000}
280+ };
281+ for (int i = 0; i < samples.length; i++) {
282+ for (int j = 0; j < samples[i].length; j++) {
283+ int K = samples[i][j];
284+ int KX = getKXOf(K);
285+ int KB = getKBOf(K);
286+ System.out.println("K="+Integer.toHexString(K)+
287+ " KX="+KX+" KB="+KB);
288+ assert(isCodableLength(K));
289+ assert(K == decodeK(KX, KB));
290+ if (j == 0) continue;
291+ int K1 = samples[i][j-1];
292+ assert(K == getNextK(K1));
293+ }
294+ }
295+ }
296+//*/
297+
298+}