1 /**************************************************************************
3 * Copyright 2010 VMware, Inc.
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:
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
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
24 **************************************************************************/
26 #ifndef _TRACE_PARSER_HPP_
27 #define _TRACE_PARSER_HPP_
36 #include "trace_format.hpp"
37 #include "trace_model.hpp"
52 bool parse(const char *filename) {
53 unsigned long long version;
55 file = gzopen(filename, "rb");
60 version = read_uint();
61 if (version != TRACE_VERSION) {
62 std::cerr << "error: unsupported format version" << version << "\n";
66 while (!gzeof(file)) {
73 void parse_call(void) {
75 call.name = read_string();
79 if (c == Trace::CALL_END || c == -1) {
86 call.args.push_back(parse_arg());
89 call.ret = parse_value();
92 std::cerr << "error: unknown call detail " << c << "\n";
100 virtual void handle_call(Call &call) {
104 Arg parse_arg(void) {
105 std::string name = read_string();
106 Value *value = parse_value();
107 return Arg(name, value);
110 Value *parse_value(void) {
114 case Trace::TYPE_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:
122 case Trace::TYPE_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:
138 case Trace::TYPE_POINTER:
139 return parse_pointer();
140 case Trace::TYPE_OPAQUE:
141 return parse_opaque();
143 std::cerr << "error: unknown type " << c << "\n";
149 Value *parse_bool() {
155 Value *parse_sint() {
156 return new SInt(-read_uint());
159 Value *parse_uint() {
160 return new UInt(read_uint());
163 Value *parse_float() {
165 gzread(file, &value, sizeof value);
166 return new Float(value);
169 Value *parse_double() {
171 gzread(file, &value, sizeof value);
172 return new Float(value);
175 Value *parse_string() {
176 return new String(read_string());
179 Value *parse_const() {
180 std::string name = read_string();
181 Value *value = parse_value();
182 return new Const(name, value);
185 Value *parse_bitmask() {
186 unsigned long long value = 0;
191 case Trace::TYPE_SINT:
192 value |= -read_uint();
194 case Trace::TYPE_UINT:
195 value |= read_uint();
197 case Trace::TYPE_CONST:
200 case Trace::TYPE_NULL:
203 std::cerr << "error: uexpected type " << c << "\n";
209 return new UInt(value);
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();
221 Value *parse_blob(void) {
222 size_t size = read_uint();
223 Blob *blob = new Blob(size);
225 gzread(file, blob->buf, size);
230 Value *parse_pointer() {
231 unsigned long long addr;
234 value = parse_value();
236 value = new UInt(addr);
240 Value *parse_opaque() {
241 unsigned long long addr;
244 return new UInt(addr);
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);
256 unsigned long long read_uint(void) {
257 unsigned long long value = 0;
265 value |= (unsigned long long)(c & 0x7f) << shift;
273 } /* namespace Trace */
275 #endif /* _TRACE_PARSER_HPP_ */