/** Parses an {@code InnerClasses} attribute. */ private Attribute innerClasses( DirectClassFile cf, int offset, int length, ParseObserver observer) { if (length < 2) { return throwSeverelyTruncated(); } ByteArray bytes = cf.getBytes(); ConstantPool pool = cf.getConstantPool(); int count = bytes.getUnsignedShort(offset); // number_of_classes if (observer != null) { observer.parsed(bytes, offset, 2, "number_of_classes: " + Hex.u2(count)); } offset += 2; length -= 2; if (length != (count * 8)) { throwBadLength((count * 8) + 2); } InnerClassList list = new InnerClassList(count); for (int i = 0; i < count; i++) { int innerClassIdx = bytes.getUnsignedShort(offset); int outerClassIdx = bytes.getUnsignedShort(offset + 2); int nameIdx = bytes.getUnsignedShort(offset + 4); int accessFlags = bytes.getUnsignedShort(offset + 6); CstType innerClass = (CstType) pool.get(innerClassIdx); CstType outerClass = (CstType) pool.get0Ok(outerClassIdx); CstString name = (CstString) pool.get0Ok(nameIdx); list.set(i, innerClass, outerClass, name, accessFlags); if (observer != null) { observer.parsed( bytes, offset, 2, "inner_class: " + DirectClassFile.stringOrNone(innerClass)); observer.parsed( bytes, offset + 2, 2, " outer_class: " + DirectClassFile.stringOrNone(outerClass)); observer.parsed(bytes, offset + 4, 2, " name: " + DirectClassFile.stringOrNone(name)); observer.parsed( bytes, offset + 6, 2, " access_flags: " + AccessFlags.innerClassString(accessFlags)); } offset += 8; } list.setImmutable(); return new AttInnerClasses(list); }
/** Parses an {@code EnclosingMethod} attribute. */ private Attribute enclosingMethod( DirectClassFile cf, int offset, int length, ParseObserver observer) { if (length != 4) { throwBadLength(4); } ByteArray bytes = cf.getBytes(); ConstantPool pool = cf.getConstantPool(); int idx = bytes.getUnsignedShort(offset); CstType type = (CstType) pool.get(idx); idx = bytes.getUnsignedShort(offset + 2); CstNat method = (CstNat) pool.get0Ok(idx); Attribute result = new AttEnclosingMethod(type, method); if (observer != null) { observer.parsed(bytes, offset, 2, "class: " + type); observer.parsed(bytes, offset + 2, 2, "method: " + DirectClassFile.stringOrNone(method)); } return result; }