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_
38 #include "trace_format.hpp"
39 #include "trace_model.hpp"
42 #define TRACE_VERBOSE 0
53 typedef std::map<size_t, std::string> namemap;
65 bool open(const char *filename) {
66 unsigned long long version;
68 file = gzopen(filename, "rb");
73 version = read_uint();
74 if (version != TRACE_VERSION) {
75 std::cerr << "error: unsupported format version" << version << "\n";
89 Call *parse_call(void) {
90 Call *call = new Call;
91 call->name = read_name();
100 case Trace::CALL_RET:
101 call->ret = parse_value();
104 std::cerr << "error: unknown call detail " << c << "\n";
114 void parse_arg(Call *call) {
115 unsigned index = read_uint();
116 std::string name = read_name();
117 Value *value = parse_value();
118 if (index >= call->args.size()) {
119 call->args.resize(index + 1);
121 call->args[index] = Arg(name, value);
124 Value *parse_value(void) {
128 case Trace::TYPE_NULL:
130 case Trace::TYPE_FALSE:
131 return new Bool(false);
132 case Trace::TYPE_TRUE:
133 return new Bool(true);
134 case Trace::TYPE_SINT:
136 case Trace::TYPE_UINT:
138 case Trace::TYPE_FLOAT:
139 return parse_float();
140 case Trace::TYPE_DOUBLE:
141 return parse_double();
142 case Trace::TYPE_STRING:
143 return parse_string();
144 case Trace::TYPE_CONST:
145 return parse_const();
146 case Trace::TYPE_BITMASK:
147 return parse_bitmask();
148 case Trace::TYPE_ARRAY:
149 return parse_array();
150 case Trace::TYPE_STRUCT:
151 return parse_struct();
152 case Trace::TYPE_BLOB:
154 case Trace::TYPE_OPAQUE:
155 return parse_opaque();
157 std::cerr << "error: unknown type " << c << "\n";
163 Value *parse_sint() {
164 return new SInt(-(signed long long)read_uint());
167 Value *parse_uint() {
168 return new UInt(read_uint());
171 Value *parse_float() {
173 gzread(file, &value, sizeof value);
174 return new Float(value);
177 Value *parse_double() {
179 gzread(file, &value, sizeof value);
180 return new Float(value);
183 Value *parse_string() {
184 return new String(read_string());
187 Value *parse_const() {
188 std::string name = read_name();
189 Value *value = parse_value();
190 return new Const(name, value);
193 Value *parse_bitmask() {
194 unsigned long long value = 0;
199 case Trace::TYPE_SINT:
200 value |= -(signed long long)read_uint();
202 case Trace::TYPE_UINT:
203 value |= read_uint();
205 case Trace::TYPE_CONST:
208 case Trace::TYPE_NULL:
211 std::cerr << "error: uexpected type " << c << "\n";
217 return new UInt(value);
220 Value *parse_array(void) {
221 size_t len = read_uint();
222 Array *array = new Array(len);
223 for (size_t i = 0; i < len; ++i) {
224 array->values[i] = parse_value();
229 Value *parse_blob(void) {
230 size_t size = read_uint();
231 Blob *blob = new Blob(size);
233 gzread(file, blob->buf, size);
238 Value *parse_struct() {
239 size_t length = read_uint();
241 for (size_t i = 0; i < length; ++i) {
242 std::string name = read_name();
243 Value *value = parse_value();
244 std::cout << " " << name << " = " << value << "\n";
249 Value *parse_opaque() {
250 unsigned long long addr;
253 return new UInt(addr);
256 std::string read_name(void) {
258 size_t id = read_uint();
259 if (id >= names.size()) {
260 assert(id == names.size());
261 name = read_string();
268 std::cerr << "\tNAME " << id << " " << name << "\n";
273 std::string read_string(void) {
274 size_t len = read_uint();
276 return std::string();
278 char * buf = new char[len];
279 gzread(file, buf, len);
280 std::string value(buf, len);
283 std::cerr << "\tSTRING \"" << value << "\"\n";
288 unsigned long long read_uint(void) {
289 unsigned long long value = 0;
297 value |= (unsigned long long)(c & 0x7f) << shift;
301 std::cerr << "\tUINT " << value << "\n";
306 int read_byte(void) {
307 int c = gzgetc(file);
310 std::cerr << "\tEOF" << "\n";
312 std::cerr << "\tBYTE 0x" << std::hex << c << std::dec << "\n";
319 } /* namespace Trace */
321 #endif /* _TRACE_PARSER_HPP_ */