--- a/jdk/test/tools/pack200/pack200-verifier/src/xmlkit/ClassWriter.java Wed May 09 13:08:07 2012 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,818 +0,0 @@
-/*
- * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package xmlkit; // -*- mode: java; indent-tabs-mode: nil -*-
-
-import java.util.*;
-import java.lang.reflect.*;
-import java.io.*;
-import xmlkit.XMLKit.Element;
-/*
- * @author jrose
- */
-public class ClassWriter extends ClassSyntax implements ClassSyntax.GetCPIndex {
-
- private static final CommandLineParser CLP = new CommandLineParser(""
- + "-source: +> = \n"
- + "-dest: +> = \n"
- + "-encoding: +> = \n"
- + "-parseBytes $ \n"
- + "- *? \n"
- + "\n");
-
- public static void main(String[] ava) throws IOException {
- ArrayList<String> av = new ArrayList<String>(Arrays.asList(ava));
- HashMap<String, String> props = new HashMap<String, String>();
- props.put("-encoding:", "UTF8"); // default
- CLP.parse(av, props);
- File source = asFile(props.get("-source:"));
- File dest = asFile(props.get("-dest:"));
- String encoding = props.get("-encoding:");
- boolean parseBytes = props.containsKey("-parseBytes");
- boolean destMade = false;
-
- for (String a : av) {
- File f;
- File inf = new File(source, a);
- System.out.println("Reading " + inf);
- Element e;
- if (inf.getName().endsWith(".class")) {
- ClassReader cr = new ClassReader();
- cr.parseBytes = parseBytes;
- e = cr.readFrom(inf);
- f = new File(a);
- } else if (inf.getName().endsWith(".xml")) {
- InputStream in = new FileInputStream(inf);
- Reader inw = ClassReader.makeReader(in, encoding);
- e = XMLKit.readFrom(inw);
- e.findAllInTree(XMLKit.and(XMLKit.elementFilter(nonAttrTags()),
- XMLKit.methodFilter(Element.method("trimText"))));
- //System.out.println(e);
- inw.close();
- f = new File(a.substring(0, a.length() - ".xml".length()) + ".class");
- } else {
- System.out.println("Warning: unknown input " + a);
- continue;
- }
- // Now write it:
- if (!destMade) {
- destMade = true;
- if (dest == null) {
- dest = File.createTempFile("TestOut", ".dir", new File("."));
- dest.delete();
- System.out.println("Writing results to " + dest);
- }
- if (!(dest.isDirectory() || dest.mkdir())) {
- throw new RuntimeException("Cannot create " + dest);
- }
- }
- File outf = new File(dest, f.isAbsolute() ? f.getName() : f.getPath());
- outf.getParentFile().mkdirs();
- new ClassWriter(e).writeTo(outf);
- }
- }
-
- private static File asFile(String str) {
- return (str == null) ? null : new File(str);
- }
-
- public void writeTo(File file) throws IOException {
- OutputStream out = null;
- try {
- out = new BufferedOutputStream(new FileOutputStream(file));
- writeTo(out);
- } finally {
- if (out != null) {
- out.close();
- }
- }
- }
- protected String[] callables; // varies
- protected int cpoolSize = 0;
- protected HashMap<String, String> attrTypesByTag;
- protected OutputStream out;
- protected HashMap<String, int[]> cpMap = new HashMap<String, int[]>();
- protected ArrayList<ByteArrayOutputStream> attrBufs = new ArrayList<ByteArrayOutputStream>();
-
- private void setupAttrTypes() {
- attrTypesByTag = new HashMap<String, String>();
- for (String key : attrTypes.keySet()) {
- String pfx = key.substring(0, key.indexOf('.') + 1);
- String val = attrTypes.get(key);
- int pos = val.indexOf('<');
- if (pos >= 0) {
- String tag = val.substring(pos + 1, val.indexOf('>', pos));
- attrTypesByTag.put(pfx + tag, key);
- }
- }
- //System.out.println("attrTypesByTag: "+attrTypesByTag);
- }
-
- protected ByteArrayOutputStream getAttrBuf() {
- int nab = attrBufs.size();
- if (nab == 0) {
- return new ByteArrayOutputStream(1024);
- }
- ByteArrayOutputStream ab = attrBufs.get(nab - 1);
- attrBufs.remove(nab - 1);
- return ab;
- }
-
- protected void putAttrBuf(ByteArrayOutputStream ab) {
- ab.reset();
- attrBufs.add(ab);
- }
-
- public ClassWriter(Element root) {
- this(root, null);
- }
-
- public ClassWriter(Element root, ClassSyntax cr) {
- if (cr != null) {
- attrTypes = cr.attrTypes;
- }
- setupAttrTypes();
- if (root.getName() == "ClassFile") {
- cfile = root;
- cpool = root.findElement("ConstantPool");
- klass = root.findElement("Class");
- } else if (root.getName() == "Class") {
- cfile = new Element("ClassFile",
- new String[]{
- "magic", String.valueOf(0xCAFEBABE),
- "minver", "0", "majver", "46",});
- cpool = new Element("ConstantPool");
- klass = root;
- } else {
- throw new IllegalArgumentException("bad element type " + root.getName());
- }
- if (cpool == null) {
- cpool = new Element("ConstantPool");
- }
-
- int cpLen = 1 + cpool.size();
- for (Element c : cpool.elements()) {
- int id = (int) c.getAttrLong("id");
- int tag = cpTagValue(c.getName());
- setCPIndex(tag, c.getText().toString(), id);
- switch (tag) {
- case CONSTANT_Long:
- case CONSTANT_Double:
- cpLen += 1;
- }
- }
- cpoolSize = cpLen;
- }
-
- public int findCPIndex(int tag, String name) {
- if (name == null) {
- return 0;
- }
- int[] ids = cpMap.get(name.toString());
- return (ids == null) ? 0 : ids[tag];
- }
-
- public int getCPIndex(int tag, String name) {
- //System.out.println("getCPIndex "+cpTagName(tag)+" "+name);
- if (name == null) {
- return 0;
- }
- int id = findCPIndex(tag, name);
- if (id == 0) {
- id = cpoolSize;
- cpoolSize += 1;
- setCPIndex(tag, name, id);
- cpool.add(new Element(cpTagName(tag),
- new String[]{"id", "" + id},
- new Object[]{name}));
- int pos;
- switch (tag) {
- case CONSTANT_Long:
- case CONSTANT_Double:
- cpoolSize += 1;
- break;
- case CONSTANT_Class:
- case CONSTANT_String:
- getCPIndex(CONSTANT_Utf8, name);
- break;
- case CONSTANT_Fieldref:
- case CONSTANT_Methodref:
- case CONSTANT_InterfaceMethodref:
- pos = name.indexOf(' ');
- getCPIndex(CONSTANT_Class, name.substring(0, pos));
- getCPIndex(CONSTANT_NameAndType, name.substring(pos + 1));
- break;
- case CONSTANT_NameAndType:
- pos = name.indexOf(' ');
- getCPIndex(CONSTANT_Utf8, name.substring(0, pos));
- getCPIndex(CONSTANT_Utf8, name.substring(pos + 1));
- break;
- }
- }
- return id;
- }
-
- public void setCPIndex(int tag, String name, int id) {
- //System.out.println("setCPIndex id="+id+" tag="+tag+" name="+name);
- int[] ids = cpMap.get(name);
- if (ids == null) {
- cpMap.put(name, ids = new int[13]);
- }
- if (ids[tag] != 0 && ids[tag] != id) {
- System.out.println("Warning: Duplicate CP entries for " + ids[tag] + " and " + id);
- }
- //assert(ids[tag] == 0 || ids[tag] == id);
- ids[tag] = id;
- }
-
- public int parseFlags(String flagString) {
- int flags = 0;
- int i = -1;
- for (String[] names : modifierNames) {
- ++i;
- for (String name : names) {
- if (name == null) {
- continue;
- }
- int pos = flagString.indexOf(name);
- if (pos >= 0) {
- flags |= (1 << i);
- }
- }
- }
- return flags;
- }
-
- public void writeTo(OutputStream realOut) throws IOException {
- OutputStream headOut = realOut;
- ByteArrayOutputStream tailOut = new ByteArrayOutputStream();
-
- // write the body of the class file first
- this.out = tailOut;
- writeClass();
-
- // write the file header last
- this.out = headOut;
- u4((int) cfile.getAttrLong("magic"));
- u2((int) cfile.getAttrLong("minver"));
- u2((int) cfile.getAttrLong("majver"));
- writeCP();
-
- // recopy the file tail
- this.out = null;
- tailOut.writeTo(realOut);
- }
-
- void writeClass() throws IOException {
- int flags = parseFlags(klass.getAttr("flags"));
- flags ^= Modifier.SYNCHRONIZED;
- u2(flags);
- cpRef(CONSTANT_Class, klass.getAttr("name"));
- cpRef(CONSTANT_Class, klass.getAttr("super"));
- Element interfaces = klass.findAllElements("Interface");
- u2(interfaces.size());
- for (Element e : interfaces.elements()) {
- cpRef(CONSTANT_Class, e.getAttr("name"));
- }
- for (int isMethod = 0; isMethod <= 1; isMethod++) {
- Element members = klass.findAllElements(isMethod != 0 ? "Method" : "Field");
- u2(members.size());
- for (Element m : members.elements()) {
- writeMember(m, isMethod != 0);
- }
- }
- writeAttributesFor(klass);
- }
-
- private void writeMember(Element member, boolean isMethod) throws IOException {
- //System.out.println("writeMember "+member);
- u2(parseFlags(member.getAttr("flags")));
- cpRef(CONSTANT_Utf8, member.getAttr("name"));
- cpRef(CONSTANT_Utf8, member.getAttr("type"));
- writeAttributesFor(member);
- }
-
- protected void writeAttributesFor(Element x) throws IOException {
- LinkedHashSet<String> attrNames = new LinkedHashSet<String>();
- for (Element e : x.elements()) {
- attrNames.add(e.getName()); // uniquifying
- }
- attrNames.removeAll(nonAttrTags());
- u2(attrNames.size());
- if (attrNames.isEmpty()) {
- return;
- }
- Element prevCurrent;
- if (x.getName() == "Code") {
- prevCurrent = currentCode;
- currentCode = x;
- } else {
- prevCurrent = currentMember;
- currentMember = x;
- }
- OutputStream realOut = this.out;
- for (String utag : attrNames) {
- String qtag = x.getName() + "." + utag;
- String wtag = "*." + utag;
- String key = attrTypesByTag.get(qtag);
- if (key == null) {
- key = attrTypesByTag.get(wtag);
- }
- String type = attrTypes.get(key);
- //System.out.println("tag "+qtag+" => key "+key+"; type "+type);
- Element attrs = x.findAllElements(utag);
- ByteArrayOutputStream attrBuf = getAttrBuf();
- if (type == null) {
- if (attrs.size() != 1 || !attrs.get(0).equals(new Element(utag))) {
- System.out.println("Warning: No attribute type description: " + qtag);
- }
- key = wtag;
- } else {
- try {
- this.out = attrBuf;
- // unparse according to type desc.
- if (type.equals("<Code>...")) {
- writeCode((Element) attrs.get(0)); // assume only 1
- } else if (type.equals("<Frame>...")) {
- writeStackMap(attrs, false);
- } else if (type.equals("<FrameX>...")) {
- writeStackMap(attrs, true);
- } else if (type.startsWith("[")) {
- writeAttributeRecursive(attrs, type);
- } else {
- writeAttribute(attrs, type);
- }
- } finally {
- //System.out.println("Attr Bytes = \""+attrBuf.toString(EIGHT_BIT_CHAR_ENCODING).replace('"', (char)('"'|0x80))+"\"");
- this.out = realOut;
- }
- }
- cpRef(CONSTANT_Utf8, key.substring(key.indexOf('.') + 1));
- u4(attrBuf.size());
- attrBuf.writeTo(out);
- putAttrBuf(attrBuf);
- }
- if (x.getName() == "Code") {
- currentCode = prevCurrent;
- } else {
- currentMember = prevCurrent;
- }
- }
-
- private void writeAttributeRecursive(Element aval, String type) throws IOException {
- assert (callables == null);
- callables = getBodies(type);
- writeAttribute(aval, callables[0]);
- callables = null;
- }
-
- private void writeAttribute(Element aval, String type) throws IOException {
- //System.out.println("writeAttribute "+aval+" using "+type);
- String nextAttrName = null;
- boolean afterElemHead = false;
- for (int len = type.length(), next, i = 0; i < len; i = next) {
- int value;
- char intKind;
- int tag;
- int sigChar;
- String attrValue;
- switch (type.charAt(i)) {
- case '<':
- assert (nextAttrName == null);
- next = type.indexOf('>', i);
- String form = type.substring(i + 1, next++);
- if (form.indexOf('=') < 0) {
- // elem_placement = '<' elemname '>'
- if (aval.isAnonymous()) {
- assert (aval.size() == 1);
- aval = (Element) aval.get(0);
- }
- assert (aval.getName().equals(form)) : aval + " // " + form;
- afterElemHead = true;
- } else {
- // attr_placement = '(' attrname '=' (value)? ')'
- int eqPos = form.indexOf('=');
- assert (eqPos >= 0);
- nextAttrName = form.substring(0, eqPos).intern();
- if (eqPos != form.length() - 1) {
- // value is implicit, not placed in file
- nextAttrName = null;
- }
- afterElemHead = false;
- }
- continue;
- case '(':
- next = type.indexOf(')', ++i);
- int callee = Integer.parseInt(type.substring(i, next++));
- writeAttribute(aval, callables[callee]);
- continue;
- case 'N': // replication = 'N' int '[' type ... ']'
- {
- assert (nextAttrName == null);
- afterElemHead = false;
- char countType = type.charAt(i + 1);
- next = i + 2;
- String type1 = getBody(type, next);
- Element elems = aval;
- if (type1.startsWith("<")) {
- // Select only matching members of aval.
- String elemName = type1.substring(1, type1.indexOf('>'));
- elems = aval.findAllElements(elemName);
- }
- putInt(elems.size(), countType);
- next += type1.length() + 2; // skip body and brackets
- for (Element elem : elems.elements()) {
- writeAttribute(elem, type1);
- }
- }
- continue;
- case 'T': // union = 'T' any_int union_case* '(' ')' '[' body ']'
- // write the value
- value = (int) aval.getAttrLong("tag");
- assert (aval.getAttr("tag") != null) : aval;
- intKind = type.charAt(++i);
- if (intKind == 'S') {
- intKind = type.charAt(++i);
- }
- putInt(value, intKind);
- nextAttrName = null;
- afterElemHead = false;
- ++i; // skip the int type char
- // union_case = '(' ('-')? digit+ ')' '[' body ']'
- for (boolean foundCase = false;;) {
- assert (type.charAt(i) == '(');
- next = type.indexOf(')', ++i);
- assert (next >= i);
- String caseStr = type.substring(i, next++);
- String type1 = getBody(type, next);
- next += type1.length() + 2; // skip body and brackets
- boolean lastCase = (caseStr.length() == 0);
- if (!foundCase
- && (lastCase || matchTag(value, caseStr))) {
- foundCase = true;
- // Execute this body.
- writeAttribute(aval, type1);
- }
- if (lastCase) {
- break;
- }
- }
- continue;
- case 'B':
- case 'H':
- case 'I': // int = oneof "BHI"
- value = (int) aval.getAttrLong(nextAttrName);
- intKind = type.charAt(i);
- next = i + 1;
- break;
- case 'K':
- sigChar = type.charAt(i + 1);
- if (sigChar == 'Q') {
- assert (currentMember.getName() == "Field");
- assert (aval.getName() == "ConstantValue");
- String sig = currentMember.getAttr("type");
- sigChar = sig.charAt(0);
- switch (sigChar) {
- case 'Z':
- case 'B':
- case 'C':
- case 'S':
- sigChar = 'I';
- break;
- }
- }
- switch (sigChar) {
- case 'I':
- tag = CONSTANT_Integer;
- break;
- case 'J':
- tag = CONSTANT_Long;
- break;
- case 'F':
- tag = CONSTANT_Float;
- break;
- case 'D':
- tag = CONSTANT_Double;
- break;
- case 'L':
- tag = CONSTANT_String;
- break;
- default:
- assert (false);
- tag = 0;
- }
- assert (type.charAt(i + 2) == 'H'); // only H works for now
- next = i + 3;
- assert (afterElemHead || nextAttrName != null);
- //System.out.println("get attr "+nextAttrName+" in "+aval);
- if (nextAttrName != null) {
- attrValue = aval.getAttr(nextAttrName);
- assert (attrValue != null);
- } else {
- assert (aval.isText()) : aval;
- attrValue = aval.getText().toString();
- }
- value = getCPIndex(tag, attrValue);
- intKind = 'H'; //type.charAt(i+2);
- break;
- case 'R':
- sigChar = type.charAt(i + 1);
- switch (sigChar) {
- case 'C':
- tag = CONSTANT_Class;
- break;
- case 'S':
- tag = CONSTANT_Utf8;
- break;
- case 'D':
- tag = CONSTANT_Class;
- break;
- case 'F':
- tag = CONSTANT_Fieldref;
- break;
- case 'M':
- tag = CONSTANT_Methodref;
- break;
- case 'I':
- tag = CONSTANT_InterfaceMethodref;
- break;
- case 'U':
- tag = CONSTANT_Utf8;
- break;
- //case 'Q': tag = CONSTANT_Class; break;
- default:
- assert (false);
- tag = 0;
- }
- assert (type.charAt(i + 2) == 'H'); // only H works for now
- next = i + 3;
- assert (afterElemHead || nextAttrName != null);
- //System.out.println("get attr "+nextAttrName+" in "+aval);
- if (nextAttrName != null) {
- attrValue = aval.getAttr(nextAttrName);
- } else if (aval.hasText()) {
- attrValue = aval.getText().toString();
- } else {
- attrValue = null;
- }
- value = getCPIndex(tag, attrValue);
- intKind = 'H'; //type.charAt(i+2);
- break;
- case 'P': // bci = 'P' int
- case 'S': // signed_int = 'S' int
- next = i + 2;
- value = (int) aval.getAttrLong(nextAttrName);
- intKind = type.charAt(i + 1);
- break;
- case 'F':
- next = i + 2;
- value = parseFlags(aval.getAttr(nextAttrName));
- intKind = type.charAt(i + 1);
- break;
- default:
- throw new RuntimeException("bad attr format '" + type.charAt(i) + "': " + type);
- }
- // write the value
- putInt(value, intKind);
- nextAttrName = null;
- afterElemHead = false;
- }
- assert (nextAttrName == null);
- }
-
- private void putInt(int x, char ch) throws IOException {
- switch (ch) {
- case 'B':
- u1(x);
- break;
- case 'H':
- u2(x);
- break;
- case 'I':
- u4(x);
- break;
- }
- assert ("BHI".indexOf(ch) >= 0);
- }
-
- private void writeCode(Element code) throws IOException {
- //System.out.println("writeCode "+code);
- //Element m = new Element(currentMember); m.remove(code);
- //System.out.println(" in "+m);
- int stack = (int) code.getAttrLong("stack");
- int local = (int) code.getAttrLong("local");
- Element bytes = code.findElement("Bytes");
- Element insns = code.findElement("Instructions");
- String bytecodes;
- if (insns == null) {
- bytecodes = bytes.getText().toString();
- } else {
- bytecodes = InstructionSyntax.assemble(insns, this);
- // Cache the assembled bytecodes:
- bytes = new Element("Bytes", (String[]) null, bytecodes);
- code.add(0, bytes);
- }
- u2(stack);
- u2(local);
- int length = bytecodes.length();
- u4(length);
- for (int i = 0; i < length; i++) {
- u1((byte) bytecodes.charAt(i));
- }
- Element handlers = code.findAllElements("Handler");
- u2(handlers.size());
- for (Element handler : handlers.elements()) {
- int start = (int) handler.getAttrLong("start");
- int end = (int) handler.getAttrLong("end");
- int catsh = (int) handler.getAttrLong("catch");
- u2(start);
- u2(end);
- u2(catsh);
- cpRef(CONSTANT_Class, handler.getAttr("class"));
- }
- writeAttributesFor(code);
- }
-
- protected void writeStackMap(Element attrs, boolean hasXOption) throws IOException {
- Element bytes = currentCode.findElement("Bytes");
- assert (bytes != null && bytes.size() == 1);
- int byteLength = ((String) bytes.get(0)).length();
- boolean uoffsetIsU4 = (byteLength >= (1 << 16));
- boolean ulocalvarIsU4 = currentCode.getAttrLong("local") >= (1 << 16);
- boolean ustackIsU4 = currentCode.getAttrLong("stack") >= (1 << 16);
- if (uoffsetIsU4) {
- u4(attrs.size());
- } else {
- u2(attrs.size());
- }
- for (Element frame : attrs.elements()) {
- int bci = (int) frame.getAttrLong("bci");
- if (uoffsetIsU4) {
- u4(bci);
- } else {
- u2(bci);
- }
- if (hasXOption) {
- u1((int) frame.getAttrLong("flags"));
- }
- // Scan local and stack types in this frame:
- final int LOCALS = 0, STACK = 1;
- for (int j = LOCALS; j <= STACK; j++) {
- Element types = frame.findElement(j == LOCALS ? "Local" : "Stack");
- int typeSize = (types == null) ? 0 : types.size();
- if (j == LOCALS) {
- if (ulocalvarIsU4) {
- u4(typeSize);
- } else {
- u2(typeSize);
- }
- } else { // STACK
- if (ustackIsU4) {
- u4(typeSize);
- } else {
- u2(typeSize);
- }
- }
- if (types == null) {
- continue;
- }
- for (Element type : types.elements()) {
- int tag = itemTagValue(type.getName());
- u1(tag);
- switch (tag) {
- case ITEM_Object:
- cpRef(CONSTANT_Class, type.getAttr("class"));
- break;
- case ITEM_Uninitialized:
- case ITEM_ReturnAddress: {
- int offset = (int) type.getAttrLong("bci");
- if (uoffsetIsU4) {
- u4(offset);
- } else {
- u2(offset);
- }
- }
- break;
- }
- }
- }
- }
- }
-
- public void writeCP() throws IOException {
- int cpLen = cpoolSize;
- u2(cpLen);
- ByteArrayOutputStream buf = getAttrBuf();
- for (Element c : cpool.elements()) {
- if (!c.isText()) {
- System.out.println("## !isText " + c);
- }
- int id = (int) c.getAttrLong("id");
- int tag = cpTagValue(c.getName());
- String name = c.getText().toString();
- int pos;
- u1(tag);
- switch (tag) {
- case CONSTANT_Utf8: {
- int done = 0;
- buf.reset();
- int nameLen = name.length();
- while (done < nameLen) {
- int next = name.indexOf((char) 0, done);
- if (next < 0) {
- next = nameLen;
- }
- if (done < next) {
- buf.write(name.substring(done, next).getBytes(UTF8_ENCODING));
- }
- if (next < nameLen) {
- buf.write(0300);
- buf.write(0200);
- next++;
- }
- done = next;
- }
- u2(buf.size());
- buf.writeTo(out);
- }
- break;
- case CONSTANT_Integer:
- u4(Integer.parseInt(name));
- break;
- case CONSTANT_Float:
- u4(Float.floatToIntBits(Float.parseFloat(name)));
- break;
- case CONSTANT_Long:
- u8(Long.parseLong(name));
- //i += 1; // no need: extra cp slot is implicit
- break;
- case CONSTANT_Double:
- u8(Double.doubleToLongBits(Double.parseDouble(name)));
- //i += 1; // no need: extra cp slot is implicit
- break;
- case CONSTANT_Class:
- case CONSTANT_String:
- u2(getCPIndex(CONSTANT_Utf8, name));
- break;
- case CONSTANT_Fieldref:
- case CONSTANT_Methodref:
- case CONSTANT_InterfaceMethodref:
- pos = name.indexOf(' ');
- u2(getCPIndex(CONSTANT_Class, name.substring(0, pos)));
- u2(getCPIndex(CONSTANT_NameAndType, name.substring(pos + 1)));
- break;
- case CONSTANT_NameAndType:
- pos = name.indexOf(' ');
- u2(getCPIndex(CONSTANT_Utf8, name.substring(0, pos)));
- u2(getCPIndex(CONSTANT_Utf8, name.substring(pos + 1)));
- break;
- }
- }
- putAttrBuf(buf);
- }
-
- public void cpRef(int tag, String name) throws IOException {
- u2(getCPIndex(tag, name));
- }
-
- public void u8(long x) throws IOException {
- u4((int) (x >>> 32));
- u4((int) (x >>> 0));
- }
-
- public void u4(int x) throws IOException {
- u2(x >>> 16);
- u2(x >>> 0);
- }
-
- public void u2(int x) throws IOException {
- u1(x >>> 8);
- u1(x >>> 0);
- }
-
- public void u1(int x) throws IOException {
- out.write(x & 0xFF);
- }
-}
-