]> git.cworth.org Git - apitrace/blobdiff - trace_parser.hpp
More efficient enum representation.
[apitrace] / trace_parser.hpp
index 850dc8de821cd17d0f437a70b2522ce2d4ad07cc..254141c1bb6f66b4b4f4a9a830c5b8b10db4bff8 100644 (file)
@@ -56,6 +56,15 @@ protected:
    typedef std::map<unsigned, Call *> callmap;
    callmap calls;
 
+   typedef std::map<size_t, Call::Signature *> FunctionMap;
+   FunctionMap functions;
+
+   typedef std::map<size_t, Enum *> EnumMap;
+   EnumMap enums;
+
+   typedef std::map<size_t, Bitmask::Signature *> BitmaskMap;
+   BitmaskMap bitmasks;
+
    unsigned next_call_no;
 
 public:
@@ -115,9 +124,26 @@ public:
    }
    
    void parse_enter(void) {
-      Call *call = new Call;
+      size_t id = read_uint();
+
+      Call::Signature *sig;
+      FunctionMap::const_iterator it = functions.find(id);
+      if (it == functions.end()) {
+          sig = new Call::Signature;
+          sig->name = read_string();
+          unsigned size = read_uint();
+          for (unsigned i = 0; i < size; ++i) {
+              sig->arg_names.push_back(read_string());
+          }
+          functions[id] = sig;
+      } else {
+          sig = it->second;
+      }
+      assert(sig);
+
+      Call *call = new Call(sig);
       call->no = next_call_no++;
-      call->name = read_name();
+
       parse_call_details(call);
       calls[call->no] = call;
    }
@@ -157,12 +183,11 @@ public:
    
    void parse_arg(Call *call) {
       unsigned index = read_uint();
-      std::string name = read_name();
       Value *value = parse_value();
       if (index >= call->args.size()) {
           call->args.resize(index + 1);
       }
-      call->args[index] = Arg(name, value);
+      call->args[index] = value;
    }
    
    Value *parse_value(void) {
@@ -185,8 +210,8 @@ public:
          return parse_double();
       case Trace::TYPE_STRING:
          return parse_string();
-      case Trace::TYPE_CONST:
-         return parse_const();
+      case Trace::TYPE_ENUM:
+         return parse_enum();
       case Trace::TYPE_BITMASK:
          return parse_bitmask();
       case Trace::TYPE_ARRAY:
@@ -228,37 +253,43 @@ public:
       return new String(read_string());
    }
    
-   Value *parse_const() {
-      std::string name = read_name();
-      Value *value = parse_value();
-      return new Const(name, value);
+   Value *parse_enum() {
+      size_t id = read_uint();
+      Enum *sig;
+      EnumMap::const_iterator it = enums.find(id);
+      if (it == enums.end()) {
+          std::string name = read_string();
+          Value *value = parse_value();
+          sig = new Enum(name, value);
+          enums[id] = sig;
+      } else {
+          sig = it->second;
+      }
+      assert(sig);
+      return sig;
    }
    
    Value *parse_bitmask() {
-      unsigned long long value = 0;
-      int c;
-      do {
-         c = read_byte();
-         switch(c) {
-         case Trace::TYPE_SINT:
-            value |= -(signed long long)read_uint();
-            break;
-         case Trace::TYPE_UINT:
-            value |= read_uint();
-            break;
-         case Trace::TYPE_CONST:
-            read_name();
-            break;
-         case Trace::TYPE_NULL:
-            goto done;
-         default:
-            std::cerr << "error: uexpected type " << c << "\n";
-            assert(0);
-            return NULL;
-         }
-      } while(true);
-done:
-      return new UInt(value);
+      size_t id = read_uint();
+      Bitmask::Signature *sig;
+      BitmaskMap::const_iterator it = bitmasks.find(id);
+      if (it == bitmasks.end()) {
+          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;
+      } else {
+          sig = it->second;
+      }
+      assert(sig);
+
+      unsigned long long value = read_uint();
+
+      return new Bitmask(sig, value);
    }
 
    Value *parse_array(void) {