]> git.cworth.org Git - apitrace/commitdiff
Switch the gui to the on-demand-loader.
authorZack Rusin <zack@kde.org>
Tue, 6 Sep 2011 21:44:43 +0000 (17:44 -0400)
committerZack Rusin <zack@kde.org>
Tue, 6 Sep 2011 21:44:43 +0000 (17:44 -0400)
Doesn't yet do actual on demand loading, but a lot of the code is
in place.

13 files changed:
gui/CMakeLists.txt
gui/apitrace.cpp
gui/apitrace.h
gui/apitracecall.cpp
gui/apitracecall.h
gui/apitracemodel.cpp
gui/mainwindow.cpp
gui/mainwindow.h
gui/traceloader.cpp
gui/traceloader.h
trace_file.cpp
trace_parser.cpp
trace_parser.hpp

index e0cfe44f04206b6a0c204863dff418d46c39d7d7..777bc9255c7c1d4c83207ec7ac12e826657e1700 100644 (file)
@@ -12,7 +12,6 @@ set(qapitrace_SRCS
    glsledit.cpp
    imageviewer.cpp
    jumpwidget.cpp
-   loaderthread.cpp
    mainwindow.cpp
    main.cpp
    retracer.cpp
index 9a68e63d56eb0ee3db5233bf327ac481527a50bb..d6a9e41375c2cda6ef5f39eb43084e21d2b35cc0 100644 (file)
@@ -1,31 +1,46 @@
 #include "apitrace.h"
 
-#include "loaderthread.h"
+#include "traceloader.h"
 #include "saverthread.h"
 
 #include <QDir>
+#include <QThread>
 
 ApiTrace::ApiTrace()
     : m_frameMarker(ApiTrace::FrameMarker_SwapBuffers),
       m_needsSaving(false)
 {
-    m_loader = new LoaderThread(this);
-    connect(m_loader, SIGNAL(parsedFrames(const QList<ApiTraceFrame*>)),
+    m_loader = new TraceLoader();
+    connect(this, SIGNAL(loadTrace(QString)),
+            m_loader, SLOT(loadTrace(QString)));
+    connect(m_loader, SIGNAL(framesLoaded(const QList<ApiTraceFrame*>)),
             this, SLOT(addFrames(const QList<ApiTraceFrame*>)));
-    connect(m_loader, SIGNAL(started()),
+    connect(m_loader, SIGNAL(frameLoaded(int,QVector<ApiTraceCall*>,quint64)),
+            this, SLOT(fillFrame(int,QVector<ApiTraceCall*>,quint64)));
+
+    connect(m_loader, SIGNAL(startedParsing()),
             this, SIGNAL(startedLoadingTrace()));
-    connect(m_loader, SIGNAL(finished()),
+    connect(m_loader, SIGNAL(parsed(int)),
+            this, SIGNAL(loaded(int)));
+    connect(m_loader, SIGNAL(finishedParsing()),
             this, SIGNAL(finishedLoadingTrace()));
 
+
     m_saver = new SaverThread(this);
     connect(m_saver, SIGNAL(traceSaved()),
             this, SLOT(slotSaved()));
     connect(m_saver, SIGNAL(traceSaved()),
             this, SIGNAL(saved()));
+
+    m_loaderThread = new QThread();
+    m_loader->moveToThread(m_loaderThread);
+    m_loaderThread->start();
 }
 
 ApiTrace::~ApiTrace()
 {
+    m_loaderThread->quit();
+    m_loaderThread->deleteLater();
     qDeleteAll(m_calls);
     qDeleteAll(m_frames);
     delete m_loader;
@@ -118,10 +133,6 @@ void ApiTrace::setFileName(const QString &name)
     if (m_fileName != name) {
         m_fileName = name;
 
-        if (m_loader->isRunning()) {
-            m_loader->terminate();
-            m_loader->wait();
-        }
         m_frames.clear();
         m_calls.clear();
         m_errors.clear();
@@ -129,7 +140,8 @@ void ApiTrace::setFileName(const QString &name)
         m_needsSaving = false;
         emit invalidated();
 
-        m_loader->loadFile(m_fileName);
+//        m_loader->loadTrace(m_fileName);
+        emit loadTrace(m_fileName);
     }
 }
 
@@ -157,7 +169,7 @@ void ApiTrace::addFrames(const QList<ApiTraceFrame*> &frames)
     int currentCalls = m_calls.count();
     int numNewCalls = 0;
     foreach(ApiTraceFrame *frame, frames) {
-        Q_ASSERT(this == frame->parentTrace());
+        frame->setParentTrace(this);
         numNewCalls += frame->numChildren();
         calls += frame->calls();
     }
@@ -290,34 +302,9 @@ bool ApiTrace::hasErrors() const
     return !m_errors.isEmpty();
 }
 
-ApiTraceCallSignature * ApiTrace::signature(unsigned id)
-{
-    if (id >= m_signatures.count()) {
-        m_signatures.resize(id + 1);
-        return NULL;
-    } else {
-        return m_signatures[id];
-    }
-}
-
-void ApiTrace::addSignature(unsigned id, ApiTraceCallSignature *signature)
-{
-    m_signatures[id] = signature;
-}
-
-ApiTraceEnumSignature * ApiTrace::enumSignature(unsigned id)
-{
-    if (id >= m_enumSignatures.count()) {
-        m_enumSignatures.resize(id + 1);
-        return NULL;
-    } else {
-        return m_enumSignatures[id];
-    }
-}
-
-void ApiTrace::addEnumSignature(unsigned id, ApiTraceEnumSignature *signature)
+void ApiTrace::fillFrame(int frameIdx, const QVector<ApiTraceCall *> &calls,
+                         quint64 binaryDataSize)
 {
-    m_enumSignatures[id] = signature;
 }
 
 #include "apitrace.moc"
index 036a84cdd0b14f150560570c6104b8c543772169..3b737e0bbe81c3281d5e54e463b8029d6163aeb9 100644 (file)
@@ -6,8 +6,9 @@
 #include <QObject>
 #include <QSet>
 
-class LoaderThread;
+class TraceLoader;
 class SaverThread;
+class QThread;
 
 class ApiTrace : public QObject
 {
@@ -33,13 +34,6 @@ public:
 
     ApiTraceState defaultState() const;
 
-    ApiTraceCallSignature *signature(unsigned id);
-    void addSignature(unsigned id, ApiTraceCallSignature *signature);
-
-    ApiTraceEnumSignature *enumSignature(unsigned id);
-    void addEnumSignature(unsigned id, ApiTraceEnumSignature *signature);
-
-
     QVector<ApiTraceCall*> calls() const;
     ApiTraceCall *callAt(int idx) const;
     ApiTraceCall *callWithIndex(int idx) const;
@@ -67,7 +61,9 @@ public slots:
     void save();
 
 signals:
+    void loadTrace(const QString &name);
     void startedLoadingTrace();
+    void loaded(int percent);
     void finishedLoadingTrace();
     void invalidated();
     void framesInvalidated();
@@ -81,6 +77,8 @@ signals:
 
 private slots:
     void addFrames(const QList<ApiTraceFrame*> &frames);
+    void fillFrame(int frameIdx, const QVector<ApiTraceCall*> &calls,
+                   quint64 binaryDataSize);
     void slotSaved();
 private:
     void detectFrames();
@@ -93,7 +91,8 @@ private:
 
     FrameMarker m_frameMarker;
 
-    LoaderThread *m_loader;
+    TraceLoader *m_loader;
+    QThread     *m_loaderThread;
     SaverThread  *m_saver;
 
     QSet<ApiTraceCall*> m_editedCalls;
@@ -101,8 +100,6 @@ private:
     bool m_needsSaving;
 
     QSet<ApiTraceCall*> m_errors;
-    QVector<ApiTraceCallSignature*> m_signatures;
-    QVector<ApiTraceEnumSignature*> m_enumSignatures;
 };
 
 #endif
index 680d22a543ad73c9a7e03dcf80c9d6ccc64e874a..d1de5a85f5c29700f2e01da4790abe21abf2b21d 100644 (file)
@@ -1,6 +1,7 @@
 #include "apitracecall.h"
 
 #include "apitrace.h"
+#include "traceloader.h"
 #include "trace_model.hpp"
 
 #include <QDebug>
@@ -175,15 +176,15 @@ void VariantVisitor::visit(Trace::Enum *e)
 {
     ApiTraceEnumSignature *sig = 0;
 
-    if (m_trace) {
-        sig = m_trace->enumSignature(e->sig->id);
+    if (m_loader) {
+        sig = m_loader->enumSignature(e->sig->id);
     }
     if (!sig) {
         sig = new ApiTraceEnumSignature(
             QString::fromStdString(e->sig->name),
             QVariant(e->sig->value));
-        if (m_trace) {
-            m_trace->addEnumSignature(e->sig->id, sig);
+        if (m_loader) {
+            m_loader->addEnumSignature(e->sig->id, sig);
         }
     }
 
@@ -600,17 +601,15 @@ void ApiTraceEvent::setState(ApiTraceState *state)
     m_state = state;
 }
 
-ApiTraceCall::ApiTraceCall(ApiTraceFrame *parentFrame, const Trace::Call *call)
+ApiTraceCall::ApiTraceCall(ApiTraceFrame *parentFrame,
+                           TraceLoader *loader,
+                           const Trace::Call *call)
     : ApiTraceEvent(ApiTraceEvent::Call),
       m_parentFrame(parentFrame)
 {
-    ApiTrace *trace = parentTrace();
-
-    Q_ASSERT(trace);
-
     m_index = call->no;
 
-    m_signature = trace->signature(call->sig->id);
+    m_signature = loader->signature(call->sig->id);
 
     if (!m_signature) {
         QString name = QString::fromStdString(call->sig->name);
@@ -620,16 +619,16 @@ ApiTraceCall::ApiTraceCall(ApiTraceFrame *parentFrame, const Trace::Call *call)
             argNames += QString::fromStdString(call->sig->arg_names[i]);
         }
         m_signature = new ApiTraceCallSignature(name, argNames);
-        trace->addSignature(call->sig->id, m_signature);
+        loader->addSignature(call->sig->id, m_signature);
     }
     if (call->ret) {
-        VariantVisitor retVisitor(trace);
+        VariantVisitor retVisitor(loader);
         call->ret->visit(retVisitor);
         m_returnValue = retVisitor.variant();
     }
     m_argValues.reserve(call->args.size());
     for (int i = 0; i < call->args.size(); ++i) {
-        VariantVisitor argVisitor(trace);
+        VariantVisitor argVisitor(loader);
         call->args[i]->visit(argVisitor);
         m_argValues.append(argVisitor.variant());
         if (m_argValues[i].type() == QVariant::ByteArray) {
@@ -1035,3 +1034,8 @@ void ApiTraceFrame::setNumChildren(int num)
 {
     m_callsToLoad = num;
 }
+
+void ApiTraceFrame::setParentTrace(ApiTrace *parent)
+{
+    m_parentTrace = parent;
+}
index 5a5a64b9eadd6b5c26d6ff38ecf6dd98ec5d8960..865f60c2ff7d406df6f3a52846794ce44b5122d5 100644 (file)
 
 
 class ApiTrace;
+class TraceLoader;
 
 class VariantVisitor : public Trace::Visitor
 {
 public:
-    VariantVisitor(ApiTrace *trace)
-        : m_trace(trace)
+    VariantVisitor(TraceLoader *loader)
+        : m_loader(loader)
     {}
     virtual void visit(Trace::Null *);
     virtual void visit(Trace::Bool *node);
@@ -37,7 +38,7 @@ public:
         return m_variant;
     }
 private:
-    ApiTrace *m_trace;
+    TraceLoader *m_loader;
     QVariant m_variant;
 };
 
@@ -233,7 +234,8 @@ Q_DECLARE_METATYPE(ApiTraceEvent*);
 class ApiTraceCall : public ApiTraceEvent
 {
 public:
-    ApiTraceCall(ApiTraceFrame *parentFrame, const Trace::Call *tcall);
+    ApiTraceCall(ApiTraceFrame *parentFrame, TraceLoader *loader,
+                 const Trace::Call *tcall);
     ~ApiTraceCall();
 
     int index() const;
@@ -284,11 +286,12 @@ Q_DECLARE_METATYPE(ApiTraceCall*);
 class ApiTraceFrame : public ApiTraceEvent
 {
 public:
-    ApiTraceFrame(ApiTrace *parent);
+    ApiTraceFrame(ApiTrace *parent=0);
     int number;
 
     bool isEmpty() const;
 
+    void setParentTrace(ApiTrace *parent);
     ApiTrace *parentTrace() const;
 
     void setNumChildren(int num);
index 5860cf9530e4d66310d6497db52454b7f9f085fc..800b5c7457d03781e1f9d25726335922c0dbf9fd 100644 (file)
@@ -1,7 +1,7 @@
 #include "apitracemodel.h"
 
 #include "apitracecall.h"
-#include "loaderthread.h"
+#include "traceloader.h"
 #include "trace_parser.hpp"
 
 #include <QDebug>
index 591c557e55567eda81a93c1341eadf7cc727aa7a..e5f6d9b2a4b7852a71d375fac33055940e6cbf8c 100644 (file)
@@ -647,7 +647,7 @@ void MainWindow::initObjects()
     m_ui.callView->setContextMenuPolicy(Qt::CustomContextMenu);
 
     m_progressBar = new QProgressBar();
-    m_progressBar->setRange(0, 0);
+    m_progressBar->setRange(0, 100);
     statusBar()->addPermanentWidget(m_progressBar);
     m_progressBar->hide();
 
@@ -682,6 +682,8 @@ void MainWindow::initConnections()
 {
     connect(m_trace, SIGNAL(startedLoadingTrace()),
             this, SLOT(startedLoadingTrace()));
+    connect(m_trace, SIGNAL(loaded(int)),
+            this, SLOT(loadProgess(int)));
     connect(m_trace, SIGNAL(finishedLoadingTrace()),
             this, SLOT(finishedLoadingTrace()));
     connect(m_trace, SIGNAL(startedSaving()),
@@ -1159,4 +1161,9 @@ void MainWindow::saveSelectedSurface()
     statusBar()->showMessage( tr("Saved '%1'").arg(fileName), 5000);
 }
 
+void MainWindow::loadProgess(int percent)
+{
+    m_progressBar->setValue(percent);
+}
+
 #include "mainwindow.moc"
index f3e31811717f4a218f60860df2f5e203534125cd..00fe04b25ce698322e9294eee5e427e2f8f0ed1e 100644 (file)
@@ -46,6 +46,7 @@ private slots:
     void replayStateFound(ApiTraceState *state);
     void replayError(const QString &msg);
     void startedLoadingTrace();
+    void loadProgess(int percent);
     void finishedLoadingTrace();
     void lookupState();
     void showSettings();
index 40609adef6ef2ca6d83f2deba811b40f467c061f..0303ee72efd55f631127d3da49b2575cb3b2bb1b 100644 (file)
@@ -8,18 +8,18 @@
 static ApiTraceCall *
 apiCallFromTraceCall(const Trace::Call *call,
                      const QHash<QString, QUrl> &helpHash,
-                     ApiTraceFrame *frame)
+                     ApiTraceFrame *frame,
+                     TraceLoader *loader)
 {
-    ApiTraceCall *apiCall = new ApiTraceCall(frame, call);
+    ApiTraceCall *apiCall = new ApiTraceCall(frame, loader, call);
 
     apiCall->setHelpUrl(helpHash.value(apiCall->name()));
 
     return apiCall;
 }
 
-TraceLoader::TraceLoader(ApiTrace *parent)
+TraceLoader::TraceLoader(QObject *parent)
     : QObject(parent),
-      m_trace(parent),
       m_frameMarker(ApiTrace::FrameMarker_SwapBuffers)
 {
 }
@@ -39,9 +39,10 @@ void TraceLoader::loadTrace(const QString &filename)
         qDebug() << "error: failed to open " << filename;
         return;
     }
-
+    qDebug()<<"load trace with "<<filename;
     emit startedParsing();
 
+    qDebug() <<"\t support offsets = "<<m_parser.supportsOffsets();
     if (m_parser.supportsOffsets()) {
        scanTrace();
     } else {
@@ -166,7 +167,7 @@ void TraceLoader::scanTrace()
            frameOffset.numberOfCalls = numOfCalls;
            frameOffset.callNumber = callNum;
 
-           currentFrame = new ApiTraceFrame(m_trace);
+           currentFrame = new ApiTraceFrame();
            currentFrame->number = numOfFrames;
            currentFrame->setNumChildren(numOfCalls);
            frames.append(currentFrame);
@@ -192,7 +193,7 @@ void TraceLoader::scanTrace()
       frameOffset.numberOfCalls = numOfCalls;
       frameOffset.callNumber = callNum;
 
-      currentFrame = new ApiTraceFrame(m_trace);
+      currentFrame = new ApiTraceFrame();
       currentFrame->number = numOfFrames;
       currentFrame->setNumChildren(numOfCalls);
       frames.append(currentFrame);
@@ -220,12 +221,12 @@ void TraceLoader::parseTrace()
    while (call) {
       //std::cout << *call;
       if (!currentFrame) {
-         currentFrame = new ApiTraceFrame(m_trace);
+         currentFrame = new ApiTraceFrame();
          currentFrame->number = frameCount;
          ++frameCount;
       }
       ApiTraceCall *apiCall =
-            apiCallFromTraceCall(call, m_helpHash, currentFrame);
+            apiCallFromTraceCall(call, m_helpHash, currentFrame, this);
       calls.append(apiCall);
       if (apiCall->hasBinaryData()) {
          QByteArray data =
@@ -245,6 +246,7 @@ void TraceLoader::parseTrace()
             frames.clear();
          }
          if (m_parser.percentRead() - lastPercentReport >= 5) {
+            qDebug()<<"emitting = " << m_parser.percentRead();
             emit parsed(m_parser.percentRead());
             lastPercentReport = m_parser.percentRead();
          }
@@ -270,4 +272,34 @@ void TraceLoader::parseTrace()
 }
 
 
+ApiTraceCallSignature * TraceLoader::signature(unsigned id)
+{
+    if (id >= m_signatures.count()) {
+        m_signatures.resize(id + 1);
+        return NULL;
+    } else {
+        return m_signatures[id];
+    }
+}
+
+void TraceLoader::addSignature(unsigned id, ApiTraceCallSignature *signature)
+{
+    m_signatures[id] = signature;
+}
+
+ApiTraceEnumSignature * TraceLoader::enumSignature(unsigned id)
+{
+    if (id >= m_enumSignatures.count()) {
+        m_enumSignatures.resize(id + 1);
+        return NULL;
+    } else {
+        return m_enumSignatures[id];
+    }
+}
+
+void TraceLoader::addEnumSignature(unsigned id, ApiTraceEnumSignature *signature)
+{
+    m_enumSignatures[id] = signature;
+}
+
 #include "traceloader.moc"
index e9c4171026b2d4b82f20d97e1f9e56b6fb14ecab..32c7f1669e65883371a03de52ecec660610893cc 100644 (file)
@@ -14,9 +14,16 @@ class TraceLoader : public QObject
 {
     Q_OBJECT
 public:
-    TraceLoader(ApiTrace *parent);
+    TraceLoader(QObject *parent=0);
     ~TraceLoader();
 
+
+    ApiTraceCallSignature *signature(unsigned id);
+    void addSignature(unsigned id, ApiTraceCallSignature *signature);
+
+    ApiTraceEnumSignature *enumSignature(unsigned id);
+    void addEnumSignature(unsigned id, ApiTraceEnumSignature *signature);
+
 public slots:
     void loadTrace(const QString &filename);
     void loadFrame(int frameIdx);
@@ -24,7 +31,7 @@ public slots:
 
 signals:
     void startedParsing();
-    void parsed(float percent);
+    void parsed(int percent);
     void finishedParsing();
 
     void framesLoaded(const QList<ApiTraceFrame*> &frames);
@@ -53,8 +60,8 @@ private:
     void loadHelpFile();
     void scanTrace();
     void parseTrace();
+
 private:
-    ApiTrace *m_trace;
     Trace::Parser m_parser;
     QString m_fileName;
     ApiTrace::FrameMarker m_frameMarker;
@@ -63,6 +70,9 @@ private:
     FrameOffsets m_frameOffsets;
 
     QHash<QString, QUrl> m_helpHash;
+
+    QVector<ApiTraceCallSignature*> m_signatures;
+    QVector<ApiTraceEnumSignature*> m_enumSignatures;
 };
 
 #endif
index 517e2219cf70fdd8924d9844dca7a0e14aaf9036..45473b345ffa3a3cae447ccab1fe101e93f91514 100644 (file)
@@ -97,6 +97,12 @@ bool File::isSnappyCompressed(const std::string &filename)
     return (byte1 == SNAPPY_BYTE1 && byte2 == SNAPPY_BYTE2);
 }
 
+typedef struct gz_stream {
+    z_stream stream;
+    int      z_err;   /* error code for last stream operation */
+    int      z_eof;   /* set if end of input file */
+    FILE     *file;   /* .gz file */
+} gz_dummy_stream;
 
 ZLibFile::ZLibFile(const std::string &filename,
                    File::Mode mode)
@@ -115,8 +121,15 @@ bool ZLibFile::rawOpen(const std::string &filename, File::Mode mode)
                       (mode == File::Write) ? "wb" : "rb");
 
     if (mode == File::Read && m_gzFile) {
-        m_endOffset = gzseek(m_gzFile, 0, SEEK_END);
-        gzrewind(m_gzFile);
+        //XXX: unfortunately zlib doesn't support
+        //     SEEK_END or we could've done:
+        //m_endOffset = gzseek(m_gzFile, 0, SEEK_END);
+        //gzrewind(m_gzFile);
+        gz_dummy_stream *stream = (gz_dummy_stream *)m_gzFile;
+        long loc = ftell(stream->file);
+        fseek(stream->file,0,SEEK_END);
+        m_endOffset = ftell(stream->file);
+        fseek(stream->file, loc, SEEK_SET);
     }
 
     return m_gzFile != NULL;
@@ -163,5 +176,6 @@ bool ZLibFile::rawSkip(size_t)
 
 int ZLibFile::rawPercentRead()
 {
-    return 100 * (gztell(m_gzFile) / m_endOffset);
+    gz_dummy_stream *stream = (gz_dummy_stream *)m_gzFile;
+    return 100 * (ftell(stream->file) / m_endOffset);
 }
index 95dbec50d8da620e972d49663066f1277ccc5d73..2ef77b6d79daf856636414358fd2c232afd414c6 100644 (file)
@@ -43,6 +43,7 @@ Parser::Parser() {
     file = NULL;
     next_call_no = 0;
     version = 0;
+    m_supportsSeeking = false;
 }
 
 
@@ -62,6 +63,7 @@ bool Parser::open(const char *filename) {
     if (!file->open(filename, File::Read)) {
         return false;
     }
+    m_supportsSeeking = file->supportsOffsets();
 
     version = read_uint();
     if (version > TRACE_VERSION) {
@@ -146,8 +148,15 @@ void Parser::parse_enter(void) {
     size_t id = read_uint();
 
     FunctionSig *sig = lookup(functions, id);
-    const File::Offset offset = file->currentOffset();
-    bool callWithSig = callWithSignature(offset);
+
+
+    File::Offset offset;
+    bool callWithSig = false;
+    if (m_supportsSeeking) {
+        offset = file->currentOffset();
+        callWithSig = callWithSignature(offset);
+    }
+
     if (!sig || callWithSig) {
         if (!sig) {
             sig = new FunctionSig;
@@ -160,7 +169,9 @@ void Parser::parse_enter(void) {
             }
             sig->arg_names = arg_names;
             functions[id] = sig;
-            m_callSigOffsets.insert(offset);
+            if (m_supportsSeeking) {
+                m_callSigOffsets.insert(offset);
+            }
         } else {
             /* skip over the signature */
             skip_string(); /* name */
@@ -336,8 +347,14 @@ Value *Parser::parse_string() {
 Value *Parser::parse_enum() {
     size_t id = read_uint();
     EnumSig *sig = lookup(enums, id);
-    const File::Offset offset = file->currentOffset();
-    bool enumWithSig = enumWithSignature(offset);
+    File::Offset offset;
+    bool enumWithSig = false;
+
+    if (m_supportsSeeking) {
+        offset = file->currentOffset();
+        enumWithSig = enumWithSignature(offset);
+    }
+
     if (!sig || enumWithSig) {
         if (!sig) {
             sig = new EnumSig;
@@ -347,7 +364,9 @@ Value *Parser::parse_enum() {
             sig->value = value->toSInt();
             delete value;
             enums[id] = sig;
-            m_enumSigOffsets.insert(offset);
+            if (m_supportsSeeking) {
+                m_enumSigOffsets.insert(offset);
+            }
         } else {
             skip_string(); /*name*/
             scan_value();
@@ -361,8 +380,14 @@ Value *Parser::parse_enum() {
 Value *Parser::parse_bitmask() {
     size_t id = read_uint();
     BitmaskSig *sig = lookup(bitmasks, id);
-    const File::Offset offset = file->currentOffset();
-    bool bitmaskWithSig = bitmaskWithSignature(offset);
+    File::Offset offset;
+    bool bitmaskWithSig = false;
+
+    if (m_supportsSeeking) {
+        offset = file->currentOffset();
+        bitmaskWithSig = bitmaskWithSignature(offset);
+    }
+
     if (!sig || bitmaskWithSig) {
         if (!sig) {
             sig = new BitmaskSig;
@@ -378,7 +403,9 @@ Value *Parser::parse_bitmask() {
             }
             sig->flags = flags;
             bitmasks[id] = sig;
-            m_bitmaskSigOffsets.insert(offset);
+            if (m_supportsSeeking) {
+                m_bitmaskSigOffsets.insert(offset);
+            }
         } else {
             int num_flags = read_uint();
             for (int i = 0; i < num_flags; ++i) {
@@ -419,8 +446,14 @@ Value *Parser::parse_struct() {
     size_t id = read_uint();
 
     StructSig *sig = lookup(structs, id);
-    const File::Offset offset = file->currentOffset();
-    bool structWithSig = structWithSignature(offset);
+    File::Offset offset;
+    bool structWithSig = false;
+
+    if (m_supportsSeeking) {
+        offset = file->currentOffset();
+        structWithSig = structWithSignature(offset);
+    }
+
     if (!sig || structWithSig) {
         if (!sig) {
             sig = new StructSig;
@@ -433,7 +466,9 @@ Value *Parser::parse_struct() {
             }
             sig->member_names = member_names;
             structs[id] = sig;
-            m_structSigOffsets.insert(offset);
+            if (m_supportsSeeking) {
+                m_structSigOffsets.insert(offset);
+            }
         } else {
             skip_string(); /* name */
             unsigned num_members = read_uint();
@@ -528,6 +563,7 @@ inline bool Parser::bitmaskWithSignature(const File::Offset &offset) const
 
 Call * Parser::scan_call()
 {
+    assert(m_supportsSeeking);
     do {
         int c = read_byte();
         switch(c) {
index f50cf9aebe94c3e8b79cb06c83a7b196feb180c7..15b0ccb9b03f0964b5ce1c5418488e23bfb5afe7 100644 (file)
@@ -67,6 +67,8 @@ protected:
     typedef std::map<File::Offset, unsigned> CallNumOffsets;
     CallNumOffsets m_callNumOffsets;
 
+    bool m_supportsSeeking;
+
     unsigned next_call_no;
 
 public: