Home | History | Annotate | Download | only in code
      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