]> git.cworth.org Git - apitrace/blob - trace_parser.hpp
Use more standard names on FindDirectX.cmake
[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 << "error: 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             std::cerr << "error: unknown call detail " << c << "\n";
93             assert(0);
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_NULL:
115          return new Null;
116       case Trace::TYPE_FALSE:
117          return new Bool(false);
118       case Trace::TYPE_TRUE:
119          return new Bool(true);
120       case Trace::TYPE_SINT:
121          return parse_sint();
122       case Trace::TYPE_UINT:
123          return parse_uint();
124       case Trace::TYPE_FLOAT:
125          return parse_float();
126       case Trace::TYPE_DOUBLE:
127          return parse_double();
128       case Trace::TYPE_STRING:
129          return parse_string();
130       case Trace::TYPE_CONST:
131          return parse_const();
132       case Trace::TYPE_BITMASK:
133          return parse_bitmask();
134       case Trace::TYPE_ARRAY:
135          return parse_array();
136       case Trace::TYPE_BLOB:
137          return parse_blob();
138       case Trace::TYPE_POINTER:
139          return parse_pointer();
140       case Trace::TYPE_OPAQUE:
141          return parse_opaque();
142       default:
143          std::cerr << "error: unknown type " << c << "\n";
144          assert(0);
145          return NULL;
146       }
147    }
148
149    Value *parse_bool() {
150       int c;
151       c = gzgetc(file);
152       return new Bool(c);
153    }
154    
155    Value *parse_sint() {
156       return new SInt(-read_uint());
157    }
158    
159    Value *parse_uint() {
160       return new UInt(read_uint());
161    }
162    
163    Value *parse_float() {
164       float value;
165       gzread(file, &value, sizeof value);
166       return new Float(value);
167    }
168    
169    Value *parse_double() {
170       double value;
171       gzread(file, &value, sizeof value);
172       return new Float(value);
173    }
174    
175    Value *parse_string() {
176       return new String(read_string());
177    }
178    
179    Value *parse_const() {
180       std::string name = read_string();
181       Value *value = parse_value();
182       return new Const(name, value);
183    }
184    
185    Value *parse_bitmask() {
186       unsigned long long value = 0;
187       int c;
188       do {
189          c = gzgetc(file);
190          switch(c) {
191          case Trace::TYPE_SINT:
192             value |= -read_uint();
193             break;
194          case Trace::TYPE_UINT:
195             value |= read_uint();
196             break;
197          case Trace::TYPE_CONST:
198             read_string();
199             break;
200          case Trace::TYPE_NULL:
201             goto done;
202          default:
203             std::cerr << "error: uexpected type " << c << "\n";
204             assert(0);
205             return NULL;
206          }
207       } while(true);
208 done:
209       return new UInt(value);
210    }
211
212    Value *parse_array(void) {
213       size_t len = read_uint();
214       Array *array = new Array(len);
215       for (size_t i = 0; i < len; ++i) {
216          array->values[i] = parse_value();
217       }
218       return array;
219    }
220    
221    Value *parse_blob(void) {
222       size_t size = read_uint();
223       Blob *blob = new Blob(size);
224       if (size) {
225           gzread(file, blob->buf, size);
226       }
227       return blob;
228    }
229    
230    Value *parse_pointer() {
231       unsigned long long addr;
232       Value *value;
233       addr = read_uint();
234       value = parse_value();
235       if (!value)
236          value = new UInt(addr);
237       return value;
238    }
239    
240    Value *parse_opaque() {
241       unsigned long long addr;
242       addr = read_uint();
243       /* XXX */
244       return new UInt(addr);
245    }
246    
247    std::string read_string(void) {
248       size_t len = read_uint();
249       char * buf = new char[len];
250       gzread(file, buf, len);
251       std::string value(buf, len);
252       delete [] buf;
253       return value;
254    }
255
256    unsigned long long read_uint(void) {
257       unsigned long long value = 0;
258       int c;
259       unsigned shift = 0;
260       do {
261          c = gzgetc(file);
262          if (c == -1) {
263             break;
264          }
265          value |= (unsigned long long)(c & 0x7f) << shift;
266          shift += 7;
267       } while(c & 0x80);
268       return value;
269    }
270 };
271
272
273 } /* namespace Trace */
274
275 #endif /* _TRACE_PARSER_HPP_ */