glretrace: Create decorator parser class to allow variety of parsers.

The parser class is abstracted so that various looping parsers  can be
added as decorators.  Add the last frame looping parser as the first
looping parser.  Fix the singlethreaded case so it functions with the
looping parser just like the multithreaded case.

v2: Simplify/cleanup -- Jose Fonseca <jfonseca@vmware.com>
diff --git a/common/trace_parser.hpp b/common/trace_parser.hpp
index fb24743..e62092a 100644
--- a/common/trace_parser.hpp
+++ b/common/trace_parser.hpp
@@ -45,7 +45,21 @@
 };
 
 
-class Parser
+// Parser interface
+class AbstractParser
+{
+public:
+    virtual ~AbstractParser() {}
+    virtual  Call *parse_call(void) = 0;
+    virtual void getBookmark(ParseBookmark &bookmark) = 0;
+    virtual void setBookmark(const ParseBookmark &bookmark) = 0;
+    virtual bool open(const char *filename) = 0;
+    virtual void close(void) = 0;
+    virtual unsigned long long getVersion(void) const = 0;
+};
+
+
+class Parser: public AbstractParser
 {
 protected:
     File *file;
@@ -95,8 +109,8 @@
 
     unsigned next_call_no;
 
-public:
     unsigned long long version;
+public:
     API api;
 
     Parser();
@@ -120,6 +134,10 @@
 
     void setBookmark(const ParseBookmark &bookmark);
 
+    unsigned long long getVersion(void) const {
+        return version;
+    }
+
     int percentRead()
     {
         return file->percentRead();
@@ -222,5 +240,33 @@
 };
 
 
+// Decorator for parser which loops
+class LastFrameLoopParser : public AbstractParser  {
+public:
+    LastFrameLoopParser(AbstractParser *p, int c) {
+        parser = p;
+        loopCount = c;
+    }
+
+    ~LastFrameLoopParser() {
+        delete parser;
+    }
+
+    Call *parse_call(void);
+
+    // Delegate to Parser
+    void getBookmark(ParseBookmark &bookmark) { parser->getBookmark(bookmark); }
+    void setBookmark(const ParseBookmark &bookmark) { parser->setBookmark(bookmark); }
+    bool open(const char *filename);
+    void close(void) { parser->close(); }
+    unsigned long long getVersion(void) const { return parser->getVersion(); }
+private:
+    int loopCount;
+    AbstractParser *parser;
+    ParseBookmark frameStart;
+    ParseBookmark lastFrameStart;
+};
+
+
 } /* namespace trace */