Integrating bug fix for CFSerializer.
[jpf-core.git] / src / main / gov / nasa / jpf / vm / JPFOutputStream.java
1 /*
2  * Copyright (C) 2014, United States Government, as represented by the
3  * Administrator of the National Aeronautics and Space Administration.
4  * All rights reserved.
5  *
6  * The Java Pathfinder core (jpf-core) platform is licensed under the
7  * Apache License, Version 2.0 (the "License"); you may not use this file except
8  * in compliance with the License. You may obtain a copy of the License at
9  * 
10  *        http://www.apache.org/licenses/LICENSE-2.0. 
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and 
16  * limitations under the License.
17  */
18 package gov.nasa.jpf.vm;
19
20 import java.io.IOException;
21 import java.io.OutputStream;
22 import java.io.PrintStream;
23
24 import gov.nasa.jpf.util.FinalBitSet;
25 import gov.nasa.jpf.util.PrintUtils;
26
27 /**
28  * stream to write program state info in a readable and diff-able format.
29  * This is mostly intended for debugging, but could also at some point be
30  * used to restore such states.
31  * 
32  * Currently supports heap objects, classes (static fields), threads and stack frames
33  */
34 public class JPFOutputStream extends OutputStream {
35   
36   PrintStream ps;
37   
38   boolean useSid = false;
39   int maxElements = -1;
40   
41   public JPFOutputStream (OutputStream os){
42     ps = new PrintStream(os);
43   }
44   
45   public JPFOutputStream (PrintStream ps){
46     this.ps = ps;
47   }
48   
49   public JPFOutputStream (){
50     this(System.out);
51   }
52   
53   @Override
54   public void close(){
55     ps.flush();
56     
57     if (ps != System.err && ps != System.out){
58       ps.close();
59     }
60   }
61   
62   public void printCommentLine(String msg){
63     ps.print("// ");
64     ps.println(msg);
65   }
66   
67   public void print (ElementInfo ei, FieldInfo fi, boolean isFiltered){
68     ps.print(fi.getName());
69     ps.print(':');
70
71     if (isFiltered){
72       ps.print("X");
73       
74     } else {
75       switch (fi.getTypeCode()) {
76       case Types.T_BOOLEAN:
77         ps.print(ei.getBooleanField(fi));
78         break;
79       case Types.T_BYTE:
80         ps.print(ei.getByteField(fi));
81         break;
82       case Types.T_CHAR:
83         PrintUtils.printCharLiteral(ps, ei.getCharField(fi));
84         break;
85       case Types.T_SHORT:
86         ps.print(ei.getShortField(fi));
87         break;
88       case Types.T_INT:
89         ps.print(ei.getIntField(fi));
90         break;
91       case Types.T_LONG:
92         ps.print(ei.getLongField(fi));
93         break;
94       case Types.T_FLOAT:
95         ps.print(ei.getFloatField(fi));
96         break;
97       case Types.T_DOUBLE:
98         ps.print(ei.getDoubleField(fi));
99         break;
100
101       case Types.T_REFERENCE:
102       case Types.T_ARRAY:
103         PrintUtils.printReference(ps, ei.getReferenceField(fi));
104         break;
105       }
106     }
107   }
108   
109   protected void printFields (ElementInfo ei, FieldInfo[] fields, FinalBitSet filterMask){
110     if (fields != null){
111       for (int i = 0; i < fields.length; i++) {
112         if (i > 0) {
113           ps.print(',');
114         }
115         print(ei, fields[i], (filterMask != null && filterMask.get(i)));
116       }
117     }
118   }
119   
120   public void print (ElementInfo ei, FinalBitSet filterMask){
121     boolean isObject = ei.isObject();
122     ClassInfo ci = ei.getClassInfo();
123     
124     int ref = (useSid) ? ((int)ei.getSid()) : ei.getObjectRef();
125     ps.printf("@%x ", ref);
126     
127     if (isObject){
128       ps.print("object ");
129       if (ei.isArray()){
130         ps.print( Types.getTypeName(ci.getName()));
131       } else {
132         ps.print(ci.getName());
133       }
134     } else {
135       ps.print("class ");
136       ps.print(ci.getName());
137     }
138     
139     ps.print(':');
140     
141     if (isObject){
142       if (ei.isArray()){
143         ps.print('[');
144         ei.getArrayFields().printElements(ps, maxElements);
145         ps.print(']');
146             
147       } else {
148         ps.print('{');
149         printFields(ei, ci.getInstanceFields(), filterMask);
150         ps.print('}');
151       }
152       
153     } else {
154       ps.print('{');
155       printFields( ei, ci.getDeclaredStaticFields(), filterMask);        
156       ps.print('}');
157     }
158   }
159   
160   public void print (ThreadInfo ti){
161     PrintUtils.printReference(ps, ti.getThreadObjectRef());
162     ps.print(' ');
163     ps.print(ti.getStateDescription());
164   }
165   
166   public void print (StackFrame frame){
167     MethodInfo mi = frame.getMethodInfo();
168   
169     ps.print('@');
170     ps.print(frame.getDepth());
171     
172     ps.print(" frame ");
173     ps.print( mi.getFullName());
174     ps.print( ":{" );
175     
176     if (!mi.isStatic()){
177       ps.print("this:");
178       PrintUtils.printReference(ps, frame.getThis());
179       ps.print(',');
180     }
181     
182     ps.print("pc:");
183     ps.print(frame.getPC().getInstructionIndex());
184     
185     ps.print(",slots:[");
186     frame.printSlots(ps);
187     ps.print(']');
188     
189     ps.print('}');
190   }
191   
192   public void println(){
193     ps.println();
194   }
195   
196   public void print (NativeStateHolder nsh){
197     ps.print(nsh);
198     ps.print(":");
199     ps.print(nsh.getHash());
200   }
201   
202   @Override
203   public void write(int b) throws IOException {
204     ps.write(b);
205   }
206 }