1 52 53 package com.go.trove.classfile; 54 55 import java.util.*; 56 import java.io.*; 57 58 66 class LineNumberTableAttr extends Attribute { 67 private List mEntries = new ArrayList(); 68 private boolean mClean = false; 69 70 public LineNumberTableAttr(ConstantPool cp) { 71 super(cp, LINE_NUMBER_TABLE); 72 } 73 74 public int getLineNumber(Location start) { 75 clean(); 76 int index = Collections.binarySearch(mEntries, new Entry(start, 0)); 77 if (index < 0) { 78 if ((index = -index - 2) < 0) { 79 return -1; 80 } 81 } 82 return ((Entry)mEntries.get(index)).mLineNumber; 83 } 84 85 public void addEntry(Location start, int line_number) { 86 check("line number", line_number); 87 mEntries.add(new Entry(start, line_number)); 88 mClean = false; 89 } 90 91 public int getLength() { 92 clean(); 93 return 2 + 4 * mEntries.size(); 94 } 95 96 public void writeDataTo(DataOutput dout) throws IOException { 97 int size = mEntries.size(); 98 dout.writeShort(size); 99 for (int i=0; i<size; i++) { 100 Entry entry = (Entry)mEntries.get(i); 101 102 int start_pc = entry.mStart.getLocation(); 103 104 check("line number table entry start PC", start_pc); 105 106 dout.writeShort(start_pc); 107 dout.writeShort(entry.mLineNumber); 108 } 109 } 110 111 private void check(String type, int addr) throws RuntimeException { 112 if (addr < 0 || addr > 65535) { 113 throw new RuntimeException ("Value for " + type + " out of " + 114 "valid range: " + addr); 115 116 } 117 } 118 119 private void clean() { 120 if (!mClean) { 121 mClean = true; 122 123 129 Set reduced = new TreeSet(); 130 for (int i = mEntries.size(); --i >= 0; ) { 131 reduced.add(mEntries.get(i)); 132 } 133 134 mEntries = new ArrayList(reduced); 135 } 136 } 137 138 static Attribute define(ConstantPool cp, 139 String name, 140 int length, 141 DataInput din) throws IOException { 142 143 LineNumberTableAttr lineNumbers = new LineNumberTableAttr(cp); 144 145 int size = din.readUnsignedShort(); 146 for (int i=0; i<size; i++) { 147 int start_pc = din.readUnsignedShort(); 148 int line_number = din.readUnsignedShort(); 149 150 lineNumbers.addEntry(new FixedLocation(start_pc), line_number); 151 } 152 153 return lineNumbers; 154 } 155 156 private static class Entry implements Comparable { 157 public final Location mStart; 158 public final int mLineNumber; 159 160 public Entry(Location start, int line_number) { 161 mStart = start; 162 mLineNumber = line_number; 163 } 164 165 public int compareTo(Object other) { 166 int thisLoc = mStart.getLocation(); 167 int thatLoc = ((Entry)other).mStart.getLocation(); 168 169 if (thisLoc < thatLoc) { 170 return -1; 171 } 172 else if (thisLoc > thatLoc) { 173 return 1; 174 } 175 else { 176 return 0; 177 } 178 } 179 180 public boolean equals(Object other) { 181 if (other instanceof Entry) { 182 return mStart.getLocation() == 183 ((Entry)other).mStart.getLocation(); 184 } 185 return false; 186 } 187 188 public String toString() { 189 return "start_pc=" + mStart.getLocation() + " => " + 190 "line_number=" + mLineNumber; 191 } 192 } 193 } 194 | Popular Tags |