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);
26 OS::CatchInterrupts(cleanupHandler);
35 void addFile(Trace::File *file)
39 void removeFile(Trace::File *file)
46 std::set<Trace::File*>::const_iterator itr;
47 for (itr = m_files.begin(); itr != m_files.end(); ++itr) {
48 (*itr)->flush(File::FlushDeep);
53 std::set<Trace::File*> m_files;
55 static FileCleanup s_cleaner;
57 static void cleanupHandler(int sig)
62 File::File(const std::string &filename,
64 : m_filename(filename),
68 if (!m_filename.empty()) {
69 open(m_filename, m_mode);
79 bool File::isOpened() const
84 File::Mode File::mode() const
89 std::string File::filename() const
94 bool File::open(const std::string &filename, File::Mode mode)
99 m_isOpened = rawOpen(filename, mode);
103 s_cleaner.addFile(this);
108 bool File::write(const void *buffer, int length)
110 if (!m_isOpened || m_mode != File::Write) {
113 return rawWrite(buffer, length);
116 bool File::read(void *buffer, int length)
118 if (!m_isOpened || m_mode != File::Read) {
121 return rawRead(buffer, length);
129 s_cleaner.removeFile(this);
133 void File::flush(FlushType type)
140 if (!m_isOpened || m_mode != File::Read) {
146 bool File::isZLibCompressed(const std::string &filename)
148 std::fstream stream(filename.c_str(),
149 std::fstream::binary | std::fstream::in);
150 if (!stream.is_open())
153 unsigned char byte1, byte2;
158 return (byte1 == 0x1f && byte2 == 0x8b);
162 bool File::isSnappyCompressed(const std::string &filename)
164 std::fstream stream(filename.c_str(),
165 std::fstream::binary | std::fstream::in);
166 if (!stream.is_open())
169 unsigned char byte1, byte2;
174 return (byte1 == SNAPPY_BYTE1 && byte2 == SNAPPY_BYTE2);
178 ZLibFile::ZLibFile(const std::string &filename,
180 : File(filename, mode),
185 ZLibFile::~ZLibFile()
189 bool ZLibFile::rawOpen(const std::string &filename, File::Mode mode)
191 m_gzFile = gzopen(filename.c_str(),
192 (mode == File::Write) ? "wb" : "rb");
193 return m_gzFile != NULL;
196 bool ZLibFile::rawWrite(const void *buffer, int length)
198 return gzwrite(m_gzFile, buffer, length) != -1;
201 bool ZLibFile::rawRead(void *buffer, int length)
203 return gzread(m_gzFile, buffer, length) != -1;
206 int ZLibFile::rawGetc()
208 return gzgetc(m_gzFile);
211 void ZLibFile::rawClose()
219 void ZLibFile::rawFlush(FlushType type)
221 gzflush(m_gzFile, Z_SYNC_FLUSH);
224 SnappyFile::SnappyFile(const std::string &filename,
231 m_compressedCache = new char[SNAPPY_CHUNK_SIZE];
234 SnappyFile::~SnappyFile()
236 delete [] m_compressedCache;
239 bool SnappyFile::rawOpen(const std::string &filename, File::Mode mode)
241 std::ios_base::openmode fmode = std::fstream::binary;
242 if (mode == File::Write) {
243 fmode |= (std::fstream::out | std::fstream::trunc);
244 createCache(SNAPPY_CHUNK_SIZE);
245 } else if (mode == File::Read) {
246 fmode |= std::fstream::in;
249 m_stream.open(filename.c_str(), fmode);
251 //read in the initial buffer if we're reading
252 if (m_stream.is_open() && mode == File::Read) {
253 // read the snappy file identifier
254 unsigned char byte1, byte2;
257 assert(byte1 == SNAPPY_BYTE1 && byte2 == SNAPPY_BYTE2);
260 } else if (m_stream.is_open() && mode == File::Write) {
261 // write the snappy file identifier
262 m_stream << SNAPPY_BYTE1;
263 m_stream << SNAPPY_BYTE2;
265 return m_stream.is_open();
268 bool SnappyFile::rawWrite(const void *buffer, int length)
270 if (freeCacheSize() > length) {
271 memcpy(m_cachePtr, buffer, length);
272 m_cachePtr += length;
273 } else if (freeCacheSize() == length) {
274 memcpy(m_cachePtr, buffer, length);
275 m_cachePtr += length;
278 int sizeToWrite = length;
280 while (sizeToWrite >= freeCacheSize()) {
281 int endSize = freeCacheSize();
282 int offset = length - sizeToWrite;
283 memcpy(m_cachePtr, (char*)buffer + offset, endSize);
284 sizeToWrite -= endSize;
285 m_cachePtr += endSize;
289 int offset = length - sizeToWrite;
290 memcpy(m_cachePtr, (char*)buffer + offset, sizeToWrite);
291 m_cachePtr += sizeToWrite;
298 bool SnappyFile::rawRead(void *buffer, int length)
300 if (m_stream.eof()) {
303 if (freeCacheSize() > length) {
304 memcpy(buffer, m_cachePtr, length);
305 m_cachePtr += length;
306 } else if (freeCacheSize() == length) {
307 memcpy(buffer, m_cachePtr, length);
308 m_cachePtr += length;
311 int sizeToRead = length;
314 int chunkSize = std::min(freeCacheSize(), sizeToRead);
315 offset = length - sizeToRead;
316 memcpy((char*)buffer + offset, m_cachePtr, chunkSize);
317 m_cachePtr += chunkSize;
318 sizeToRead -= chunkSize;
329 int SnappyFile::rawGetc()
337 void SnappyFile::rawClose()
346 void SnappyFile::rawFlush(FlushType type)
348 if (type == FlushDeep) {
354 void SnappyFile::flushCache()
356 if (m_mode == File::Write) {
357 size_t compressedLength;
359 ::snappy::RawCompress(m_cache, SNAPPY_CHUNK_SIZE - freeCacheSize(),
360 m_compressedCache, &compressedLength);
362 m_stream << compressedLength;
363 m_stream.write(m_compressedCache, compressedLength);
364 m_cachePtr = m_cache;
365 } else if (m_mode == File::Read) {
368 //assert(m_cachePtr == m_cache + m_cacheSize);
369 size_t compressedLength;
370 m_stream >> compressedLength;
371 m_stream.read((char*)m_compressedCache, compressedLength);
372 ::snappy::GetUncompressedLength(m_compressedCache, compressedLength,
376 createCache(m_cacheSize);
377 ::snappy::RawUncompress(m_compressedCache, compressedLength,
382 void SnappyFile::createCache(size_t size)
384 m_cache = new char[size];
385 m_cachePtr = m_cache;