jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Signature.java
changeset 46174 5611d2529b49
parent 44797 8b3b3b911b8a
equal deleted inserted replaced
46173:5546b5710844 46174:5611d2529b49
    19  * limitations under the License.
    19  * limitations under the License.
    20  */
    20  */
    21 
    21 
    22 package com.sun.org.apache.bcel.internal.classfile;
    22 package com.sun.org.apache.bcel.internal.classfile;
    23 
    23 
    24 
    24 import java.io.ByteArrayInputStream;
    25 import  com.sun.org.apache.bcel.internal.Constants;
    25 import java.io.DataInput;
    26 import  java.io.*;
    26 import java.io.DataOutputStream;
       
    27 import java.io.IOException;
       
    28 
       
    29 import com.sun.org.apache.bcel.internal.Const;
    27 
    30 
    28 /**
    31 /**
    29  * This class is derived from <em>Attribute</em> and represents a reference
    32  * This class is derived from <em>Attribute</em> and represents a reference
    30  * to a <href="http://wwwipd.ira.uka.de/~pizza/gj/">GJ</a> attribute.
    33  * to a GJ attribute.
    31  *
    34  *
    32  * @author  <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
    35  * @version $Id: Signature.java 1749603 2016-06-21 20:50:19Z ggregory $
    33  * @see     Attribute
    36  * @see     Attribute
    34  */
    37  */
    35 public final class Signature extends Attribute {
    38 public final class Signature extends Attribute {
    36   private int signature_index;
    39 
    37 
    40     private int signature_index;
    38   /**
    41 
    39    * Initialize from another object. Note that both objects use the same
    42 
    40    * references (shallow copy). Use clone() for a physical copy.
    43     /**
    41    */
    44      * Initialize from another object. Note that both objects use the same
    42   public Signature(Signature c) {
    45      * references (shallow copy). Use clone() for a physical copy.
    43     this(c.getNameIndex(), c.getLength(), c.getSignatureIndex(), c.getConstantPool());
    46      */
    44   }
    47     public Signature(final Signature c) {
    45 
    48         this(c.getNameIndex(), c.getLength(), c.getSignatureIndex(), c.getConstantPool());
    46   /**
    49     }
    47    * Construct object from file stream.
    50 
    48    * @param name_index Index in constant pool to CONSTANT_Utf8
    51 
    49    * @param length Content length in bytes
    52     /**
    50    * @param file Input stream
    53      * Construct object from file stream.
    51    * @param constant_pool Array of constants
    54      * @param name_index Index in constant pool to CONSTANT_Utf8
    52    * @throws IOException
    55      * @param length Content length in bytes
    53    */
    56      * @param input Input stream
    54   Signature(int name_index, int length, DataInputStream file,
    57      * @param constant_pool Array of constants
    55            ConstantPool constant_pool) throws IOException
    58      * @throws IOException
    56   {
    59      */
    57     this(name_index, length, file.readUnsignedShort(), constant_pool);
    60     Signature(final int name_index, final int length, final DataInput input, final ConstantPool constant_pool)
    58   }
    61             throws IOException {
    59 
    62         this(name_index, length, input.readUnsignedShort(), constant_pool);
    60   /**
    63     }
    61    * @param name_index Index in constant pool to CONSTANT_Utf8
    64 
    62    * @param length Content length in bytes
    65 
    63    * @param constant_pool Array of constants
    66     /**
    64    * @param Signature_index Index in constant pool to CONSTANT_Utf8
    67      * @param name_index Index in constant pool to CONSTANT_Utf8
    65    */
    68      * @param length Content length in bytes
    66   public Signature(int name_index, int length, int signature_index,
    69      * @param signature_index Index in constant pool to CONSTANT_Utf8
    67                   ConstantPool constant_pool)
    70      * @param constant_pool Array of constants
    68   {
    71      */
    69     super(Constants.ATTR_SIGNATURE, name_index, length, constant_pool);
    72     public Signature(final int name_index, final int length, final int signature_index, final ConstantPool constant_pool) {
    70     this.signature_index = signature_index;
    73         super(Const.ATTR_SIGNATURE, name_index, length, constant_pool);
    71   }
    74         this.signature_index = signature_index;
    72 
    75     }
    73   /**
    76 
    74    * Called by objects that are traversing the nodes of the tree implicitely
    77 
    75    * defined by the contents of a Java class. I.e., the hierarchy of methods,
    78     /**
    76    * fields, attributes, etc. spawns a tree of objects.
    79      * Called by objects that are traversing the nodes of the tree implicitely
    77    *
    80      * defined by the contents of a Java class. I.e., the hierarchy of methods,
    78    * @param v Visitor object
    81      * fields, attributes, etc. spawns a tree of objects.
    79    */
    82      *
    80    public void accept(Visitor v) {
    83      * @param v Visitor object
    81      System.err.println("Visiting non-standard Signature object");
    84      */
    82      v.visitSignature(this);
    85     @Override
    83    }
    86     public void accept( final Visitor v ) {
    84 
    87         //System.err.println("Visiting non-standard Signature object");
    85   /**
    88         v.visitSignature(this);
    86    * Dump source file attribute to file stream in binary format.
    89     }
    87    *
    90 
    88    * @param file Output file stream
    91 
    89    * @throws IOException
    92     /**
    90    */
    93      * Dump source file attribute to file stream in binary format.
    91   public final void dump(DataOutputStream file) throws IOException
    94      *
    92   {
    95      * @param file Output file stream
    93     super.dump(file);
    96      * @throws IOException
    94     file.writeShort(signature_index);
    97      */
    95   }
    98     @Override
    96 
    99     public final void dump( final DataOutputStream file ) throws IOException {
    97   /**
   100         super.dump(file);
    98    * @return Index in constant pool of source file name.
   101         file.writeShort(signature_index);
    99    */
   102     }
   100   public final int getSignatureIndex() { return signature_index; }
   103 
   101 
   104 
   102   /**
   105     /**
   103    * @param Signature_index.
   106      * @return Index in constant pool of source file name.
   104    */
   107      */
   105   public final void setSignatureIndex(int signature_index) {
   108     public final int getSignatureIndex() {
   106     this.signature_index = signature_index;
   109         return signature_index;
   107   }
   110     }
   108 
   111 
   109   /**
   112 
   110    * @return GJ signature.
   113     /**
   111    */
   114      * @param signature_index the index info the constant pool of this signature
   112   public final String getSignature() {
   115      */
   113     ConstantUtf8 c = (ConstantUtf8)constant_pool.getConstant(signature_index,
   116     public final void setSignatureIndex( final int signature_index ) {
   114                                                              Constants.CONSTANT_Utf8);
   117         this.signature_index = signature_index;
   115     return c.getBytes();
   118     }
   116   }
   119 
   117 
   120 
   118   /**
   121     /**
   119    * Extends ByteArrayInputStream to make 'unreading' chars possible.
   122      * @return GJ signature.
   120    */
   123      */
   121   private static final class MyByteArrayInputStream extends ByteArrayInputStream {
   124     public final String getSignature() {
   122     MyByteArrayInputStream(String data) { super(data.getBytes()); }
   125         final ConstantUtf8 c = (ConstantUtf8) super.getConstantPool().getConstant(signature_index,
   123     final int  mark()                   { return pos; }
   126                 Const.CONSTANT_Utf8);
   124     final String getData()              { return new String(buf); }
   127         return c.getBytes();
   125     final void reset(int p)             { pos = p; }
   128     }
   126     final void unread()                 { if(pos > 0) pos--; }
   129 
   127   }
   130     /**
   128 
   131      * Extends ByteArrayInputStream to make 'unreading' chars possible.
   129   private static boolean identStart(int ch) {
   132      */
   130     return ch == 'T' || ch == 'L';
   133     private static final class MyByteArrayInputStream extends ByteArrayInputStream {
   131   }
   134 
   132 
   135         MyByteArrayInputStream(final String data) {
   133   private static boolean identPart(int ch) {
   136             super(data.getBytes());
   134     return ch == '/' || ch == ';';
   137         }
   135   }
   138 
   136 
   139 
   137   private static final void matchIdent(MyByteArrayInputStream in, StringBuffer buf) {
   140         final String getData() {
   138     int ch;
   141             return new String(buf);
   139 
   142         }
   140     if((ch = in.read()) == -1)
   143 
   141       throw new RuntimeException("Illegal signature: " + in.getData() +
   144 
   142                                  " no ident, reaching EOF");
   145         final void unread() {
   143 
   146             if (pos > 0) {
   144     //System.out.println("return from ident:" + (char)ch);
   147                 pos--;
   145 
   148             }
   146     if(!identStart(ch)) {
   149         }
   147       StringBuffer buf2 = new StringBuffer();
   150     }
   148 
   151 
   149       int count = 1;
   152 
   150       while(Character.isJavaIdentifierPart((char)ch)) {
   153     private static boolean identStart( final int ch ) {
   151         buf2.append((char)ch);
   154         return ch == 'T' || ch == 'L';
   152         count++;
   155     }
       
   156 
       
   157 
       
   158     private static void matchIdent( final MyByteArrayInputStream in, final StringBuilder buf ) {
       
   159         int ch;
       
   160         if ((ch = in.read()) == -1) {
       
   161             throw new RuntimeException("Illegal signature: " + in.getData()
       
   162                     + " no ident, reaching EOF");
       
   163         }
       
   164         //System.out.println("return from ident:" + (char)ch);
       
   165         if (!identStart(ch)) {
       
   166             final StringBuilder buf2 = new StringBuilder();
       
   167             int count = 1;
       
   168             while (Character.isJavaIdentifierPart((char) ch)) {
       
   169                 buf2.append((char) ch);
       
   170                 count++;
       
   171                 ch = in.read();
       
   172             }
       
   173             if (ch == ':') { // Ok, formal parameter
       
   174                 in.skip("Ljava/lang/Object".length());
       
   175                 buf.append(buf2);
       
   176                 ch = in.read();
       
   177                 in.unread();
       
   178                 //System.out.println("so far:" + buf2 + ":next:" +(char)ch);
       
   179             } else {
       
   180                 for (int i = 0; i < count; i++) {
       
   181                     in.unread();
       
   182                 }
       
   183             }
       
   184             return;
       
   185         }
       
   186         final StringBuilder buf2 = new StringBuilder();
   153         ch = in.read();
   187         ch = in.read();
   154       }
   188         do {
   155 
   189             buf2.append((char) ch);
   156       if(ch == ':') { // Ok, formal parameter
   190             ch = in.read();
   157         in.skip("Ljava/lang/Object".length());
   191             //System.out.println("within ident:"+ (char)ch);
   158         buf.append(buf2);
   192         } while ((ch != -1) && (Character.isJavaIdentifierPart((char) ch) || (ch == '/')));
   159 
   193         buf.append(buf2.toString().replace('/', '.'));
       
   194         //System.out.println("regular return ident:"+ (char)ch + ":" + buf2);
       
   195         if (ch != -1) {
       
   196             in.unread();
       
   197         }
       
   198     }
       
   199 
       
   200 
       
   201     private static void matchGJIdent( final MyByteArrayInputStream in, final StringBuilder buf ) {
       
   202         int ch;
       
   203         matchIdent(in, buf);
   160         ch = in.read();
   204         ch = in.read();
   161         in.unread();
   205         if ((ch == '<') || ch == '(') { // Parameterized or method
   162         //System.out.println("so far:" + buf2 + ":next:" +(char)ch);
   206             //System.out.println("Enter <");
   163       } else {
   207             buf.append((char) ch);
   164         for(int i=0; i < count; i++)
   208             matchGJIdent(in, buf);
   165           in.unread();
   209             while (((ch = in.read()) != '>') && (ch != ')')) { // List of parameters
   166       }
   210                 if (ch == -1) {
   167 
   211                     throw new RuntimeException("Illegal signature: " + in.getData()
   168       return;
   212                             + " reaching EOF");
   169     }
   213                 }
   170 
   214                 //System.out.println("Still no >");
   171     StringBuffer buf2 = new StringBuffer();
   215                 buf.append(", ");
   172     ch = in.read();
   216                 in.unread();
   173 
   217                 matchGJIdent(in, buf); // Recursive call
   174     do {
   218             }
   175       buf2.append((char)ch);
   219             //System.out.println("Exit >");
   176       ch = in.read();
   220             buf.append((char) ch);
   177       //System.out.println("within ident:"+ (char)ch);
   221         } else {
   178 
   222             in.unread();
   179     } while((ch != -1) && (Character.isJavaIdentifierPart((char)ch) || (ch == '/')));
   223         }
   180 
   224         ch = in.read();
   181     buf.append(buf2.toString().replace('/', '.'));
   225         if (identStart(ch)) {
   182 
   226             in.unread();
   183     //System.out.println("regular return ident:"+ (char)ch + ":" + buf2);
   227             matchGJIdent(in, buf);
   184 
   228         } else if (ch == ')') {
   185     if(ch != -1)
   229             in.unread();
   186       in.unread();
   230             return;
   187   }
   231         } else if (ch != ';') {
   188 
   232             throw new RuntimeException("Illegal signature: " + in.getData() + " read " + (char) ch);
   189   private static final void matchGJIdent(MyByteArrayInputStream in,
   233         }
   190                                          StringBuffer buf)
   234     }
   191   {
   235 
   192     int ch;
   236 
   193 
   237     public static String translate( final String s ) {
   194     matchIdent(in, buf);
   238         //System.out.println("Sig:" + s);
   195 
   239         final StringBuilder buf = new StringBuilder();
   196     ch = in.read();
   240         matchGJIdent(new MyByteArrayInputStream(s), buf);
   197     if((ch == '<') || ch == '(') { // Parameterized or method
   241         return buf.toString();
   198       //System.out.println("Enter <");
   242     }
   199       buf.append((char)ch);
   243 
   200       matchGJIdent(in, buf);
   244 
   201 
   245     // @since 6.0 is no longer final
   202       while(((ch = in.read()) != '>') && (ch != ')')) { // List of parameters
   246     public static boolean isFormalParameterList( final String s ) {
   203         if(ch == -1)
   247         return s.startsWith("<") && (s.indexOf(':') > 0);
   204           throw new RuntimeException("Illegal signature: " + in.getData() +
   248     }
   205                                      " reaching EOF");
   249 
   206 
   250 
   207         //System.out.println("Still no >");
   251     // @since 6.0 is no longer final
   208         buf.append(", ");
   252     public static boolean isActualParameterList( final String s ) {
   209         in.unread();
   253         return s.startsWith("L") && s.endsWith(">;");
   210         matchGJIdent(in, buf); // Recursive call
   254     }
   211       }
   255 
   212 
   256 
   213       //System.out.println("Exit >");
   257     /**
   214 
   258      * @return String representation
   215       buf.append((char)ch);
   259      */
   216     } else
   260     @Override
   217       in.unread();
   261     public final String toString() {
   218 
   262         final String s = getSignature();
   219     ch = in.read();
   263         return "Signature: " + s;
   220     if(identStart(ch)) {
   264     }
   221       in.unread();
   265 
   222       matchGJIdent(in, buf);
   266 
   223     } else if(ch == ')') {
   267     /**
   224       in.unread();
   268      * @return deep copy of this attribute
   225       return;
   269      */
   226     } else if(ch != ';')
   270     @Override
   227       throw new RuntimeException("Illegal signature: " + in.getData() + " read " +
   271     public Attribute copy( final ConstantPool _constant_pool ) {
   228                                  (char)ch);
   272         return (Attribute) clone();
   229   }
   273     }
   230 
       
   231   public static String translate(String s) {
       
   232     //System.out.println("Sig:" + s);
       
   233     StringBuffer buf = new StringBuffer();
       
   234 
       
   235     matchGJIdent(new MyByteArrayInputStream(s), buf);
       
   236 
       
   237     return buf.toString();
       
   238   }
       
   239 
       
   240   public static final boolean isFormalParameterList(String s) {
       
   241     return s.startsWith("<") && (s.indexOf(':') > 0);
       
   242   }
       
   243 
       
   244   public static final boolean isActualParameterList(String s) {
       
   245     return s.startsWith("L") && s.endsWith(">;");
       
   246   }
       
   247 
       
   248   /**
       
   249    * @return String representation
       
   250    */
       
   251   public final String toString() {
       
   252     String s = getSignature();
       
   253 
       
   254     return "Signature(" + s + ")";
       
   255   }
       
   256 
       
   257   /**
       
   258    * @return deep copy of this attribute
       
   259    */
       
   260   public Attribute copy(ConstantPool constant_pool) {
       
   261     return (Signature)clone();
       
   262   }
       
   263 }
   274 }