]> git.cworth.org Git - apitrace/blobdiff - trace_file.cpp
Make sure that the traces are always complete.
[apitrace] / trace_file.cpp
index 0272a5c29767bacb76fed998613113b56b2a6424..421120fc4ce568663d1383a9cd8330da085f000c 100644 (file)
@@ -6,10 +6,62 @@
 #include <zlib.h>
 #include <snappy.h>
 
+#include "os.hpp"
+
 #include <iostream>
+#include <set>
 
 using namespace Trace;
 
+#define SNAPPY_BYTE1 'a'
+#define SNAPPY_BYTE2 't'
+
+static void cleanupHandler(int sig);
+
+class FileCleanup
+{
+public:
+    FileCleanup()
+        : m_quitOnFlush(false)
+    {
+        OS::CatchInterrupts(cleanupHandler);
+    }
+
+    ~FileCleanup()
+    {
+    }
+
+    void addFile(Trace::File *file)
+    {
+        m_files.insert(file);
+    }
+    void removeFile(Trace::File *file)
+    {
+        m_files.erase(file);
+        if (m_files.empty() && m_quitOnFlush) {
+            OS::Abort();
+        }
+    }
+
+    void setQuitOnFlush(bool quit) {
+        m_quitOnFlush = quit;
+    }
+    bool quitOnFlush() const
+    {
+        return m_quitOnFlush;
+    }
+
+private:
+    std::set<Trace::File*> m_files;
+    bool m_quitOnFlush;
+};
+static FileCleanup s_cleaner;
+
+static void cleanupHandler(int sig)
+{
+    s_cleaner.setQuitOnFlush(true);
+}
+
 File::File(const std::string &filename,
            File::Mode mode)
     : m_filename(filename),
@@ -49,6 +101,10 @@ bool File::open(const std::string &filename, File::Mode mode)
     }
     m_isOpened = rawOpen(filename, mode);
     m_mode = mode;
+
+    if (m_isOpened) {
+        s_cleaner.addFile(this);
+    }
     return m_isOpened;
 }
 
@@ -73,12 +129,16 @@ void File::close()
     if (m_isOpened) {
         rawClose();
         m_isOpened = false;
+        s_cleaner.removeFile(this);
     }
 }
 
 void File::flush()
 {
     rawFlush();
+    if (s_cleaner.quitOnFlush()) {
+        close();
+    }
 }
 
 int File::getc()
@@ -89,6 +149,38 @@ int File::getc()
     return rawGetc();
 }
 
+bool File::isZLibCompressed(const std::string &filename)
+{
+    std::fstream stream(filename.c_str(),
+                        std::fstream::binary | std::fstream::in);
+    if (!stream.is_open())
+        return false;
+
+    unsigned char byte1, byte2;
+    stream >> byte1;
+    stream >> byte2;
+    stream.close();
+
+    return (byte1 == 0x1f && byte2 == 0x8b);
+}
+
+
+bool File::isSnappyCompressed(const std::string &filename)
+{
+    std::fstream stream(filename.c_str(),
+                        std::fstream::binary | std::fstream::in);
+    if (!stream.is_open())
+        return false;
+
+    unsigned char byte1, byte2;
+    stream >> byte1;
+    stream >> byte2;
+    stream.close();
+
+    return (byte1 == SNAPPY_BYTE1 && byte2 == SNAPPY_BYTE2);
+}
+
+
 ZLibFile::ZLibFile(const std::string &filename,
                    File::Mode mode)
     : File(filename, mode),
@@ -164,7 +256,17 @@ bool SnappyFile::rawOpen(const std::string &filename, File::Mode mode)
 
     //read in the initial buffer if we're reading
     if (m_stream.is_open() && mode == File::Read) {
+        // read the snappy file identifier
+        unsigned char byte1, byte2;
+        m_stream >> byte1;
+        m_stream >> byte2;
+        assert(byte1 == SNAPPY_BYTE1 && byte2 == SNAPPY_BYTE2);
+
         flushCache();
+    } else if (m_stream.is_open() && mode == File::Write) {
+        // write the snappy file identifier
+        m_stream << SNAPPY_BYTE1;
+        m_stream << SNAPPY_BYTE2;
     }
     return m_stream.is_open();
 }