1 #include "trace_file.hpp"
14 using namespace Trace;
16 #define SNAPPY_BYTE1 'a'
17 #define SNAPPY_BYTE2 't'
19 static void cleanupHandler(int sig);
25 : m_quitOnFlush(false)
27 OS::CatchInterrupts(cleanupHandler);
34 void addFile(Trace::File *file)
38 void removeFile(Trace::File *file)
41 if (m_files.empty() && m_quitOnFlush) {
46 void setQuitOnFlush(bool quit) {
49 bool quitOnFlush() const
55 std::set<Trace::File*> m_files;
58 static FileCleanup s_cleaner;
60 static void cleanupHandler(int sig)
62 s_cleaner.setQuitOnFlush(true);
65 File::File(const std::string &filename,
67 : m_filename(filename),
71 if (!m_filename.empty()) {
72 open(m_filename, m_mode);
82 bool File::isOpened() const
87 File::Mode File::mode() const
92 std::string File::filename() const
97 bool File::open(const std::string &filename, File::Mode mode)
102 m_isOpened = rawOpen(filename, mode);
106 s_cleaner.addFile(this);
111 bool File::write(const void *buffer, int length)
113 if (!m_isOpened || m_mode != File::Write) {
116 return rawWrite(buffer, length);
119 bool File::read(void *buffer, int length)
121 if (!m_isOpened || m_mode != File::Read) {
124 return rawRead(buffer, length);
132 s_cleaner.removeFile(this);
139 if (s_cleaner.quitOnFlush()) {
146 if (!m_isOpened || m_mode != File::Read) {
152 bool File::isZLibCompressed(const std::string &filename)
154 std::fstream stream(filename.c_str(),
155 std::fstream::binary | std::fstream::in);
156 if (!stream.is_open())
159 unsigned char byte1, byte2;
164 return (byte1 == 0x1f && byte2 == 0x8b);
168 bool File::isSnappyCompressed(const std::string &filename)
170 std::fstream stream(filename.c_str(),
171 std::fstream::binary | std::fstream::in);
172 if (!stream.is_open())
175 unsigned char byte1, byte2;
180 return (byte1 == SNAPPY_BYTE1 && byte2 == SNAPPY_BYTE2);
184 ZLibFile::ZLibFile(const std::string &filename,
186 : File(filename, mode),
191 ZLibFile::~ZLibFile()
195 bool ZLibFile::rawOpen(const std::string &filename, File::Mode mode)
197 m_gzFile = gzopen(filename.c_str(),
198 (mode == File::Write) ? "wb" : "rb");
199 return m_gzFile != NULL;
202 bool ZLibFile::rawWrite(const void *buffer, int length)
204 return gzwrite(m_gzFile, buffer, length) != -1;
207 bool ZLibFile::rawRead(void *buffer, int length)
209 return gzread(m_gzFile, buffer, length) != -1;
212 int ZLibFile::rawGetc()
214 return gzgetc(m_gzFile);
217 void ZLibFile::rawClose()
225 void ZLibFile::rawFlush()
227 gzflush(m_gzFile, Z_SYNC_FLUSH);
230 SnappyFile::SnappyFile(const std::string &filename,
237 m_compressedCache = new char[SNAPPY_CHUNK_SIZE];
240 SnappyFile::~SnappyFile()
242 delete [] m_compressedCache;
245 bool SnappyFile::rawOpen(const std::string &filename, File::Mode mode)
247 std::ios_base::openmode fmode = std::fstream::binary;
248 if (mode == File::Write) {
249 fmode |= (std::fstream::out | std::fstream::trunc);
250 createCache(SNAPPY_CHUNK_SIZE);
251 } else if (mode == File::Read) {
252 fmode |= std::fstream::in;
255 m_stream.open(filename.c_str(), fmode);
257 //read in the initial buffer if we're reading
258 if (m_stream.is_open() && mode == File::Read) {
259 // read the snappy file identifier
260 unsigned char byte1, byte2;
263 assert(byte1 == SNAPPY_BYTE1 && byte2 == SNAPPY_BYTE2);
266 } else if (m_stream.is_open() && mode == File::Write) {
267 // write the snappy file identifier
268 m_stream << SNAPPY_BYTE1;
269 m_stream << SNAPPY_BYTE2;
271 return m_stream.is_open();
274 bool SnappyFile::rawWrite(const void *buffer, int length)
276 if (freeCacheSize() > length) {
277 memcpy(m_cachePtr, buffer, length);
278 m_cachePtr += length;
279 } else if (freeCacheSize() == length) {
280 memcpy(m_cachePtr, buffer, length);
281 m_cachePtr += length;
284 int sizeToWrite = length;
286 while (sizeToWrite >= freeCacheSize()) {
287 int endSize = freeCacheSize();
288 int offset = length - sizeToWrite;
289 memcpy(m_cachePtr, (char*)buffer + offset, endSize);
290 sizeToWrite -= endSize;
291 m_cachePtr += endSize;
295 int offset = length - sizeToWrite;
296 memcpy(m_cachePtr, (char*)buffer + offset, sizeToWrite);
297 m_cachePtr += sizeToWrite;
304 bool SnappyFile::rawRead(void *buffer, int length)
306 if (m_stream.eof()) {
309 if (freeCacheSize() > length) {
310 memcpy(buffer, m_cachePtr, length);
311 m_cachePtr += length;
312 } else if (freeCacheSize() == length) {
313 memcpy(buffer, m_cachePtr, length);
314 m_cachePtr += length;
317 int sizeToRead = length;
320 int chunkSize = std::min(freeCacheSize(), sizeToRead);
321 offset = length - sizeToRead;
322 memcpy((char*)buffer + offset, m_cachePtr, chunkSize);
323 m_cachePtr += chunkSize;
324 sizeToRead -= chunkSize;
333 int SnappyFile::rawGetc()
341 void SnappyFile::rawClose()
350 void SnappyFile::rawFlush()
355 void SnappyFile::flushCache()
357 if (m_mode == File::Write) {
358 size_t compressedLength;
360 ::snappy::RawCompress(m_cache, SNAPPY_CHUNK_SIZE - freeCacheSize(),
361 m_compressedCache, &compressedLength);
363 m_stream << compressedLength;
364 m_stream.write(m_compressedCache, compressedLength);
365 m_cachePtr = m_cache;
366 } else if (m_mode == File::Read) {
369 //assert(m_cachePtr == m_cache + m_cacheSize);
370 size_t compressedLength;
371 m_stream >> compressedLength;
372 m_stream.read((char*)m_compressedCache, compressedLength);
373 ::snappy::GetUncompressedLength(m_compressedCache, compressedLength,
377 createCache(m_cacheSize);
378 ::snappy::RawUncompress(m_compressedCache, compressedLength,
383 void SnappyFile::createCache(size_t size)
385 m_cache = new char[size];
386 m_cachePtr = m_cache;