001: /**
002: * YGuard -- an obfuscation library for Java(TM) classfiles.
003: *
004: * Original Copyright (c) 1999 Mark Welsh (markw@retrologic.com)
005: * Modifications Copyright (c) 2002 yWorks GmbH (yguard@yworks.com)
006: *
007: * This library is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU Lesser General Public
009: * License as published by the Free Software Foundation; either
010: * version 2 of the License, or (at your option) any later version.
011: *
012: * This library is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015: * Lesser General Public License for more details.
016: *
017: * You should have received a copy of the GNU Lesser General Public
018: * License along with this library; if not, write to the Free Software
019: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
020: *
021: * The author may be contacted at yguard@yworks.com
022: *
023: * Java and all Java-based marks are trademarks or registered
024: * trademarks of Sun Microsystems, Inc. in the U.S. and other countries.
025: */package com.yworks.yguard.obf.classfile;
026:
027: import java.io.*;
028: import java.util.*;
029: import com.yworks.yguard.obf.*;
030:
031: /**
032: * Representation of an attribute.
033: *
034: * @author Mark Welsh
035: */
036: public class CodeAttrInfo extends AttrInfo {
037: // Constants -------------------------------------------------------------
038: public static final int CONSTANT_FIELD_SIZE = 12;
039:
040: // Fields ----------------------------------------------------------------
041: private int u2maxStack;
042: private int u2maxLocals;
043: private int u4codeLength;
044: private byte[] code;
045: private int u2exceptionTableLength;
046: private ExceptionInfo[] exceptionTable;
047: protected int u2attributesCount;
048: protected AttrInfo[] attributes;
049:
050: // Class Methods ---------------------------------------------------------
051:
052: // Instance Methods ------------------------------------------------------
053: protected CodeAttrInfo(ClassFile cf, int attrNameIndex,
054: int attrLength) {
055: super (cf, attrNameIndex, attrLength);
056: }
057:
058: /** Return the length in bytes of the attribute. */
059: protected int getAttrInfoLength() {
060: int length = CONSTANT_FIELD_SIZE + u4codeLength
061: + u2exceptionTableLength
062: * ExceptionInfo.CONSTANT_FIELD_SIZE;
063: for (int i = 0; i < u2attributesCount; i++) {
064: length += AttrInfo.CONSTANT_FIELD_SIZE
065: + attributes[i].getAttrInfoLength();
066: }
067: return length;
068: }
069:
070: /** Return the String name of the attribute; over-ride this in sub-classes. */
071: protected String getAttrName() {
072: return ATTR_Code;
073: }
074:
075: /**
076: * Trim attributes from the classfile ('Code', 'Exceptions', 'ConstantValue'
077: * are preserved, all others except the list in the String[] are killed).
078: */
079: protected void trimAttrsExcept(String[] keepAttrs) {
080: // Traverse all attributes, removing all except those on 'keep' list
081: for (int i = 0; i < attributes.length; i++) {
082: if (Tools.isInArray(attributes[i].getAttrName(), keepAttrs)) {
083: attributes[i].trimAttrsExcept(keepAttrs);
084: } else {
085: attributes[i] = null;
086: }
087: }
088:
089: // Delete the marked attributes
090: AttrInfo[] left = new AttrInfo[attributes.length];
091: int j = 0;
092: for (int i = 0; i < attributes.length; i++) {
093: if (attributes[i] != null) {
094: left[j++] = attributes[i];
095: }
096: }
097: attributes = new AttrInfo[j];
098: System.arraycopy(left, 0, attributes, 0, j);
099: u2attributesCount = j;
100: }
101:
102: /** Check for references in the 'info' data to the constant pool and mark them. */
103: protected void markUtf8RefsInInfo(ConstantPool pool) {
104: for (int i = 0; i < attributes.length; i++) {
105: attributes[i].markUtf8Refs(pool);
106: }
107: }
108:
109: /** Read the data following the header. */
110: protected void readInfo(DataInput din) throws java.io.IOException {
111: u2maxStack = din.readUnsignedShort();
112: u2maxLocals = din.readUnsignedShort();
113: u4codeLength = din.readInt();
114: code = new byte[u4codeLength];
115: din.readFully(code);
116: u2exceptionTableLength = din.readUnsignedShort();
117: exceptionTable = new ExceptionInfo[u2exceptionTableLength];
118: for (int i = 0; i < u2exceptionTableLength; i++) {
119: exceptionTable[i] = ExceptionInfo.create(din);
120: }
121: u2attributesCount = din.readUnsignedShort();
122: attributes = new AttrInfo[u2attributesCount];
123: for (int i = 0; i < u2attributesCount; i++) {
124: attributes[i] = AttrInfo.create(din, owner);
125: }
126: }
127:
128: /** Export data following the header to a DataOutput stream. */
129: public void writeInfo(DataOutput dout) throws java.io.IOException {
130: dout.writeShort(u2maxStack);
131: dout.writeShort(u2maxLocals);
132: dout.writeInt(u4codeLength);
133: dout.write(code);
134: dout.writeShort(u2exceptionTableLength);
135: for (int i = 0; i < u2exceptionTableLength; i++) {
136: exceptionTable[i].write(dout);
137: }
138: dout.writeShort(u2attributesCount);
139: for (int i = 0; i < u2attributesCount; i++) {
140: attributes[i].write(dout);
141: }
142: }
143: }
|