summaryrefslogtreecommitdiff
path: root/dx/src/com/android/dx/cf/code/LineNumberList.java
diff options
context:
space:
mode:
Diffstat (limited to 'dx/src/com/android/dx/cf/code/LineNumberList.java')
-rw-r--r--dx/src/com/android/dx/cf/code/LineNumberList.java184
1 files changed, 184 insertions, 0 deletions
diff --git a/dx/src/com/android/dx/cf/code/LineNumberList.java b/dx/src/com/android/dx/cf/code/LineNumberList.java
new file mode 100644
index 0000000..f54f8b5
--- /dev/null
+++ b/dx/src/com/android/dx/cf/code/LineNumberList.java
@@ -0,0 +1,184 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.dx.cf.code;
+
+import com.android.dx.util.FixedSizeList;
+
+/**
+ * List of "line number" entries, which are the contents of
+ * {@code LineNumberTable} attributes.
+ */
+public final class LineNumberList extends FixedSizeList {
+ /** {@code non-null;} zero-size instance */
+ public static final LineNumberList EMPTY = new LineNumberList(0);
+
+ /**
+ * Returns an instance which is the concatenation of the two given
+ * instances.
+ *
+ * @param list1 {@code non-null;} first instance
+ * @param list2 {@code non-null;} second instance
+ * @return {@code non-null;} combined instance
+ */
+ public static LineNumberList concat(LineNumberList list1,
+ LineNumberList list2) {
+ if (list1 == EMPTY) {
+ // easy case
+ return list2;
+ }
+
+ int sz1 = list1.size();
+ int sz2 = list2.size();
+ LineNumberList result = new LineNumberList(sz1 + sz2);
+
+ for (int i = 0; i < sz1; i++) {
+ result.set(i, list1.get(i));
+ }
+
+ for (int i = 0; i < sz2; i++) {
+ result.set(sz1 + i, list2.get(i));
+ }
+
+ return result;
+ }
+
+ /**
+ * Constructs an instance.
+ *
+ * @param count the number of elements to be in the list
+ */
+ public LineNumberList(int count) {
+ super(count);
+ }
+
+ /**
+ * Gets the indicated item.
+ *
+ * @param n {@code >= 0;} which item
+ * @return {@code null-ok;} the indicated item
+ */
+ public Item get(int n) {
+ return (Item) get0(n);
+ }
+
+ /**
+ * Sets the item at the given index.
+ *
+ * @param n {@code >= 0, < size();} which element
+ * @param item {@code non-null;} the item
+ */
+ public void set(int n, Item item) {
+ if (item == null) {
+ throw new NullPointerException("item == null");
+ }
+
+ set0(n, item);
+ }
+
+ /**
+ * Sets the item at the given index.
+ *
+ * @param n {@code >= 0, < size();} which element
+ * @param startPc {@code >= 0;} start pc of this item
+ * @param lineNumber {@code >= 0;} corresponding line number
+ */
+ public void set(int n, int startPc, int lineNumber) {
+ set0(n, new Item(startPc, lineNumber));
+ }
+
+ /**
+ * Gets the line number associated with the given address.
+ *
+ * @param pc {@code >= 0;} the address to look up
+ * @return {@code >= -1;} the associated line number, or {@code -1} if
+ * none is known
+ */
+ public int pcToLine(int pc) {
+ /*
+ * Line number entries don't have to appear in any particular
+ * order, so we have to do a linear search. TODO: If
+ * this turns out to be a bottleneck, consider sorting the
+ * list prior to use.
+ */
+ int sz = size();
+ int bestPc = -1;
+ int bestLine = -1;
+
+ for (int i = 0; i < sz; i++) {
+ Item one = get(i);
+ int onePc = one.getStartPc();
+ if ((onePc <= pc) && (onePc > bestPc)) {
+ bestPc = onePc;
+ bestLine = one.getLineNumber();
+ if (bestPc == pc) {
+ // We can't do better than this
+ break;
+ }
+ }
+ }
+
+ return bestLine;
+ }
+
+ /**
+ * Item in a line number table.
+ */
+ public static class Item {
+ /** {@code >= 0;} start pc of this item */
+ private final int startPc;
+
+ /** {@code >= 0;} corresponding line number */
+ private final int lineNumber;
+
+ /**
+ * Constructs an instance.
+ *
+ * @param startPc {@code >= 0;} start pc of this item
+ * @param lineNumber {@code >= 0;} corresponding line number
+ */
+ public Item(int startPc, int lineNumber) {
+ if (startPc < 0) {
+ throw new IllegalArgumentException("startPc < 0");
+ }
+
+ if (lineNumber < 0) {
+ throw new IllegalArgumentException("lineNumber < 0");
+ }
+
+ this.startPc = startPc;
+ this.lineNumber = lineNumber;
+ }
+
+ /**
+ * Gets the start pc of this item.
+ *
+ * @return the start pc
+ */
+ public int getStartPc() {
+ return startPc;
+ }
+
+ /**
+ * Gets the line number of this item.
+ *
+ * @return the line number
+ */
+ public int getLineNumber() {
+ return lineNumber;
+ }
+ }
+}