Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: com/chaoswg/xtc4y/classdesc/code/instructions/LookupSwitchInstruction.java


1   //$Header: /cvsroot/xtc4y/xtc4y/src/com/chaoswg/xtc4y/classdesc/code/instructions/LookupSwitchInstruction.java,v 1.2 2003/08/26 12:35:25 toggm Exp $
2   /******************************************************************************
3    * XTC4y - eXtreme Testing Collection 4 you                                   *
4    * -------------------------------------------------------------------------- *
5    * URL: http://www.chaoswg.com/xtc4y                                          *
6    * Author: Mike Toggweiler (2.dog@gmx.ch)                                     *
7    *                                                                            *
8    * Last Updated: $Date: 2003/08/26 12:35:25 $, by $Author: toggm $            *
9    * Version: $Revision: 1.2 $                                                  *
10   * -------------------------------------------------------------------------- *
11   * COPYRIGHT:   (c) 2003 by Mike Toggweiler                                   *
12   *                                                                            *
13   * This program is free software; you can redistribute it and/or modify       *
14   * it under the terms of the GNU General Public License as published by       *
15   * the Free Software Foundation; either version 2 of the License, or          *
16   * (at your option) any later version.                                        *
17   *****************************************************************************/
18  package com.chaoswg.xtc4y.classdesc.code.instructions;
19  
20  import java.io.DataInputStream;
21  import java.io.DataOutputStream;
22  import java.io.IOException;
23  
24  import com.chaoswg.xtc4y.classdesc.ConstantPool;
25  import com.chaoswg.xtc4y.classdesc.code.Code;
26  
27  /**
28   * A Lookup switch instruction is used to represent switch statements.
29   * It consists of the command, an int giving the number of entries, an 
30   * int defining the default jump address and a set of entries where each 
31   * entry consists of two ints, the case number and the jump address. The end
32   * of a LookupSwitch Instruction is aligned to 4 byte and therefore gaps 
33   * are filled up with nop's. !The empty instructions are filled up before the 
34   * default jump adress and the numberOfEntries
35   * That means: (1byte+4bytes+4bytes+(4bytes+4bytes)*+((index+length)%4))
36   * @author Mike Toggweiler
37   **/
38  public class LookupSwitchInstruction extends Instruction {
39      private int numberOfEntries;
40      private int defaultJumpAdress;
41      private int[] cases;
42      private int[] jumps;
43      private int gap;
44  
45      private Instruction defaultInstr;
46      private Instruction[] jumpInstr;
47  
48      private DataInputStream dis;
49      /**
50       * Opcode of the lookup switch instructions
51       **/
52      public static final byte LOOKUPSWITCH = (byte)171;
53  
54      /**
55       * Creates an LookupSwitchInstruction and initializes it from a 
56       * DataInputStream
57       * @param dis the DataInputStream to read from
58       * @param cp the constant pool to resolve indices
59       **/
60      protected LookupSwitchInstruction(DataInputStream dis, ConstantPool cp) 
61    throws IOException {
62    super(LOOKUPSWITCH);
63      
64    //store temporary the datainputstream to read the gap from
65    this.dis = dis;
66      }
67      
68      /**
69       * Set the index of this instruction, is set by the code container
70       * @param index 
71       **/
72      public void setIndex(short index) {
73    super.setIndex(index);
74  
75    if (dis == null) {
76        return;
77    }
78    
79    //read the remaining gap, is depedant on the index of the switch 
80    //instruction
81    gap = (index % 4);
82    if (gap == 0) {
83        gap = 1;
84    }
85    else {
86        gap++;
87    }
88    gap = 4 - gap;
89    try {
90        for (int i=0; i<gap; ++i) {
91      //throw away byte
92      dis.readUnsignedByte();
93        }
94        defaultJumpAdress = dis.readInt();
95        numberOfEntries = dis.readInt();
96        
97        cases = new int[numberOfEntries];
98        jumps = new int[numberOfEntries];
99        jumpInstr = new Instruction[numberOfEntries];
100       for (int i=0; i<numberOfEntries; ++i) {
101     cases[i] = dis.readInt();
102     jumps[i] = dis.readInt();
103       }
104   }
105   catch (IOException ioe) {
106       //do nothing
107       //TBD: log
108   }  
109 
110   //free dis reference
111   dis = null;
112     }
113 
114     /**
115      * Resolve indices of instructions.
116      * By default do nothing
117      * @param code the code container where to resolve the indices
118      **/
119     public void resolveIndices(Code code) {  
120   for (int i=0; i<numberOfEntries; ++i) {
121       jumpInstr[i] = code.getInstructionAt((short)(jumps[i]+getIndex()));
122   }
123 
124   defaultInstr = code.getInstructionAt((short)defaultJumpAdress);
125     }
126 
127     /**
128      * Write the instruction onto the DataOutputStream, using the 
129      * constant pool to register variables. .
130      * @param dos the DataOutputStream to write on
131      * @param cp The constant pool to register variables
132      **/
133     public final void write(DataOutputStream dos, ConstantPool cp) 
134   throws IOException {
135   super.write(dos, cp);
136     
137   for (int i=0; i<gap; ++i) {      
138       dos.writeByte(UnaryInstruction.NOP);
139   }
140   dos.writeInt(defaultInstr.getIndex());
141   dos.writeInt(numberOfEntries);
142   for (int i=0; i<numberOfEntries; ++i) {
143       dos.writeInt(cases[i]);
144       dos.writeInt(jumpInstr[i].getIndex()-getIndex());
145   }  
146     }
147 
148     /**
149      * @return the number of bytes used in this command
150      **/
151     public int getNumberOfUsedBytes() {
152   //return command + numberOfEntries + defaultJumpAddr + 
153   //numberOfEntries*(case + jumpAddr) + gap
154   return 1 + 4 + 4 + numberOfEntries*(4+4) + gap;
155     }
156 }