#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),
}
}
-static size_t writtenRef = 0;
File::~File()
{
- std::cerr << "written ref = "<<writtenRef << std::endl;
close();
}
}
m_isOpened = rawOpen(filename, mode);
m_mode = mode;
+
+ if (m_isOpened) {
+ s_cleaner.addFile(this);
+ }
return m_isOpened;
}
if (!m_isOpened || m_mode != File::Write) {
return false;
}
- writtenRef += length;
return rawWrite(buffer, length);
}
if (m_isOpened) {
rawClose();
m_isOpened = false;
+ s_cleaner.removeFile(this);
}
}
void File::flush()
{
rawFlush();
+ if (s_cleaner.quitOnFlush()) {
+ close();
+ }
}
-char File::getc()
+int File::getc()
{
if (!m_isOpened || m_mode != File::Read) {
return 0;
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),
return gzread(m_gzFile, buffer, length) != -1;
}
-char ZLibFile::rawGetc()
+int ZLibFile::rawGetc()
{
return gzgetc(m_gzFile);
}
delete [] m_compressedCache;
}
-static size_t written = 0;
-static size_t writtenComp = 0;
-
bool SnappyFile::rawOpen(const std::string &filename, File::Mode mode)
{
std::ios_base::openmode fmode = std::fstream::binary;
//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();
}
bool SnappyFile::rawWrite(const void *buffer, int length)
{
- static int bufWritten = 0;
- if (bufWritten < 500) {
- const char *cbuffer = (const char*)buffer;
- for (int i = 0; i < length; ++i) {
- std::cerr << "--- "<<bufWritten << ") "<< (int) cbuffer[i]
- << std::endl;
- ++ bufWritten;
- }
- }
if (freeCacheSize() > length) {
memcpy(m_cachePtr, buffer, length);
m_cachePtr += length;
bool SnappyFile::rawRead(void *buffer, int length)
{
- std::cerr << "Reading byte = "<< (m_cachePtr - m_cache) << std::endl;
+ if (m_stream.eof()) {
+ return false;
+ }
if (freeCacheSize() > length) {
memcpy(buffer, m_cachePtr, length);
m_cachePtr += length;
} else if (freeCacheSize() == length) {
memcpy(buffer, m_cachePtr, length);
m_cachePtr += length;
- assert(0);
flushCache();
} else {
int sizeToRead = length;
int offset = 0;
- assert(0);
while (sizeToRead) {
int chunkSize = std::min(freeCacheSize(), sizeToRead);
offset = length - sizeToRead;
return true;
}
-char SnappyFile::rawGetc()
+int SnappyFile::rawGetc()
{
- char c;
- rawRead(&c, 1);
+ int c = 0;
+ if (!rawRead(&c, 1))
+ return -1;
return c;
}
void SnappyFile::rawClose()
{
flushCache();
- std::cerr << "written = "<< written
- <<", comp = "<< writtenComp
- << std::endl;
m_stream.close();
delete [] m_cache;
m_cache = NULL;
if (m_mode == File::Write) {
size_t compressedLength;
- static bool first = true;
- if (first) {
- std::cerr << "Buffer = [";
- for (int i = 0; i < 512; ++i) {
- std::cerr << i << " ) "<< (int)m_cache[i] << std::endl;
- }
- std::cerr << "]"<<std::endl;
- first = false;
- }
-
::snappy::RawCompress(m_cache, SNAPPY_CHUNK_SIZE - freeCacheSize(),
m_compressedCache, &compressedLength);
m_stream << compressedLength;
m_stream.write(m_compressedCache, compressedLength);
- std::cerr << "compressed length = "<<compressedLength
- <<" cache size = "<<(SNAPPY_CHUNK_SIZE - freeCacheSize())
- <<" (ref = " << SNAPPY_CHUNK_SIZE <<")"
- << std::endl;
- written += SNAPPY_CHUNK_SIZE - freeCacheSize();
- writtenComp += compressedLength;
m_cachePtr = m_cache;
} else if (m_mode == File::Read) {
if (m_stream.eof())
m_stream.read((char*)m_compressedCache, compressedLength);
::snappy::GetUncompressedLength(m_compressedCache, compressedLength,
&m_cacheSize);
- std::cerr << "compressed length = "<<compressedLength
- <<" cache size = "<<m_cacheSize
- <<" (ref = " << SNAPPY_CHUNK_SIZE <<")"
- << std::endl;
if (m_cache)
delete [] m_cache;
createCache(m_cacheSize);
::snappy::RawUncompress(m_compressedCache, compressedLength,
m_cache);
- static bool first = true;
- if (first) {
- std::cerr << "Buffer = [";
- for (int i = 0; i < 512; ++i) {
- std::cerr << i << " ) "<< (int)m_cache[i] << std::endl;
- }
- std::cerr << "]"<<std::endl;
- first = false;
- }
}
}