001    /* MBEL: The Microsoft Bytecode Engineering Library
002     * Copyright (C) 2003 The University of Arizona
003     * http://www.cs.arizona.edu/mbel/license.html
004     *
005     * This library is free software; you can redistribute it and/or
006     * modify it under the terms of the GNU Lesser General Public
007     * License as published by the Free Software Foundation; either
008     * version 2.1 of the License, or (at your option) any later version.
009     * 
010     * This library is distributed in the hope that it will be useful,
011     * but WITHOUT ANY WARRANTY; without even the implied warranty of
012     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
013     * Lesser General Public License for more details.
014     * 
015     * You should have received a copy of the GNU Lesser General Public
016     * License along with this library; if not, write to the Free Software
017     * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
018     */
019    
020    
021    package edu.arizona.cs.mbel.signature;
022    
023    /** This class describes the return type of a method in a method signature
024      * @author Michael Stepp
025      */
026    public class ReturnTypeSignature extends Signature{
027       private ParameterInfo paramInfo;
028       // Signature fields
029       private java.util.Vector customMods;   // CustomModifierSignatures
030       private TypeSignature type;
031       private byte elementType;
032       // elementType:    meaning:
033       // TYPEONLY        just Type without BYREF
034       // BYREF           BYREF and Type
035       // TYPEDBYREF      TYPEDBYREF
036       // VOID            VOID
037       
038       private ReturnTypeSignature(){
039          customMods = new java.util.Vector(10);
040       }
041    
042       /** Makes a new ReturnTypeSignature object with the given type, possibly by reference
043         * @param typeSig the type of this return value 
044         * @param byref true iff this value is returned by reference
045         */
046       public ReturnTypeSignature(TypeSignature typeSig, boolean byref) throws SignatureException{
047          this();
048          type = typeSig;
049          if (type==null)
050             throw new SignatureException("ReturnTypeSignature: Return type is null");
051          elementType = (byref ? ELEMENT_TYPE_BYREF : ELEMENT_TYPE_TYPEONLY);
052       }
053       
054       /** Makes a new ReturnTypeSignature object with the given type code
055         * @param typecode must be one of ELEMENT_TYPE_TYPEDBYREF or ELEMENT_TYPE_VOID
056         */
057       public ReturnTypeSignature(byte typecode) throws SignatureException{
058          this();
059          if (typecode == ELEMENT_TYPE_TYPEDBYREF)
060             elementType = typecode;
061          else if (typecode==ELEMENT_TYPE_VOID)
062             elementType = typecode;
063          else
064             throw new SignatureException("ReturnTypeSignature: Invalid byte code given");
065       }
066    
067    
068       /** Factory method to parse a ReturnTypeSignature from a ByteBuffer blob
069         * @param buffer the buffer to read from
070         * @param group a TypeGroup for reconciling tokens to mbel references
071         * @return a ReturnTypeSignature representing the given blob, or null if there was a parse error
072         */
073       public static ReturnTypeSignature parse(edu.arizona.cs.mbel.ByteBuffer buffer, edu.arizona.cs.mbel.mbel.TypeGroup group){
074          ReturnTypeSignature blob = new ReturnTypeSignature();
075    
076          int pos = buffer.getPosition();
077          CustomModifierSignature temp = CustomModifierSignature.parse(buffer, group);
078          while(temp!=null){
079             blob.customMods.add(temp);
080             pos = buffer.getPosition();
081             temp = CustomModifierSignature.parse(buffer, group);
082          }
083          buffer.setPosition(pos);
084    
085          blob.elementType = ELEMENT_TYPE_TYPEONLY;
086          byte data = buffer.peek();
087          if (data==ELEMENT_TYPE_TYPEDBYREF){
088             // TYPEDBYREF
089             blob.elementType = data;
090             buffer.get();
091          }else if (data==ELEMENT_TYPE_VOID){
092             // VOID
093             blob.elementType = data;
094             buffer.get();
095          }else{
096             if (data==ELEMENT_TYPE_BYREF){
097                // BYREF Type
098                blob.elementType = data;
099                buffer.get();
100             }
101             blob.type = TypeSignature.parse(buffer, group);
102             if (blob.type == null)
103                return null;
104          }
105    
106          return blob;
107       }
108    
109       /** Returns the ParamInfo object of this return type (may be null)
110         */
111       public ParameterInfo getParameterInfo(){
112          return paramInfo;
113       }
114       
115       /** Sets the ParamInfo object for this return type (may be null)
116         */
117       public void setParameterInfo(ParameterInfo info){
118          paramInfo = info;
119       }
120       
121       /** Returns the type of returntype this is:
122         * Type:                    Meaning:
123         * ELEMENT_TYPE_TYPEONLY    Return value is given by the TypeSignature
124         * ELEMENT_TYPE_BYREF       Return value is given by the TypeSignature, passed by reference
125         * ELEMENT_TYPE_TYPEDBYREF  Return value is typed by reference
126         * ELEMENT_TYPE_VOID        Void return type
127         */
128       public int getElementType(){
129          return elementType;
130       }
131    
132       /** Returns the type signature for this return type (may be null)
133         */
134       public TypeSignature getType(){
135          return type;
136       }
137    
138       /** Getter method for the CustomModifiers applied to this ReturnTypeSignature
139         */
140       public CustomModifierSignature[] getCustomModifiers(){
141          CustomModifierSignature[] sigs = new CustomModifierSignature[customMods.size()];
142          for (int i=0;i<sigs.length;i++)
143             sigs[i] = (CustomModifierSignature)customMods.get(i);
144    
145          return sigs;
146       }
147    
148       /** Write this signature out to the given buffer in raw binary form
149         * @param buffer the buffer to write to
150         */
151       public void emit(edu.arizona.cs.mbel.ByteBuffer buffer, edu.arizona.cs.mbel.emit.ClassEmitter emitter){
152          for (int i=0;i<customMods.size();i++)
153             ((CustomModifierSignature)customMods.get(i)).emit(buffer, emitter);
154          if (elementType == ELEMENT_TYPE_BYREF){
155             buffer.put(ELEMENT_TYPE_BYREF);
156             type.emit(buffer, emitter);
157          }
158          else if (elementType == ELEMENT_TYPE_TYPEONLY)
159             type.emit(buffer, emitter);
160          else if (elementType == ELEMENT_TYPE_TYPEDBYREF)
161             buffer.put(ELEMENT_TYPE_TYPEDBYREF);
162          else if (elementType == ELEMENT_TYPE_VOID)
163             buffer.put(ELEMENT_TYPE_VOID);
164       }
165    
166    /*
167       public void output(){
168          System.out.print("ReturnTypeSignature[");
169          for (int i=0;i<customMods.size();i++){
170             ((CustomModifierSignature)customMods.get(i)).output();
171             System.out.print(',');
172          }
173    
174          if (elementType==ELEMENT_TYPE_TYPEONLY){
175             type.output();
176          }else if (elementType == ELEMENT_TYPE_BYREF){
177             System.out.print("BYREF,");
178             type.output();
179          }else if (elementType == ELEMENT_TYPE_TYPEDBYREF){
180             System.out.print("TYPEDBYREF");
181          }else{
182             System.out.print("VOID");
183          }
184          System.out.print("]");
185       }
186    */
187    }