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"
56 bool open(const char *filename) {
57 unsigned long long version;
59 file = gzopen(filename, "rb");
64 version = read_uint();
65 if (version != TRACE_VERSION) {
66 std::cerr << "error: unsupported format version" << version << "\n";
80 Call *parse_call(void) {
81 Call *call = new Call;
82 call->name = read_string();
92 call->ret = parse_value();
95 std::cerr << "error: unknown call detail " << c << "\n";
105 void parse_arg(Call *call) {
106 unsigned index = read_uint();
107 std::string name = read_string();
108 Value *value = parse_value();
109 if (index >= call->args.size()) {
110 call->args.resize(index + 1);
112 call->args[index] = Arg(name, value);
115 Value *parse_value(void) {
119 case Trace::TYPE_NULL:
121 case Trace::TYPE_FALSE:
122 return new Bool(false);
123 case Trace::TYPE_TRUE:
124 return new Bool(true);
125 case Trace::TYPE_SINT:
127 case Trace::TYPE_UINT:
129 case Trace::TYPE_FLOAT:
130 return parse_float();
131 case Trace::TYPE_DOUBLE:
132 return parse_double();
133 case Trace::TYPE_STRING:
134 return parse_string();
135 case Trace::TYPE_CONST:
136 return parse_const();
137 case Trace::TYPE_BITMASK:
138 return parse_bitmask();
139 case Trace::TYPE_ARRAY:
140 return parse_array();
141 case Trace::TYPE_STRUCT:
142 return parse_struct();
143 case Trace::TYPE_BLOB:
145 case Trace::TYPE_OPAQUE:
146 return parse_opaque();
148 std::cerr << "error: unknown type " << c << "\n";
154 Value *parse_sint() {
155 return new SInt(-read_uint());
158 Value *parse_uint() {
159 return new UInt(read_uint());
162 Value *parse_float() {
164 gzread(file, &value, sizeof value);
165 return new Float(value);
168 Value *parse_double() {
170 gzread(file, &value, sizeof value);
171 return new Float(value);
174 Value *parse_string() {
175 return new String(read_string());
178 Value *parse_const() {
179 std::string name = read_string();
180 Value *value = parse_value();
181 return new Const(name, value);
184 Value *parse_bitmask() {
185 unsigned long long value = 0;
190 case Trace::TYPE_SINT:
191 value |= -read_uint();
193 case Trace::TYPE_UINT:
194 value |= read_uint();
196 case Trace::TYPE_CONST:
199 case Trace::TYPE_NULL:
202 std::cerr << "error: uexpected type " << c << "\n";
208 return new UInt(value);
211 Value *parse_array(void) {
212 size_t len = read_uint();
213 Array *array = new Array(len);
214 for (size_t i = 0; i < len; ++i) {
215 array->values[i] = parse_value();
220 Value *parse_blob(void) {
221 size_t size = read_uint();
222 Blob *blob = new Blob(size);
224 gzread(file, blob->buf, size);
229 Value *parse_struct() {
232 name = read_string();
233 while(name.length()) {
234 Value *value = parse_value();
235 std::cout << " " << name << " = " << value << "\n";
236 name = read_string();
241 Value *parse_opaque() {
242 unsigned long long addr;
245 return new UInt(addr);
248 std::string read_string(void) {
249 size_t len = read_uint();
251 return std::string();
253 char * buf = new char[len];
254 gzread(file, buf, len);
255 std::string value(buf, len);
258 std::cerr << '"' << value << '"' << "\n";
263 unsigned long long read_uint(void) {
264 unsigned long long value = 0;
272 value |= (unsigned long long)(c & 0x7f) << shift;
276 std::cerr << value << "\n";
281 int read_byte(void) {
282 int c = gzgetc(file);
285 std::cerr << "EOF" << "\n";
287 std::cerr << "0x" << std::hex << c << "\n";
294 } /* namespace Trace */
296 #endif /* _TRACE_PARSER_HPP_ */