Rebasing the Inflater support on jzlib which, unlike GNU ClassPath, has correct implementation of Huffman code. Making the implementation more easily testable by turning Inflater and ZipInputStream into pure delegates. Current implementation is going to need proper long support.
2 * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
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.
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).
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.
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
27 package org.apidesign.javap;
31 import static org.apidesign.javap.RuntimeConstants.*;
33 /* represents one entry of StackMapTable attribute
35 abstract class StackMapTableData {
39 StackMapTableData(int frameType) {
40 this.frameType = frameType;
43 abstract void applyTo(TypeArray localTypes, TypeArray stackTypes);
45 protected static String toString(
46 final String frameType,
48 final int[] localTypes,
49 final int[] stackTypes) {
50 final StringBuilder sb = new StringBuilder(frameType);
52 sb.append("(off: +").append(offset);
53 if (localTypes != null) {
54 sb.append(", locals: ");
55 appendTypes(sb, localTypes);
57 if (stackTypes != null) {
58 sb.append(", stack: ");
59 appendTypes(sb, stackTypes);
66 private static void appendTypes(final StringBuilder sb, final int[] types) {
68 if (types.length > 0) {
69 sb.append(TypeArray.typeString(types[0]));
70 for (int i = 1; i < types.length; ++i) {
72 sb.append(TypeArray.typeString(types[i]));
78 static class SameFrame extends StackMapTableData {
79 SameFrame(int frameType, int offsetDelta) {
81 this.offsetDelta = offsetDelta;
85 void applyTo(TypeArray localTypes, TypeArray stackTypes) {
90 public String toString() {
91 return toString("SAME" + ((frameType == SAME_FRAME_EXTENDED)
92 ? "_FRAME_EXTENDED" : ""),
98 static class SameLocals1StackItem extends StackMapTableData {
100 SameLocals1StackItem(int frameType, int offsetDelta, int[] stack) {
102 this.offsetDelta = offsetDelta;
107 void applyTo(TypeArray localTypes, TypeArray stackTypes) {
108 stackTypes.setAll(stack);
112 public String toString() {
114 "SAME_LOCALS_1_STACK_ITEM"
115 + ((frameType == SAME_LOCALS_1_STACK_ITEM_EXTENDED)
122 static class ChopFrame extends StackMapTableData {
123 ChopFrame(int frameType, int offsetDelta) {
125 this.offsetDelta = offsetDelta;
129 void applyTo(TypeArray localTypes, TypeArray stackTypes) {
130 localTypes.setSize(localTypes.getSize()
131 - (SAME_FRAME_EXTENDED - frameType));
136 public String toString() {
137 return toString("CHOP", offsetDelta, null, null);
141 static class AppendFrame extends StackMapTableData {
143 AppendFrame(int frameType, int offsetDelta, int[] locals) {
145 this.offsetDelta = offsetDelta;
146 this.locals = locals;
150 void applyTo(TypeArray localTypes, TypeArray stackTypes) {
151 localTypes.addAll(locals);
156 public String toString() {
157 return toString("APPEND", offsetDelta, locals, null);
161 static class FullFrame extends StackMapTableData {
164 FullFrame(int offsetDelta, int[] locals, int[] stack) {
166 this.offsetDelta = offsetDelta;
167 this.locals = locals;
172 void applyTo(TypeArray localTypes, TypeArray stackTypes) {
173 localTypes.setAll(locals);
174 stackTypes.setAll(stack);
178 public String toString() {
179 return toString("FULL", offsetDelta, locals, stack);
183 static StackMapTableData getInstance(DataInputStream in, MethodData method)
185 int frameType = in.readUnsignedByte();
187 if (frameType < SAME_FRAME_BOUND) {
189 return new SameFrame(frameType, frameType);
190 } else if (SAME_FRAME_BOUND <= frameType && frameType < SAME_LOCALS_1_STACK_ITEM_BOUND) {
191 // same_locals_1_stack_item_frame
192 // read additional single stack element
193 return new SameLocals1StackItem(frameType,
194 (frameType - SAME_FRAME_BOUND),
195 StackMapData.readTypeArray(in, 1, method));
196 } else if (frameType == SAME_LOCALS_1_STACK_ITEM_EXTENDED) {
197 // same_locals_1_stack_item_extended
198 return new SameLocals1StackItem(frameType,
199 in.readUnsignedShort(),
200 StackMapData.readTypeArray(in, 1, method));
201 } else if (SAME_LOCALS_1_STACK_ITEM_EXTENDED < frameType && frameType < SAME_FRAME_EXTENDED) {
202 // chop_frame or same_frame_extended
203 return new ChopFrame(frameType, in.readUnsignedShort());
204 } else if (frameType == SAME_FRAME_EXTENDED) {
205 // chop_frame or same_frame_extended
206 return new SameFrame(frameType, in.readUnsignedShort());
207 } else if (SAME_FRAME_EXTENDED < frameType && frameType < FULL_FRAME) {
209 return new AppendFrame(frameType, in.readUnsignedShort(),
210 StackMapData.readTypeArray(in, frameType - SAME_FRAME_EXTENDED, method));
211 } else if (frameType == FULL_FRAME) {
213 int offsetDelta = in.readUnsignedShort();
214 int locals_size = in.readUnsignedShort();
215 int[] locals = StackMapData.readTypeArray(in, locals_size, method);
216 int stack_size = in.readUnsignedShort();
217 int[] stack = StackMapData.readTypeArray(in, stack_size, method);
218 return new FullFrame(offsetDelta, locals, stack);
220 throw new ClassFormatError("unrecognized frame_type in StackMapTable");