]> git.cworth.org Git - apitrace/blob - trace_file.hpp
Load the last few calls.
[apitrace] / trace_file.hpp
1 /**************************************************************************
2  *
3  * Copyright 2011 Zack Rusin
4  * All Rights Reserved.
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to deal
8  * in the Software without restriction, including without limitation the rights
9  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10  * copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22  * THE SOFTWARE.
23  *
24  **************************************************************************/
25
26
27 #ifndef TRACE_FILE_HPP
28 #define TRACE_FILE_HPP
29
30 #include <string>
31 #include <fstream>
32 #include <stdint.h>
33
34 namespace Trace {
35
36 class File {
37 public:
38     enum Mode {
39         Read,
40         Write
41     };
42     struct Offset {
43         Offset()
44             : chunk(0),
45               offsetInChunk(0)
46         {}
47         uint64_t chunk;
48         uint32_t offsetInChunk;
49     };
50
51 public:
52     static bool isZLibCompressed(const std::string &filename);
53     static bool isSnappyCompressed(const std::string &filename);
54 public:
55     File(const std::string &filename = std::string(),
56          File::Mode mode = File::Read);
57     virtual ~File();
58
59     bool isOpened() const;
60     File::Mode mode() const;
61
62     std::string filename() const;
63
64     bool open(const std::string &filename, File::Mode mode);
65     bool write(const void *buffer, size_t length);
66     bool read(void *buffer, size_t length);
67     void close();
68     void flush(void);
69     int getc();
70     bool skip(size_t length);
71     int percentRead();
72
73     virtual bool supportsOffsets() const = 0;
74     virtual File::Offset currentOffset();
75     virtual void setCurrentOffset(const File::Offset &offset);
76 protected:
77     virtual bool rawOpen(const std::string &filename, File::Mode mode) = 0;
78     virtual bool rawWrite(const void *buffer, size_t length) = 0;
79     virtual bool rawRead(void *buffer, size_t length) = 0;
80     virtual int rawGetc() = 0;
81     virtual void rawClose() = 0;
82     virtual void rawFlush() = 0;
83     virtual bool rawSkip(size_t length) = 0;
84     virtual int rawPercentRead() = 0;
85
86 protected:
87     std::string m_filename;
88     File::Mode m_mode;
89     bool m_isOpened;
90 };
91
92 inline bool File::isOpened() const
93 {
94     return m_isOpened;
95 }
96
97 inline File::Mode File::mode() const
98 {
99     return m_mode;
100 }
101
102 inline std::string File::filename() const
103 {
104     return m_filename;
105 }
106
107 inline bool File::open(const std::string &filename, File::Mode mode)
108 {
109     if (m_isOpened) {
110         close();
111     }
112     m_isOpened = rawOpen(filename, mode);
113     m_mode = mode;
114
115     return m_isOpened;
116 }
117
118 inline bool File::write(const void *buffer, size_t length)
119 {
120     if (!m_isOpened || m_mode != File::Write) {
121         return false;
122     }
123     return rawWrite(buffer, length);
124 }
125
126 inline bool File::read(void *buffer, size_t length)
127 {
128     if (!m_isOpened || m_mode != File::Read) {
129         return false;
130     }
131     return rawRead(buffer, length);
132 }
133
134 inline int File::percentRead()
135 {
136     if (!m_isOpened || m_mode != File::Read) {
137         return 0;
138     }
139     return rawPercentRead();
140 }
141
142 inline void File::close()
143 {
144     if (m_isOpened) {
145         rawClose();
146         m_isOpened = false;
147     }
148 }
149
150 inline void File::flush(void)
151 {
152     if (m_mode == File::Write) {
153         rawFlush();
154     }
155 }
156
157 inline int File::getc()
158 {
159     if (!m_isOpened || m_mode != File::Read) {
160         return -1;
161     }
162     return rawGetc();
163 }
164
165 inline bool File::skip(size_t length)
166 {
167     if (!m_isOpened || m_mode != File::Read) {
168         return false;
169     }
170     return rawSkip(length);
171 }
172
173 class ZLibFile : public File {
174 public:
175     ZLibFile(const std::string &filename = std::string(),
176              File::Mode mode = File::Read);
177     virtual ~ZLibFile();
178
179
180     virtual bool supportsOffsets() const;
181 protected:
182     virtual bool rawOpen(const std::string &filename, File::Mode mode);
183     virtual bool rawWrite(const void *buffer, size_t length);
184     virtual bool rawRead(void *buffer, size_t length);
185     virtual int rawGetc();
186     virtual void rawClose();
187     virtual void rawFlush();
188     virtual bool rawSkip(size_t length);
189     virtual int  rawPercentRead();
190 private:
191     void *m_gzFile;
192     double m_endOffset;
193 };
194
195 inline bool
196 operator<(const File::Offset &one, const File::Offset &two)
197 {
198     return one.chunk < two.chunk ||
199             (one.chunk == two.chunk && one.offsetInChunk < two.offsetInChunk);
200 }
201
202 inline bool
203 operator==(const File::Offset &one, const File::Offset &two)
204 {
205     return one.chunk == two.chunk &&
206             one.offsetInChunk == two.offsetInChunk;
207 }
208
209 inline bool
210 operator>=(const File::Offset &one, const File::Offset &two)
211 {
212     return one.chunk > two.chunk ||
213             (one.chunk == two.chunk && one.offsetInChunk >= two.offsetInChunk);
214 }
215
216 inline bool
217 operator>(const File::Offset &one, const File::Offset &two)
218 {
219     return two < one;
220 }
221
222 inline bool
223 operator<=(const File::Offset &one, const File::Offset &two)
224 {
225     return two >= one;
226 }
227
228
229 }
230
231 #endif