1 30 package org.objectweb.asm; 31 32 38 final class AnnotationWriter implements AnnotationVisitor { 39 40 43 private final ClassWriter cw; 44 45 48 private int size; 49 50 55 private final boolean named; 56 57 62 private final ByteVector bv; 63 64 68 private final ByteVector parent; 69 70 74 private final int offset; 75 76 79 AnnotationWriter next; 80 81 84 AnnotationWriter prev; 85 86 90 100 AnnotationWriter( 101 final ClassWriter cw, 102 final boolean named, 103 final ByteVector bv, 104 final ByteVector parent, 105 final int offset) 106 { 107 this.cw = cw; 108 this.named = named; 109 this.bv = bv; 110 this.parent = parent; 111 this.offset = offset; 112 } 113 114 118 public void visit(final String name, final Object value) { 119 ++size; 120 if (named) { 121 bv.putShort(cw.newUTF8(name)); 122 } 123 if (value instanceof String ) { 124 bv.put12('s', cw.newUTF8((String ) value)); 125 } else if (value instanceof Byte ) { 126 bv.put12('B', cw.newInteger(((Byte ) value).byteValue()).index); 127 } else if (value instanceof Boolean ) { 128 int v = ((Boolean ) value).booleanValue() ? 1 : 0; 129 bv.put12('Z', cw.newInteger(v).index); 130 } else if (value instanceof Character ) { 131 bv.put12('C', cw.newInteger(((Character ) value).charValue()).index); 132 } else if (value instanceof Short ) { 133 bv.put12('S', cw.newInteger(((Short ) value).shortValue()).index); 134 } else if (value instanceof Type) { 135 bv.put12('c', cw.newUTF8(((Type) value).getDescriptor())); 136 } else if (value instanceof byte[]) { 137 byte[] v = (byte[]) value; 138 bv.put12('[', v.length); 139 for (int i = 0; i < v.length; i++) { 140 bv.put12('B', cw.newInteger(v[i]).index); 141 } 142 } else if (value instanceof boolean[]) { 143 boolean[] v = (boolean[]) value; 144 bv.put12('[', v.length); 145 for (int i = 0; i < v.length; i++) { 146 bv.put12('Z', cw.newInteger(v[i] ? 1 : 0).index); 147 } 148 } else if (value instanceof short[]) { 149 short[] v = (short[]) value; 150 bv.put12('[', v.length); 151 for (int i = 0; i < v.length; i++) { 152 bv.put12('S', cw.newInteger(v[i]).index); 153 } 154 } else if (value instanceof char[]) { 155 char[] v = (char[]) value; 156 bv.put12('[', v.length); 157 for (int i = 0; i < v.length; i++) { 158 bv.put12('C', cw.newInteger(v[i]).index); 159 } 160 } else if (value instanceof int[]) { 161 int[] v = (int[]) value; 162 bv.put12('[', v.length); 163 for (int i = 0; i < v.length; i++) { 164 bv.put12('I', cw.newInteger(v[i]).index); 165 } 166 } else if (value instanceof long[]) { 167 long[] v = (long[]) value; 168 bv.put12('[', v.length); 169 for (int i = 0; i < v.length; i++) { 170 bv.put12('J', cw.newLong(v[i]).index); 171 } 172 } else if (value instanceof float[]) { 173 float[] v = (float[]) value; 174 bv.put12('[', v.length); 175 for (int i = 0; i < v.length; i++) { 176 bv.put12('F', cw.newFloat(v[i]).index); 177 } 178 } else if (value instanceof double[]) { 179 double[] v = (double[]) value; 180 bv.put12('[', v.length); 181 for (int i = 0; i < v.length; i++) { 182 bv.put12('D', cw.newDouble(v[i]).index); 183 } 184 } else { 185 Item i = cw.newConstItem(value); 186 bv.put12(i.type, i.index); 187 } 188 } 189 190 public void visitEnum( 191 final String name, 192 final String desc, 193 final String value) 194 { 195 ++size; 196 if (named) { 197 bv.putShort(cw.newUTF8(name)); 198 } 199 bv.put12('e', cw.newUTF8(desc)).putShort(cw.newUTF8(value)); 200 } 201 202 public AnnotationVisitor visitAnnotation( 203 final String name, 204 final String desc) 205 { 206 ++size; 207 if (named) { 208 bv.putShort(cw.newUTF8(name)); 209 } 210 bv.put12('@', cw.newUTF8(desc)).putShort(0); 212 return new AnnotationWriter(cw, true, bv, bv, bv.length - 2); 213 } 214 215 public AnnotationVisitor visitArray(final String name) { 216 ++size; 217 if (named) { 218 bv.putShort(cw.newUTF8(name)); 219 } 220 bv.put12('[', 0); 222 return new AnnotationWriter(cw, false, bv, bv, bv.length - 2); 223 } 224 225 public void visitEnd() { 226 if (parent != null) { 227 byte[] data = parent.data; 228 data[offset] = (byte) (size >>> 8); 229 data[offset + 1] = (byte) size; 230 } 231 } 232 233 237 242 int getSize() { 243 int size = 0; 244 AnnotationWriter aw = this; 245 while (aw != null) { 246 size += aw.bv.length; 247 aw = aw.next; 248 } 249 return size; 250 } 251 252 258 void put(final ByteVector out) { 259 int n = 0; 260 int size = 2; 261 AnnotationWriter aw = this; 262 AnnotationWriter last = null; 263 while (aw != null) { 264 ++n; 265 size += aw.bv.length; 266 aw.visitEnd(); aw.prev = last; 268 last = aw; 269 aw = aw.next; 270 } 271 out.putInt(size); 272 out.putShort(n); 273 aw = last; 274 while (aw != null) { 275 out.putByteArray(aw.bv.data, 0, aw.bv.length); 276 aw = aw.prev; 277 } 278 } 279 280 286 static void put(final AnnotationWriter[] panns, final ByteVector out) { 287 int size = 1 + 2 * panns.length; 288 for (int i = 0; i < panns.length; ++i) { 289 size += panns[i] == null ? 0 : panns[i].getSize(); 290 } 291 out.putInt(size).putByte(panns.length); 292 for (int i = 0; i < panns.length; ++i) { 293 AnnotationWriter aw = panns[i]; 294 AnnotationWriter last = null; 295 int n = 0; 296 while (aw != null) { 297 ++n; 298 aw.visitEnd(); aw.prev = last; 300 last = aw; 301 aw = aw.next; 302 } 303 out.putShort(n); 304 aw = last; 305 while (aw != null) { 306 out.putByteArray(aw.bv.data, 0, aw.bv.length); 307 aw = aw.prev; 308 } 309 } 310 } 311 } 312 | Popular Tags |