1/*
2 * reserved comment block
3 * DO NOT REMOVE OR ALTER!
4 */
5/*
6 * Licensed to the Apache Software Foundation (ASF) under one or more
7 * contributor license agreements.  See the NOTICE file distributed with
8 * this work for additional information regarding copyright ownership.
9 * The ASF licenses this file to You under the Apache License, Version 2.0
10 * (the "License"); you may not use this file except in compliance with
11 * the License.  You may obtain a copy of the License at
12 *
13 *      http://www.apache.org/licenses/LICENSE-2.0
14 *
15 * Unless required by applicable law or agreed to in writing, software
16 * distributed under the License is distributed on an "AS IS" BASIS,
17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 * See the License for the specific language governing permissions and
19 * limitations under the License.
20 */
21
22package com.sun.org.apache.bcel.internal.generic;
23
24import java.io.DataOutputStream;
25import java.io.IOException;
26
27import com.sun.org.apache.bcel.internal.util.ByteSequence;
28
29/**
30 * TABLESWITCH - Switch within given range of values, i.e., low..high
31 *
32 * @version $Id: TABLESWITCH.java 1749603 2016-06-21 20:50:19Z ggregory $
33 * @see SWITCH
34 */
35public class TABLESWITCH extends Select {
36
37    /**
38     * Empty constructor needed for the Class.newInstance() statement in
39     * Instruction.readInstruction(). Not to be used otherwise.
40     */
41    TABLESWITCH() {
42    }
43
44
45    /**
46     * @param match sorted array of match values, match[0] must be low value,
47     * match[match_length - 1] high value
48     * @param targets where to branch for matched values
49     * @param defaultTarget default branch
50     */
51    public TABLESWITCH(final int[] match, final InstructionHandle[] targets, final InstructionHandle defaultTarget) {
52        super(com.sun.org.apache.bcel.internal.Const.TABLESWITCH, match, targets, defaultTarget);
53        /* Alignment remainder assumed 0 here, until dump time */
54        final short _length = (short) (13 + getMatch_length() * 4);
55        super.setLength(_length);
56        setFixed_length(_length);
57    }
58
59
60    /**
61     * Dump instruction as byte code to stream out.
62     * @param out Output stream
63     */
64    @Override
65    public void dump( final DataOutputStream out ) throws IOException {
66        super.dump(out);
67        final int _match_length = getMatch_length();
68        final int low = (_match_length > 0) ? super.getMatch(0) : 0;
69        out.writeInt(low);
70        final int high = (_match_length > 0) ? super.getMatch(_match_length - 1) : 0;
71        out.writeInt(high);
72        for (int i = 0; i < _match_length; i++) {
73            out.writeInt(setIndices(i, getTargetOffset(super.getTarget(i))));
74        }
75    }
76
77
78    /**
79     * Read needed data (e.g. index) from file.
80     */
81    @Override
82    protected void initFromFile( final ByteSequence bytes, final boolean wide ) throws IOException {
83        super.initFromFile(bytes, wide);
84        final int low = bytes.readInt();
85        final int high = bytes.readInt();
86        final int _match_length = high - low + 1;
87        setMatch_length(_match_length);
88        final short _fixed_length = (short) (13 + _match_length * 4);
89        setFixed_length(_fixed_length);
90        super.setLength((short) (_fixed_length + super.getPadding()));
91        super.setMatches(new int[_match_length]);
92        super.setIndices(new int[_match_length]);
93        super.setTargets(new InstructionHandle[_match_length]);
94        for (int i = 0; i < _match_length; i++) {
95            super.setMatch(i, low + i);
96            super.setIndices(i, bytes.readInt());
97        }
98    }
99
100
101    /**
102     * Call corresponding visitor method(s). The order is:
103     * Call visitor methods of implemented interfaces first, then
104     * call methods according to the class hierarchy in descending order,
105     * i.e., the most specific visitXXX() call comes last.
106     *
107     * @param v Visitor object
108     */
109    @Override
110    public void accept( final Visitor v ) {
111        v.visitVariableLengthInstruction(this);
112        v.visitStackConsumer(this);
113        v.visitBranchInstruction(this);
114        v.visitSelect(this);
115        v.visitTABLESWITCH(this);
116    }
117}
118