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