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 a field or method from a class-file.
033: *
034: * @author Mark Welsh
035: */
036: abstract public class ClassItemInfo implements ClassConstants {
037: // Constants -------------------------------------------------------------
038:
039: // Fields ----------------------------------------------------------------
040: private int u2accessFlags;
041: private int u2nameIndex;
042: private int u2descriptorIndex;
043: protected int u2attributesCount;
044: protected AttrInfo attributes[];
045:
046: private ClassFile cf;
047: private boolean isSynthetic = false;
048:
049: // Class Methods ---------------------------------------------------------
050:
051: // Instance Methods ------------------------------------------------------
052: protected ClassItemInfo(ClassFile cf) {
053: this .cf = cf;
054: }
055:
056: /** Is the field or method 'Synthetic'? */
057: public boolean isSynthetic() {
058: return isSynthetic;
059: }
060:
061: /** Return method/field name index into Constant Pool. */
062: protected int getNameIndex() {
063: return u2nameIndex;
064: }
065:
066: /** Set the method/field name index. */
067: protected void setNameIndex(int index) {
068: u2nameIndex = index;
069: }
070:
071: /** Return method/field descriptor index into Constant Pool. */
072: protected int getDescriptorIndex() {
073: return u2descriptorIndex;
074: }
075:
076: /** Set the method/field descriptor index. */
077: protected void setDescriptorIndex(int index) {
078: u2descriptorIndex = index;
079: }
080:
081: /** Return method/field string name. */
082: protected String getName() {
083: return ((Utf8CpInfo) cf.getCpEntry(u2nameIndex)).getString();
084: }
085:
086: /** Return descriptor string. */
087: protected String getDescriptor() {
088: return ((Utf8CpInfo) cf.getCpEntry(u2descriptorIndex))
089: .getString();
090: }
091:
092: /** Return access flags. */
093: protected int getAccessFlags() {
094: return u2accessFlags;
095: }
096:
097: /**
098: * Trim attributes from the classfile ('Code', 'Exceptions', 'ConstantValue'
099: * are preserved, all others except the list in the String[] are killed).
100: */
101: protected void trimAttrsExcept(String[] keepAttrs) {
102: // Traverse all attributes, removing all except those on 'keep' list
103: for (int i = 0; i < attributes.length; i++) {
104: if (Tools.isInArray(attributes[i].getAttrName(), keepAttrs)) {
105: attributes[i].trimAttrsExcept(keepAttrs);
106: } else {
107: attributes[i] = null;
108: }
109: }
110:
111: // Delete the marked attributes
112: AttrInfo[] left = new AttrInfo[attributes.length];
113: int j = 0;
114: for (int i = 0; i < attributes.length; i++) {
115: if (attributes[i] != null) {
116: left[j++] = attributes[i];
117: }
118: }
119: attributes = new AttrInfo[j];
120: System.arraycopy(left, 0, attributes, 0, j);
121: u2attributesCount = j;
122: }
123:
124: /** Check for Utf8 references to constant pool and mark them. */
125: protected void markUtf8Refs(ConstantPool pool) {
126: pool.incRefCount(u2nameIndex);
127: pool.incRefCount(u2descriptorIndex);
128: for (int i = 0; i < attributes.length; i++) {
129: attributes[i].markUtf8Refs(pool);
130: }
131: }
132:
133: /** Import the field or method data to internal representation. */
134: protected void read(DataInput din) throws java.io.IOException {
135: u2accessFlags = din.readUnsignedShort();
136: u2nameIndex = din.readUnsignedShort();
137: u2descriptorIndex = din.readUnsignedShort();
138: u2attributesCount = din.readUnsignedShort();
139: attributes = new AttrInfo[u2attributesCount];
140: for (int i = 0; i < u2attributesCount; i++) {
141: attributes[i] = AttrInfo.create(din, cf);
142: if (attributes[i].getAttrName().equals(ATTR_Synthetic)) {
143: isSynthetic = true;
144: }
145: }
146: }
147:
148: /** Export the representation to a DataOutput stream. */
149: public void write(DataOutput dout) throws java.io.IOException {
150: if (dout == null)
151: throw new NullPointerException(
152: "No output stream was provided.");
153: dout.writeShort(u2accessFlags);
154: dout.writeShort(u2nameIndex);
155: dout.writeShort(u2descriptorIndex);
156: dout.writeShort(u2attributesCount);
157: for (int i = 0; i < u2attributesCount; i++) {
158: attributes[i].write(dout);
159: }
160: }
161: }
|