- }
- } while(true);
-done:
- return new UInt(value);
- }
-
- Value *parse_array(void) {
- size_t len = read_uint();
- Array *array = new Array(len);
- for (size_t i = 0; i < len; ++i) {
- array->values[i] = parse_value();
- }
- return array;
- }
-
- Value *parse_blob(void) {
- size_t size = read_uint();
- Blob *blob = new Blob(size);
- if (size) {
- gzread(file, blob->buf, size);
- }
- return blob;
- }
-
- Value *parse_struct() {
- size_t length = read_uint();
- /* XXX */
- for (size_t i = 0; i < length; ++i) {
- std::string name = read_name();
- Value *value = parse_value();
- std::cout << " " << name << " = " << value << "\n";
- }
- return NULL;
- }
-
- Value *parse_opaque() {
- unsigned long long addr;
- addr = read_uint();
- /* XXX */
- return new UInt(addr);
- }
-
- std::string read_name(void) {
- std::string name;
- size_t id = read_uint();
- if (id >= names.size()) {
- name = read_string();
- names[id] = name;
- return name;
- } else {
- return names[id];
- }
- }
-
- std::string read_string(void) {
- size_t len = read_uint();
- if (!len) {
- return std::string();
- }
- char * buf = new char[len];
- gzread(file, buf, len);
- std::string value(buf, len);
- delete [] buf;
-#ifdef TRACE_VERBOSE
- std::cerr << '"' << value << '"' << "\n";
+ }
+ }
+
+ Value *parse_sint() {
+ return new SInt(-(signed long long)read_uint());
+ }
+
+ Value *parse_uint() {
+ return new UInt(read_uint());
+ }
+
+ Value *parse_float() {
+ float value;
+ gzread(file, &value, sizeof value);
+ return new Float(value);
+ }
+
+ Value *parse_double() {
+ double value;
+ gzread(file, &value, sizeof value);
+ return new Float(value);
+ }
+
+ Value *parse_string() {
+ return new String(read_string());
+ }
+
+ Value *parse_enum() {
+ size_t id = read_uint();
+ Enum *sig = lookup(enums, id);
+ if (!sig) {
+ std::string name = read_string();
+ Value *value = parse_value();
+ sig = new Enum(name, value);
+ enums[id] = sig;
+ }
+ assert(sig);
+ return sig;
+ }
+
+ Value *parse_bitmask() {
+ size_t id = read_uint();
+ Bitmask::Signature *sig = lookup(bitmasks, id);
+ if (!sig) {
+ size_t size = read_uint();
+ sig = new Bitmask::Signature(size);
+ for (Bitmask::Signature::iterator it = sig->begin(); it != sig->end(); ++it) {
+ it->first = read_string();
+ it->second = read_uint();
+ assert(it->second);
+ }
+ bitmasks[id] = sig;
+ }
+ assert(sig);
+
+ unsigned long long value = read_uint();
+
+ return new Bitmask(sig, value);
+ }
+
+ Value *parse_array(void) {
+ size_t len = read_uint();
+ Array *array = new Array(len);
+ for (size_t i = 0; i < len; ++i) {
+ array->values[i] = parse_value();
+ }
+ return array;
+ }
+
+ Value *parse_blob(void) {
+ size_t size = read_uint();
+ Blob *blob = new Blob(size);
+ if (size) {
+ gzread(file, blob->buf, size);
+ }
+ return blob;
+ }
+
+ Value *parse_struct() {
+ size_t id = read_uint();
+
+ Struct::Signature *sig = lookup(structs, id);
+ if (!sig) {
+ sig = new Struct::Signature;
+ sig->name = read_string();
+ unsigned size = read_uint();
+ for (unsigned i = 0; i < size; ++i) {
+ sig->member_names.push_back(read_string());
+ }
+ structs[id] = sig;
+ }
+ assert(sig);
+
+ Struct *value = new Struct(sig);
+
+ for (size_t i = 0; i < sig->member_names.size(); ++i) {
+ value->members[i] = parse_value();
+ }
+
+ return value;
+ }
+
+ Value *parse_opaque() {
+ unsigned long long addr;
+ addr = read_uint();
+ /* XXX */
+ return new UInt(addr);
+ }
+
+ std::string read_string(void) {
+ size_t len = read_uint();
+ if (!len) {
+ return std::string();
+ }
+ char * buf = new char[len];
+ gzread(file, buf, len);
+ std::string value(buf, len);
+ delete [] buf;
+#if TRACE_VERBOSE
+ std::cerr << "\tSTRING \"" << value << "\"\n";