]> git.cworth.org Git - apitrace/blob - trace_file.hpp
Implement ZlibFile::currentOffset.
[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(uint64_t _chunk = 0, uint32_t _offsetInChunk = 0)
44             : chunk(_chunk),
45               offsetInChunk(_offsetInChunk)
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() = 0;
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     virtual File::Offset currentOffset();
182 protected:
183     virtual bool rawOpen(const std::string &filename, File::Mode mode);
184     virtual bool rawWrite(const void *buffer, size_t length);
185     virtual bool rawRead(void *buffer, size_t length);
186     virtual int rawGetc();
187     virtual void rawClose();
188     virtual void rawFlush();
189     virtual bool rawSkip(size_t length);
190     virtual int  rawPercentRead();
191 private:
192     void *m_gzFile;
193     double m_endOffset;
194 };
195
196 inline bool
197 operator<(const File::Offset &one, const File::Offset &two)
198 {
199     return one.chunk < two.chunk ||
200             (one.chunk == two.chunk && one.offsetInChunk < two.offsetInChunk);
201 }
202
203 inline bool
204 operator==(const File::Offset &one, const File::Offset &two)
205 {
206     return one.chunk == two.chunk &&
207             one.offsetInChunk == two.offsetInChunk;
208 }
209
210 inline bool
211 operator>=(const File::Offset &one, const File::Offset &two)
212 {
213     return one.chunk > two.chunk ||
214             (one.chunk == two.chunk && one.offsetInChunk >= two.offsetInChunk);
215 }
216
217 inline bool
218 operator>(const File::Offset &one, const File::Offset &two)
219 {
220     return two < one;
221 }
222
223 inline bool
224 operator<=(const File::Offset &one, const File::Offset &two)
225 {
226     return two >= one;
227 }
228
229
230 }
231
232 #endif