1 /* 2 * Copyright (C) 2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.dx.dex.code; 18 19 import com.android.dx.util.FixedSizeList; 20 21 /** 22 * Table of catch entries. Each entry includes a range of code 23 * addresses for which it is valid and an associated {@link 24 * CatchHandlerList}. 25 */ 26 public final class CatchTable extends FixedSizeList 27 implements Comparable<CatchTable> { 28 /** {@code non-null;} empty instance */ 29 public static final CatchTable EMPTY = new CatchTable(0); 30 31 /** 32 * Constructs an instance. All indices initially contain {@code null}. 33 * 34 * @param size {@code >= 0;} the size of the table 35 */ 36 public CatchTable(int size) { 37 super(size); 38 } 39 40 /** 41 * Gets the element at the given index. It is an error to call 42 * this with the index for an element which was never set; if you 43 * do that, this will throw {@code NullPointerException}. 44 * 45 * @param n {@code >= 0, < size();} which index 46 * @return {@code non-null;} element at that index 47 */ 48 public Entry get(int n) { 49 return (Entry) get0(n); 50 } 51 52 /** 53 * Sets the entry at the given index. 54 * 55 * @param n {@code >= 0, < size();} which index 56 * @param entry {@code non-null;} the entry to set at {@code n} 57 */ 58 public void set(int n, Entry entry) { 59 set0(n, entry); 60 } 61 62 /** {@inheritDoc} */ 63 @Override 64 public int compareTo(CatchTable other) { 65 if (this == other) { 66 // Easy out. 67 return 0; 68 } 69 70 int thisSize = size(); 71 int otherSize = other.size(); 72 int checkSize = Math.min(thisSize, otherSize); 73 74 for (int i = 0; i < checkSize; i++) { 75 Entry thisEntry = get(i); 76 Entry otherEntry = other.get(i); 77 int compare = thisEntry.compareTo(otherEntry); 78 if (compare != 0) { 79 return compare; 80 } 81 } 82 83 if (thisSize < otherSize) { 84 return -1; 85 } else if (thisSize > otherSize) { 86 return 1; 87 } 88 89 return 0; 90 } 91 92 /** 93 * Entry in a catch list. 94 */ 95 public static class Entry implements Comparable<Entry> { 96 /** {@code >= 0;} start address */ 97 private final int start; 98 99 /** {@code > start;} end address (exclusive) */ 100 private final int end; 101 102 /** {@code non-null;} list of catch handlers */ 103 private final CatchHandlerList handlers; 104 105 /** 106 * Constructs an instance. 107 * 108 * @param start {@code >= 0;} start address 109 * @param end {@code > start;} end address (exclusive) 110 * @param handlers {@code non-null;} list of catch handlers 111 */ 112 public Entry(int start, int end, CatchHandlerList handlers) { 113 if (start < 0) { 114 throw new IllegalArgumentException("start < 0"); 115 } 116 117 if (end <= start) { 118 throw new IllegalArgumentException("end <= start"); 119 } 120 121 if (handlers.isMutable()) { 122 throw new IllegalArgumentException("handlers.isMutable()"); 123 } 124 125 this.start = start; 126 this.end = end; 127 this.handlers = handlers; 128 } 129 130 /** {@inheritDoc} */ 131 @Override 132 public int hashCode() { 133 int hash = (start * 31) + end; 134 hash = (hash * 31) + handlers.hashCode(); 135 return hash; 136 } 137 138 /** {@inheritDoc} */ 139 @Override 140 public boolean equals(Object other) { 141 if (other instanceof Entry) { 142 return (compareTo((Entry) other) == 0); 143 } 144 145 return false; 146 } 147 148 /** {@inheritDoc} */ 149 @Override 150 public int compareTo(Entry other) { 151 if (start < other.start) { 152 return -1; 153 } else if (start > other.start) { 154 return 1; 155 } 156 157 if (end < other.end) { 158 return -1; 159 } else if (end > other.end) { 160 return 1; 161 } 162 163 return handlers.compareTo(other.handlers); 164 } 165 166 /** 167 * Gets the start address. 168 * 169 * @return {@code >= 0;} the start address 170 */ 171 public int getStart() { 172 return start; 173 } 174 175 /** 176 * Gets the end address (exclusive). 177 * 178 * @return {@code > start;} the end address (exclusive) 179 */ 180 public int getEnd() { 181 return end; 182 } 183 184 /** 185 * Gets the handlers. 186 * 187 * @return {@code non-null;} the handlers 188 */ 189 public CatchHandlerList getHandlers() { 190 return handlers; 191 } 192 } 193 } 194