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