]> git.cworth.org Git - apitrace/blob - trace_file.cpp
Ok, when != -1
[apitrace] / trace_file.cpp
1 #include "trace_file.hpp"
2
3 #include <assert.h>
4 #include <string.h>
5
6 #include <zlib.h>
7 #include <snappy.h>
8
9 #include <iostream>
10
11 using namespace Trace;
12
13 File::File(const std::string &filename,
14            File::Mode mode)
15     : m_filename(filename),
16       m_mode(mode),
17       m_isOpened(false)
18 {
19     if (!m_filename.empty()) {
20         open(m_filename, m_mode);
21     }
22 }
23
24 static size_t writtenRef = 0;
25
26 File::~File()
27 {
28     std::cerr << "written ref = "<<writtenRef << std::endl;
29     close();
30 }
31
32 bool File::isOpened() const
33 {
34     return m_isOpened;
35 }
36
37 File::Mode File::mode() const
38 {
39     return m_mode;
40 }
41
42 std::string File::filename() const
43 {
44     return m_filename;
45 }
46
47 bool File::open(const std::string &filename, File::Mode mode)
48 {
49     if (m_isOpened) {
50         close();
51     }
52     m_isOpened = rawOpen(filename, mode);
53     m_mode = mode;
54     return m_isOpened;
55 }
56
57 bool File::write(const void *buffer, int length)
58 {
59     if (!m_isOpened || m_mode != File::Write) {
60         return false;
61     }
62     writtenRef += length;
63     return rawWrite(buffer, length);
64 }
65
66 bool File::read(void *buffer, int length)
67 {
68     if (!m_isOpened || m_mode != File::Read) {
69         return false;
70     }
71     return rawRead(buffer, length);
72 }
73
74 void File::close()
75 {
76     if (m_isOpened) {
77         rawClose();
78         m_isOpened = false;
79     }
80 }
81
82 void File::flush()
83 {
84     rawFlush();
85 }
86
87 char File::getc()
88 {
89     if (!m_isOpened || m_mode != File::Read) {
90         return 0;
91     }
92     return rawGetc();
93 }
94
95 ZLibFile::ZLibFile(const std::string &filename,
96                    File::Mode mode)
97     : File(filename, mode),
98       m_gzFile(NULL)
99 {
100 }
101
102 ZLibFile::~ZLibFile()
103 {
104 }
105
106 bool ZLibFile::rawOpen(const std::string &filename, File::Mode mode)
107 {
108     m_gzFile = gzopen(filename.c_str(),
109                       (mode == File::Write) ? "wb" : "rb");
110     return m_gzFile != NULL;
111 }
112
113 bool ZLibFile::rawWrite(const void *buffer, int length)
114 {
115     return gzwrite(m_gzFile, buffer, length) != -1;
116 }
117
118 bool ZLibFile::rawRead(void *buffer, int length)
119 {
120     return gzread(m_gzFile, buffer, length) != -1;
121 }
122
123 char ZLibFile::rawGetc()
124 {
125     return gzgetc(m_gzFile);
126 }
127
128 void ZLibFile::rawClose()
129 {
130     if (m_gzFile) {
131         gzclose(m_gzFile);
132         m_gzFile = NULL;
133     }
134 }
135
136 void ZLibFile::rawFlush()
137 {
138     gzflush(m_gzFile, Z_SYNC_FLUSH);
139 }
140
141 SnappyFile::SnappyFile(const std::string &filename,
142                               File::Mode mode)
143     : File(),
144       m_cache(0),
145       m_cachePtr(0),
146       m_cacheSize(0)
147 {
148     m_compressedCache = new char[SNAPPY_CHUNK_SIZE];
149 }
150
151 SnappyFile::~SnappyFile()
152 {
153     delete [] m_compressedCache;
154 }
155
156 static size_t written = 0;
157 static size_t writtenComp = 0;
158
159 bool SnappyFile::rawOpen(const std::string &filename, File::Mode mode)
160 {
161     std::ios_base::openmode fmode = std::fstream::binary;
162     if (mode == File::Write) {
163         fmode |= (std::fstream::out | std::fstream::trunc);
164         createCache(SNAPPY_CHUNK_SIZE);
165     } else if (mode == File::Read) {
166         fmode |= std::fstream::in;
167     }
168
169     m_stream.open(filename.c_str(), fmode);
170
171     //read in the initial buffer if we're reading
172     if (m_stream.is_open() && mode == File::Read) {
173         flushCache();
174     }
175     return m_stream.is_open();
176 }
177
178 bool SnappyFile::rawWrite(const void *buffer, int length)
179 {
180     static int bufWritten = 0;
181     if (bufWritten < 500) {
182         const char *cbuffer = (const char*)buffer;
183         for (int i = 0; i < length; ++i) {
184             std::cerr << "--- "<<bufWritten << ") "<< (int) cbuffer[i]
185                       << std::endl;
186             ++ bufWritten;
187         }
188     }
189     if (freeCacheSize() > length) {
190         memcpy(m_cachePtr, buffer, length);
191         m_cachePtr += length;
192     } else if (freeCacheSize() == length) {
193         memcpy(m_cachePtr, buffer, length);
194         m_cachePtr += length;
195         flushCache();
196     } else {
197         int sizeToWrite = length;
198
199         while (sizeToWrite >= freeCacheSize()) {
200             int endSize = freeCacheSize();
201             int offset = length - sizeToWrite;
202             memcpy(m_cachePtr, (char*)buffer + offset, endSize);
203             sizeToWrite -= endSize;
204             m_cachePtr += endSize;
205             flushCache();
206         }
207         if (sizeToWrite) {
208             int offset = length - sizeToWrite;
209             memcpy(m_cachePtr, (char*)buffer + offset, sizeToWrite);
210             m_cachePtr += sizeToWrite;
211         }
212     }
213
214     return true;
215 }
216
217 bool SnappyFile::rawRead(void *buffer, int length)
218 {
219     std::cerr << "Reading byte = "<< (m_cachePtr - m_cache) << std::endl;
220     if (freeCacheSize() > length) {
221         memcpy(buffer, m_cachePtr, length);
222         m_cachePtr += length;
223     } else if (freeCacheSize() == length) {
224         memcpy(buffer, m_cachePtr, length);
225         m_cachePtr += length;
226         assert(0);
227         flushCache();
228     } else {
229         int sizeToRead = length;
230         int offset = 0;
231         assert(0);
232         while (sizeToRead) {
233             int chunkSize = std::min(freeCacheSize(), sizeToRead);
234             offset = length - sizeToRead;
235             memcpy((char*)buffer + offset, m_cachePtr, chunkSize);
236             m_cachePtr += chunkSize;
237             sizeToRead -= chunkSize;
238             if (sizeToRead > 0)
239                 flushCache();
240         }
241     }
242
243     return true;
244 }
245
246 char SnappyFile::rawGetc()
247 {
248     char c;
249     rawRead(&c, 1);
250     return c;
251 }
252
253 void SnappyFile::rawClose()
254 {
255     flushCache();
256     std::cerr << "written = "<< written
257               <<", comp = "<< writtenComp
258               << std::endl;
259     m_stream.close();
260     delete [] m_cache;
261     m_cache = NULL;
262     m_cachePtr = NULL;
263 }
264
265 void SnappyFile::rawFlush()
266 {
267     m_stream.flush();
268 }
269
270 void SnappyFile::flushCache()
271 {
272     if (m_mode == File::Write) {
273         size_t compressedLength;
274
275         static bool first = true;
276         if (first) {
277             std::cerr << "Buffer = [";
278             for (int i = 0; i < 512; ++i) {
279                 std::cerr << i << " ) "<< (int)m_cache[i] << std::endl;
280             }
281             std::cerr << "]"<<std::endl;
282             first = false;
283         }
284
285         ::snappy::RawCompress(m_cache, SNAPPY_CHUNK_SIZE - freeCacheSize(),
286                               m_compressedCache, &compressedLength);
287
288         m_stream << compressedLength;
289         m_stream.write(m_compressedCache, compressedLength);
290         std::cerr << "compressed length = "<<compressedLength
291                   <<" cache size = "<<(SNAPPY_CHUNK_SIZE - freeCacheSize())
292                   <<" (ref = " << SNAPPY_CHUNK_SIZE <<")"
293                   << std::endl;
294         written += SNAPPY_CHUNK_SIZE - freeCacheSize();
295         writtenComp += compressedLength;
296         m_cachePtr = m_cache;
297     } else if (m_mode == File::Read) {
298         if (m_stream.eof())
299             return;
300         //assert(m_cachePtr == m_cache + m_cacheSize);
301         size_t compressedLength;
302         m_stream >> compressedLength;
303         m_stream.read((char*)m_compressedCache, compressedLength);
304         ::snappy::GetUncompressedLength(m_compressedCache, compressedLength,
305                                         &m_cacheSize);
306         std::cerr << "compressed length = "<<compressedLength
307                   <<" cache size = "<<m_cacheSize
308                   <<" (ref = " << SNAPPY_CHUNK_SIZE <<")"
309                   << std::endl;
310         if (m_cache)
311             delete [] m_cache;
312         createCache(m_cacheSize);
313         ::snappy::RawUncompress(m_compressedCache, compressedLength,
314                                 m_cache);
315         static bool first = true;
316         if (first) {
317             std::cerr << "Buffer = [";
318             for (int i = 0; i < 512; ++i) {
319                 std::cerr << i << " ) "<< (int)m_cache[i] << std::endl;
320             }
321             std::cerr << "]"<<std::endl;
322             first = false;
323         }
324     }
325 }
326
327 void SnappyFile::createCache(size_t size)
328 {
329     m_cache = new char[size];
330     m_cachePtr = m_cache;
331     m_cacheSize = size;
332 }