]> git.cworth.org Git - apitrace/blob - trace_file.hpp
Merge remote-tracking branch 'origin/master' into on-demand-loading
[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(unsigned length);
71
72     virtual bool supportsOffsets() const = 0;
73     virtual File::Offset currentOffset();
74     virtual void setCurrentOffset(const File::Offset &offset);
75 protected:
76     virtual bool rawOpen(const std::string &filename, File::Mode mode) = 0;
77     virtual bool rawWrite(const void *buffer, size_t length) = 0;
78     virtual bool rawRead(void *buffer, size_t length) = 0;
79     virtual int rawGetc() = 0;
80     virtual void rawClose() = 0;
81     virtual void rawFlush() = 0;
82     virtual bool rawSkip(unsigned length) = 0;
83
84 protected:
85     std::string m_filename;
86     File::Mode m_mode;
87     bool m_isOpened;
88 };
89
90 inline bool File::isOpened() const
91 {
92     return m_isOpened;
93 }
94
95 inline File::Mode File::mode() const
96 {
97     return m_mode;
98 }
99
100 inline std::string File::filename() const
101 {
102     return m_filename;
103 }
104
105 inline bool File::open(const std::string &filename, File::Mode mode)
106 {
107     if (m_isOpened) {
108         close();
109     }
110     m_isOpened = rawOpen(filename, mode);
111     m_mode = mode;
112
113     return m_isOpened;
114 }
115
116 inline bool File::write(const void *buffer, size_t length)
117 {
118     if (!m_isOpened || m_mode != File::Write) {
119         return false;
120     }
121     return rawWrite(buffer, length);
122 }
123
124 inline bool File::read(void *buffer, size_t length)
125 {
126     if (!m_isOpened || m_mode != File::Read) {
127         return false;
128     }
129     return rawRead(buffer, length);
130 }
131
132 inline void File::close()
133 {
134     if (m_isOpened) {
135         rawClose();
136         m_isOpened = false;
137     }
138 }
139
140 inline void File::flush(void)
141 {
142     rawFlush();
143 }
144
145 inline int File::getc()
146 {
147     if (!m_isOpened || m_mode != File::Read) {
148         return -1;
149     }
150     return rawGetc();
151 }
152
153 inline bool File::skip(unsigned length)
154 {
155     if (!m_isOpened || m_mode != File::Read) {
156         return false;
157     }
158     return rawSkip(length);
159 }
160
161 class ZLibFile : public File {
162 public:
163     ZLibFile(const std::string &filename = std::string(),
164              File::Mode mode = File::Read);
165     virtual ~ZLibFile();
166
167
168     virtual bool supportsOffsets() const;
169 protected:
170     virtual bool rawOpen(const std::string &filename, File::Mode mode);
171     virtual bool rawWrite(const void *buffer, size_t length);
172     virtual bool rawRead(void *buffer, size_t length);
173     virtual int rawGetc();
174     virtual void rawClose();
175     virtual void rawFlush();
176     virtual bool rawSkip(unsigned length);
177 private:
178     void *m_gzFile;
179 };
180
181 inline bool
182 operator<(const File::Offset &one, const File::Offset &two)
183 {
184     return one.chunk < two.chunk ||
185             (one.chunk == two.chunk && one.offsetInChunk < two.offsetInChunk);
186 }
187
188 inline bool
189 operator==(const File::Offset &one, const File::Offset &two)
190 {
191     return one.chunk == two.chunk &&
192             one.offsetInChunk == two.offsetInChunk;
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 two < one;
206 }
207
208 inline bool
209 operator<=(const File::Offset &one, const File::Offset &two)
210 {
211     return two >= one;
212 }
213
214
215 }
216
217 #endif