]> git.cworth.org Git - apitrace/blob - trace_parser.hpp
Cleanup files.
[apitrace] / trace_parser.hpp
1 /**************************************************************************
2  *
3  * Copyright 2010 VMware, Inc.
4  * All Rights Reserved.
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to deal
8  * in the Software without restriction, including without limitation the rights
9  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10  * copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22  * THE SOFTWARE.
23  *
24  **************************************************************************/
25
26 #ifndef _TRACE_PARSER_HPP_
27 #define _TRACE_PARSER_HPP_
28
29
30 #include <cassert>
31
32 #include <iostream>
33
34 #include <zlib.h>
35
36 #include "trace_format.hpp"
37 #include "trace_model.hpp"
38
39
40 namespace Trace {
41
42
43 class Parser
44 {
45 protected:
46    gzFile file;
47 public:
48    Parser() {
49       file = NULL;
50    }
51
52    bool parse(const char *filename) {
53       unsigned long long version;
54
55       file = gzopen(filename, "rb");
56       if (!file) {
57          return false;
58       }
59
60       version = read_uint();
61       if (version != TRACE_VERSION) {
62          std::cerr << "Unsupported format version" << version << "\n";
63          return false;
64       }
65
66       while (!gzeof(file)) {
67          parse_call();
68       }
69
70       return true;
71    }
72
73    void parse_call(void) {
74       Call call;
75       call.name = read_string();
76       int c;
77       do {
78          c = gzgetc(file);
79          if (c == Trace::CALL_END || c == -1) {
80             break;
81          }
82          switch(c) {
83          case Trace::CALL_END:
84             return;
85          case Trace::CALL_ARG:
86             call.args.push_back(parse_arg());
87             break;
88          case Trace::CALL_RET:
89             call.ret = parse_value();
90             break;
91          default:
92             assert(0);
93             std::cerr << "Unknown call detail " << c << "\n";
94             break;
95          }
96       } while(true);
97       handle_call(call);
98    }
99    
100    virtual void handle_call(Call &call) {
101       std::cout << call;
102    }
103
104    Arg parse_arg(void) {
105       std::string name = read_string();
106       Value *value = parse_value();
107       return Arg(name, value);
108    }
109    
110    Value *parse_value(void) {
111       int c;
112       c = gzgetc(file);
113       switch(c) {
114       case Trace::TYPE_BOOL:
115          return parse_bool();
116       case Trace::TYPE_SINT:
117          return parse_sint();
118       case Trace::TYPE_UINT:
119          return parse_uint();
120       case Trace::TYPE_FLOAT:
121          return parse_float();
122       case Trace::TYPE_DOUBLE:
123          return parse_double();
124       case Trace::TYPE_STRING:
125          return parse_string();
126       case Trace::TYPE_CONST:
127          return parse_const();
128       case Trace::TYPE_BITMASK:
129          return parse_bitmask();
130       case Trace::TYPE_ARRAY:
131          return parse_array();
132       case Trace::TYPE_POINTER:
133          return parse_pointer();
134       case Trace::TYPE_VOID:
135          return NULL;
136       default:
137          std::cerr << "Unknown type " << c << "\n";
138          assert(0);
139          return NULL;
140       }
141    }
142
143    Value *parse_bool() {
144       int c;
145       c = gzgetc(file);
146       return new Bool(c);
147    }
148    
149    Value *parse_sint() {
150       return new SInt(-read_uint());
151    }
152    
153    Value *parse_uint() {
154       return new UInt(read_uint());
155    }
156    
157    Value *parse_float() {
158       float value;
159       gzread(file, &value, sizeof value);
160       return new Float(value);
161    }
162    
163    Value *parse_double() {
164       double value;
165       gzread(file, &value, sizeof value);
166       return new Float(value);
167    }
168    
169    Value *parse_string() {
170       return new String(read_string());
171    }
172    
173    Value *parse_const() {
174       std::string name = read_string();
175       Value *value = parse_value();
176       return new Const(name, value);
177    }
178    
179    Value *parse_bitmask() {
180       unsigned long long value = 0;
181       int c;
182       do {
183          c = gzgetc(file);
184          switch(c) {
185          case Trace::TYPE_SINT:
186             value |= -read_uint();
187             break;
188          case Trace::TYPE_UINT:
189             value |= read_uint();
190             break;
191          case Trace::TYPE_CONST:
192             read_string();
193             break;
194          case Trace::TYPE_VOID:
195             goto done;
196          default:
197             std::cerr << "Unexpected type " << c << "\n";
198             assert(0);
199             return NULL;
200          }
201       } while(true);
202 done:
203       return new UInt(value);
204    }
205
206    Value *parse_array() {
207       size_t len = read_uint();
208       Array *array = new Array(len);
209       for (size_t i = 0; i < len; ++i) {
210          array->values[i] = parse_value();
211       }
212       return array;
213    }
214    
215    Value *parse_pointer() {
216       unsigned long long addr;
217       Value *value;
218       addr = read_uint();
219       value = parse_value();
220       if (!value)
221          value = new UInt(addr);
222       return value;
223    }
224    
225    std::string read_string(void) {
226       size_t len = read_uint();
227       char * buf = new char[len];
228       gzread(file, buf, len);
229       std::string value(buf, len);
230       delete [] buf;
231       return value;
232    }
233
234    unsigned long long read_uint(void) {
235       unsigned long long value = 0;
236       int c;
237       unsigned shift = 0;
238       do {
239          c = gzgetc(file);
240          if (c == -1) {
241             break;
242          }
243          value |= (unsigned long long)(c & 0x7f) << shift;
244          shift += 7;
245       } while(c & 0x80);
246       return value;
247    }
248 };
249
250
251 } /* namespace Trace */
252
253 #endif /* _TRACE_PARSER_HPP_ */