1f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 2f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project 3f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 4f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 5f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * you may not use this file except in compliance with the License. 6f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * You may obtain a copy of the License at 7f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 8f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 9f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 10f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 11f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 12f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * See the License for the specific language governing permissions and 14f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * limitations under the License. 15f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 16f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 17f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpackage com.android.dx.cf.code; 18f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 19f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.util.IntList; 20f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.util.MutabilityControl; 21f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 22f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/** 23f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * List of (value, target) mappings representing the choices of a 2499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * {@code tableswitch} or {@code lookupswitch} instruction. It 25f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * also holds the default target for the switch. 26f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 27f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpublic final class SwitchList extends MutabilityControl { 2899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project /** {@code non-null;} list of test values */ 29f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private final IntList values; 30f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 31f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 3299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * {@code non-null;} list of targets corresponding to the test values; there 33f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * is always one extra element in the target list, to hold the 34de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * default target 35f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 36f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private final IntList targets; 37f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 38f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** ultimate size of the list */ 39f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private int size; 40f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 41f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 42f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Constructs an instance. 43de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 4499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param size {@code >= 0;} the number of elements to be in the table 45f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 46f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public SwitchList(int size) { 47f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project super(true); 48f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this.values = new IntList(size); 49f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this.targets = new IntList(size + 1); 50f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this.size = size; 51f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 52f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 53f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** {@inheritDoc} */ 54f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project @Override 55f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public void setImmutable() { 56f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project values.setImmutable(); 57f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project targets.setImmutable(); 58f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project super.setImmutable(); 59f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 60f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 61f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 62f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Gets the size of the list. 63de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 6499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code >= 0;} the list size 65f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 66f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public int size() { 67f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return size; 68f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 69f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 70f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 71f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Gets the indicated test value. 72de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 7399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param n {@code >= 0;}, < size(); which index 74de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * @return the test value 75f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 76f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public int getValue(int n) { 77f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return values.get(n); 78f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 79f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 80f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 8199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * Gets the indicated target. Asking for the target at {@code size()} 82f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * returns the default target. 83de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 8499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param n {@code >= 0, <= size();} which index 8599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code >= 0;} the target 86f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 87f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public int getTarget(int n) { 88f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return targets.get(n); 89f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 90f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 91f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 92f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Gets the default target. This is just a shorthand for 9399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * {@code getTarget(size())}. 94de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 9599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code >= 0;} the default target 96f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 97f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public int getDefaultTarget() { 98f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return targets.get(size); 99f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Gets the list of all targets. This includes one extra element at the 103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * end of the list, which holds the default target. 104de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 10599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code non-null;} the target list 106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public IntList getTargets() { 108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return targets; 109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Gets the list of all case values. 113de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 11499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code non-null;} the case value list 115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public IntList getValues() { 117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return values; 118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 120f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Sets the default target. It is only valid to call this method 122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * when all the non-default elements have been set. 123de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 12499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param target {@code >= 0;} the absolute (not relative) default target 125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * address 126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public void setDefaultTarget(int target) { 128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throwIfImmutable(); 129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (target < 0) { 131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new IllegalArgumentException("target < 0"); 132f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (targets.size() != size) { 135f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new RuntimeException("non-default elements not all set"); 136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project targets.add(target); 139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Adds the given item. 143de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param value the test value 14599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param target {@code >= 0;} the absolute (not relative) target address 146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public void add(int value, int target) { 148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throwIfImmutable(); 149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (target < 0) { 151f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new IllegalArgumentException("target < 0"); 152f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 153f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project values.add(value); 155f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project targets.add(target); 156f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 157f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 158f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 159f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Shrinks this instance if possible, removing test elements that 160f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * refer to the default target. This is only valid after the instance 161f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * is fully populated, including the default target (naturally). 162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public void removeSuperfluousDefaults() { 164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throwIfImmutable(); 165f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int sz = size; 167f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 168f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (sz != (targets.size() - 1)) { 169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new IllegalArgumentException("incomplete instance"); 170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int defaultTarget = targets.get(sz); 173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int at = 0; 174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (int i = 0; i < sz; i++) { 176f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int target = targets.get(i); 177f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (target != defaultTarget) { 178f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (i != at) { 179f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project targets.set(at, target); 180f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project values.set(at, values.get(i)); 181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project at++; 183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 185f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 186f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (at != sz) { 187f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project values.shrink(at); 188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project targets.set(at, defaultTarget); 189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project targets.shrink(at + 1); 190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project size = at; 191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 194