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();
89 call->args.push_back(parse_arg());
92 call->ret = parse_value();
95 std::cerr << "error: unknown call detail " << c << "\n";
105 Arg parse_arg(void) {
106 std::string name = read_string();
107 Value *value = parse_value();
108 return Arg(name, value);
111 Value *parse_value(void) {
115 case Trace::TYPE_NULL:
117 case Trace::TYPE_FALSE:
118 return new Bool(false);
119 case Trace::TYPE_TRUE:
120 return new Bool(true);
121 case Trace::TYPE_SINT:
123 case Trace::TYPE_UINT:
125 case Trace::TYPE_FLOAT:
126 return parse_float();
127 case Trace::TYPE_DOUBLE:
128 return parse_double();
129 case Trace::TYPE_STRING:
130 return parse_string();
131 case Trace::TYPE_CONST:
132 return parse_const();
133 case Trace::TYPE_BITMASK:
134 return parse_bitmask();
135 case Trace::TYPE_ARRAY:
136 return parse_array();
137 case Trace::TYPE_STRUCT:
138 return parse_struct();
139 case Trace::TYPE_BLOB:
141 case Trace::TYPE_POINTER:
142 return parse_pointer();
143 case Trace::TYPE_OPAQUE:
144 return parse_opaque();
146 std::cerr << "error: unknown type " << c << "\n";
152 Value *parse_sint() {
153 return new SInt(-read_uint());
156 Value *parse_uint() {
157 return new UInt(read_uint());
160 Value *parse_float() {
162 gzread(file, &value, sizeof value);
163 return new Float(value);
166 Value *parse_double() {
168 gzread(file, &value, sizeof value);
169 return new Float(value);
172 Value *parse_string() {
173 return new String(read_string());
176 Value *parse_const() {
177 std::string name = read_string();
178 Value *value = parse_value();
179 return new Const(name, value);
182 Value *parse_bitmask() {
183 unsigned long long value = 0;
188 case Trace::TYPE_SINT:
189 value |= -read_uint();
191 case Trace::TYPE_UINT:
192 value |= read_uint();
194 case Trace::TYPE_CONST:
197 case Trace::TYPE_NULL:
200 std::cerr << "error: uexpected type " << c << "\n";
206 return new UInt(value);
209 Value *parse_array(void) {
210 size_t len = read_uint();
211 Array *array = new Array(len);
212 for (size_t i = 0; i < len; ++i) {
213 array->values[i] = parse_value();
218 Value *parse_blob(void) {
219 size_t size = read_uint();
220 Blob *blob = new Blob(size);
222 gzread(file, blob->buf, size);
227 Value *parse_pointer() {
228 unsigned long long addr;
231 value = parse_value();
233 value = new UInt(addr);
237 Value *parse_struct() {
240 name = read_string();
241 while(name.length()) {
242 Value *value = parse_value();
243 std::cout << " " << name << " = " << value << "\n";
244 name = read_string();
249 Value *parse_opaque() {
250 unsigned long long addr;
253 return new UInt(addr);
256 std::string read_string(void) {
257 size_t len = read_uint();
259 return std::string();
261 char * buf = new char[len];
262 gzread(file, buf, len);
263 std::string value(buf, len);
266 std::cerr << '"' << value << '"' << "\n";
271 unsigned long long read_uint(void) {
272 unsigned long long value = 0;
280 value |= (unsigned long long)(c & 0x7f) << shift;
284 std::cerr << value << "\n";
289 int read_byte(void) {
290 int c = gzgetc(file);
293 std::cerr << "EOF" << "\n";
295 std::cerr << "0x" << std::hex << c << "\n";
302 } /* namespace Trace */
304 #endif /* _TRACE_PARSER_HPP_ */