]> git.cworth.org Git - apitrace/blob - common/trace_file.hpp
Use skiplist-based FastCallSet within trace::CallSet
[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
35 #define SNAPPY_BYTE1 'a'
36 #define SNAPPY_BYTE2 't'
37
38
39 namespace trace {
40
41 class File {
42 public:
43     enum Mode {
44         Read,
45         Write
46     };
47     struct Offset {
48         Offset(uint64_t _chunk = 0, uint32_t _offsetInChunk = 0)
49             : chunk(_chunk),
50               offsetInChunk(_offsetInChunk)
51         {}
52         uint64_t chunk;
53         uint32_t offsetInChunk;
54     };
55
56 public:
57     static File *createZLib(void);
58     static File *createSnappy(void);
59     static File *createForRead(const char *filename);
60     static File *createForWrite(const char *filename);
61 public:
62     File(const std::string &filename = std::string(),
63          File::Mode mode = File::Read);
64     virtual ~File();
65
66     bool isOpened() const;
67     File::Mode mode() const;
68
69     bool open(const std::string &filename, File::Mode mode);
70     bool write(const void *buffer, size_t length);
71     size_t read(void *buffer, size_t length);
72     void close();
73     void flush(void);
74     int getc();
75     bool skip(size_t length);
76     int percentRead();
77
78     virtual bool supportsOffsets() const = 0;
79     virtual File::Offset currentOffset() = 0;
80     virtual void setCurrentOffset(const File::Offset &offset);
81 protected:
82     virtual bool rawOpen(const std::string &filename, File::Mode mode) = 0;
83     virtual bool rawWrite(const void *buffer, size_t length) = 0;
84     virtual size_t rawRead(void *buffer, size_t length) = 0;
85     virtual int rawGetc() = 0;
86     virtual void rawClose() = 0;
87     virtual void rawFlush() = 0;
88     virtual bool rawSkip(size_t length) = 0;
89     virtual int rawPercentRead() = 0;
90
91 protected:
92     File::Mode m_mode;
93     bool m_isOpened;
94 };
95
96 inline bool File::isOpened() const
97 {
98     return m_isOpened;
99 }
100
101 inline File::Mode File::mode() const
102 {
103     return m_mode;
104 }
105
106 inline bool File::open(const std::string &filename, File::Mode mode)
107 {
108     if (m_isOpened) {
109         close();
110     }
111     m_isOpened = rawOpen(filename, mode);
112     m_mode = mode;
113
114     return m_isOpened;
115 }
116
117 inline bool File::write(const void *buffer, size_t length)
118 {
119     if (!m_isOpened || m_mode != File::Write) {
120         return false;
121     }
122     return rawWrite(buffer, length);
123 }
124
125 inline size_t File::read(void *buffer, size_t length)
126 {
127     if (!m_isOpened || m_mode != File::Read) {
128         return 0;
129     }
130     return rawRead(buffer, length);
131 }
132
133 inline int File::percentRead()
134 {
135     if (!m_isOpened || m_mode != File::Read) {
136         return 0;
137     }
138     return rawPercentRead();
139 }
140
141 inline void File::close()
142 {
143     if (m_isOpened) {
144         rawClose();
145         m_isOpened = false;
146     }
147 }
148
149 inline void File::flush(void)
150 {
151     if (m_mode == File::Write) {
152         rawFlush();
153     }
154 }
155
156 inline int File::getc()
157 {
158     if (!m_isOpened || m_mode != File::Read) {
159         return -1;
160     }
161     return rawGetc();
162 }
163
164 inline bool File::skip(size_t length)
165 {
166     if (!m_isOpened || m_mode != File::Read) {
167         return false;
168     }
169     return rawSkip(length);
170 }
171
172
173 inline bool
174 operator<(const File::Offset &one, const File::Offset &two)
175 {
176     return one.chunk < two.chunk ||
177             (one.chunk == two.chunk && one.offsetInChunk < two.offsetInChunk);
178 }
179
180 inline bool
181 operator==(const File::Offset &one, const File::Offset &two)
182 {
183     return one.chunk == two.chunk &&
184             one.offsetInChunk == two.offsetInChunk;
185 }
186
187 inline bool
188 operator>=(const File::Offset &one, const File::Offset &two)
189 {
190     return one.chunk > two.chunk ||
191             (one.chunk == two.chunk && one.offsetInChunk >= two.offsetInChunk);
192 }
193
194 inline bool
195 operator>(const File::Offset &one, const File::Offset &two)
196 {
197     return two < one;
198 }
199
200 inline bool
201 operator<=(const File::Offset &one, const File::Offset &two)
202 {
203     return two >= one;
204 }
205
206
207 } /* namespace trace */
208
209 #endif