souffle  2.0.2-371-g6315b36
gzfstream.h
Go to the documentation of this file.
1 /*
2  * Souffle - A Datalog Compiler
3  * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved
4  * Licensed under the Universal Permissive License v 1.0 as shown at:
5  * - https://opensource.org/licenses/UPL
6  * - <souffle root>/licenses/SOUFFLE-UPL.txt
7  */
8 
9 /************************************************************************
10  *
11  * @file gzfstream.h
12  * A simple zlib wrapper to provide gzip file streams.
13  *
14  ***********************************************************************/
15 
16 #pragma once
17 
18 #include <cstdio>
19 #include <cstring>
20 #include <iostream>
21 #include <string>
22 #include <zlib.h>
23 
24 namespace souffle {
25 
26 namespace gzfstream {
27 
28 namespace internal {
29 
30 class gzfstreambuf : public std::streambuf {
31 public:
32  gzfstreambuf() {
33  setp(buffer, buffer + (bufferSize - 1));
35  }
36 
37  gzfstreambuf(const gzfstreambuf&) = delete;
38 
39  gzfstreambuf(gzfstreambuf&& old) = default;
40 
41  gzfstreambuf* open(const std::string& filename, std::ios_base::openmode mode) {
42  if (is_open()) {
43  return nullptr;
44  }
45  if ((mode ^ std::ios::in ^ std::ios::out) == 0) {
46  return nullptr;
47  }
48 
49  this->mode = mode;
50  std::string gzmode((mode & std::ios::in) != 0 ? "rb" : "wb");
51  fileHandle = gzopen(filename.c_str(), gzmode.c_str());
52 
53  if (fileHandle == nullptr) {
54  return nullptr;
55  }
56  isOpen = true;
57 
58  return this;
59  }
60 
62  if (is_open()) {
63  sync();
64  isOpen = false;
65  if (gzclose(fileHandle) == Z_OK) {
66  return this;
67  }
68  }
69  return nullptr;
70  }
71 
72  bool is_open() const {
73  return isOpen;
74  }
75 
76  ~gzfstreambuf() override {
77  try {
78  close();
79  } catch (...) {
80  // Don't throw exceptions.
81  }
82  }
83 
84 protected:
85  int_type overflow(int c = EOF) override {
86  if (((mode & std::ios::out) == 0) || !isOpen) {
87  return EOF;
88  }
89 
90  if (c != EOF) {
91  *pptr() = c;
92  pbump(1);
93  }
94  int toWrite = pptr() - pbase();
95  if (gzwrite(fileHandle, pbase(), toWrite) != toWrite) {
96  return EOF;
97  }
98  pbump(-toWrite);
99 
100  return c;
101  }
102 
103  int_type underflow() override {
104  if (((mode & std::ios::in) == 0) || !isOpen) {
105  return EOF;
106  }
107  if ((gptr() != nullptr) && (gptr() < egptr())) {
108  return traits_type::to_int_type(*gptr());
109  }
110 
111  unsigned charsPutBack = gptr() - eback();
112  if (charsPutBack > reserveSize) {
113  charsPutBack = reserveSize;
114  }
115  memcpy(buffer + reserveSize - charsPutBack, gptr() - charsPutBack, charsPutBack);
116 
117  int charsRead = gzread(fileHandle, buffer + reserveSize, bufferSize - reserveSize);
118  if (charsRead <= 0) {
119  return EOF;
120  }
121 
122  setg(buffer + reserveSize - charsPutBack, buffer + reserveSize, buffer + reserveSize + charsRead);
123 
124  return traits_type::to_int_type(*gptr());
125  }
126 
127  int sync() override {
128  if ((pptr() != nullptr) && pptr() > pbase()) {
129  int toWrite = pptr() - pbase();
130  if (gzwrite(fileHandle, pbase(), toWrite) != toWrite) {
131  return -1;
132  }
133  pbump(-toWrite);
134  }
135  return 0;
136  }
137 
138 private:
139  static constexpr unsigned int bufferSize = 65536;
140  static constexpr unsigned int reserveSize = 16;
141 
142  char buffer[bufferSize] = {};
143  gzFile fileHandle = {};
144  bool isOpen = false;
145  std::ios_base::openmode mode = std::ios_base::in;
146 };
147 
148 class gzfstream : virtual public std::ios {
149 public:
150  gzfstream() {
151  init(&buf);
152  }
153 
154  gzfstream(const std::string& filename, std::ios_base::openmode mode) {
155  init(&buf);
156  open(filename, mode);
157  }
158 
159  gzfstream(const gzfstream&) = delete;
160 
161  gzfstream(gzfstream&&) = delete;
162 
163  ~gzfstream() override = default;
164 
165  void open(const std::string& filename, std::ios_base::openmode mode) {
166  if (buf.open(filename, mode) == nullptr) {
167  clear(rdstate() | std::ios::badbit);
168  }
169  }
170 
171  bool is_open() {
172  return buf.is_open();
173  }
174 
175  void close() {
176  if (buf.is_open()) {
177  if (buf.close() == nullptr) {
178  clear(rdstate() | std::ios::badbit);
179  }
180  }
181  }
182 
183  gzfstreambuf* rdbuf() const {
184  return &buf;
185  }
186 
187 protected:
188  mutable gzfstreambuf buf;
189 };
190 
191 } // namespace internal
192 
193 class igzfstream : public internal::gzfstream, public std::istream {
194 public:
195  igzfstream() : internal::gzfstream(), std::istream(&buf) {}
196 
197  explicit igzfstream(const std::string& filename, std::ios_base::openmode mode = std::ios::in)
198  : internal::gzfstream(filename, mode), std::istream(&buf) {}
199 
200  igzfstream(const igzfstream&) = delete;
201 
202  igzfstream(igzfstream&&) = delete;
203 
204  internal::gzfstreambuf* rdbuf() const {
206  }
207 
208  void open(const std::string& filename, std::ios_base::openmode mode = std::ios::in) {
209  internal::gzfstream::open(filename, mode);
210  }
211 };
212 
213 class ogzfstream : public internal::gzfstream, public std::ostream {
214 public:
215  ogzfstream() : std::ostream(&buf) {}
216 
217  explicit ogzfstream(const std::string& filename, std::ios_base::openmode mode = std::ios::out)
218  : internal::gzfstream(filename, mode), std::ostream(&buf) {}
219 
220  ogzfstream(const ogzfstream&) = delete;
221 
222  ogzfstream(ogzfstream&&) = delete;
223 
224  internal::gzfstreambuf* rdbuf() const {
226  }
227 
228  void open(const std::string& filename, std::ios_base::openmode mode = std::ios::out) {
229  internal::gzfstream::open(filename, mode);
230  }
231 };
232 
233 } /* namespace gzfstream */
234 
235 } /* namespace souffle */
souffle::gzfstream::internal::gzfstreambuf::open
gzfstreambuf * open(const std::string &filename, std::ios_base::openmode mode)
Definition: gzfstream.h:61
souffle::gzfstream::ogzfstream::rdbuf
internal::gzfstreambuf * rdbuf() const
Definition: gzfstream.h:234
souffle::gzfstream::internal::gzfstreambuf
Definition: gzfstream.h:45
souffle::gzfstream::internal::gzfstreambuf::isOpen
bool isOpen
Definition: gzfstream.h:164
souffle::gzfstream::internal::gzfstream::close
void close()
Definition: gzfstream.h:190
souffle::gzfstream::internal::gzfstreambuf::buffer
char buffer[bufferSize]
Definition: gzfstream.h:162
souffle::gzfstream::internal::gzfstreambuf::mode
std::ios_base::openmode mode
Definition: gzfstream.h:165
souffle::gzfstream::internal::gzfstream::rdbuf
gzfstreambuf * rdbuf() const
Definition: gzfstream.h:198
souffle::gzfstream::internal::gzfstreambuf::bufferSize
static constexpr unsigned int bufferSize
Definition: gzfstream.h:159
souffle::gzfstream::ogzfstream
Definition: gzfstream.h:223
souffle::gzfstream::internal::gzfstream::is_open
bool is_open()
Definition: gzfstream.h:186
souffle::gzfstream::internal::gzfstreambuf::sync
int sync() override
Definition: gzfstream.h:147
souffle::gzfstream::internal::gzfstream::buf
gzfstreambuf buf
Definition: gzfstream.h:203
souffle::gzfstream::internal::gzfstream
Definition: gzfstream.h:163
souffle::gzfstream::internal::gzfstreambuf::overflow
int_type overflow(int c=EOF) override
Definition: gzfstream.h:105
souffle::gzfstream::internal::gzfstream::open
void open(const std::string &filename, std::ios_base::openmode mode)
Definition: gzfstream.h:180
souffle::gzfstream::igzfstream::rdbuf
internal::gzfstreambuf * rdbuf() const
Definition: gzfstream.h:214
souffle::gzfstream::internal::gzfstreambuf::is_open
bool is_open() const
Definition: gzfstream.h:92
souffle::gzfstream::internal::gzfstream::gzfstream
gzfstream()
Definition: gzfstream.h:165
souffle::gzfstream::ogzfstream::ogzfstream
ogzfstream()
Definition: gzfstream.h:225
souffle::gzfstream::igzfstream::open
void open(const std::string &filename, std::ios_base::openmode mode=std::ios::in)
Definition: gzfstream.h:218
souffle::gzfstream::internal::gzfstreambuf::underflow
int_type underflow() override
Definition: gzfstream.h:123
souffle::gzfstream::ogzfstream::open
void open(const std::string &filename, std::ios_base::openmode mode=std::ios::out)
Definition: gzfstream.h:238
souffle::gzfstream::internal::gzfstreambuf::reserveSize
static constexpr unsigned int reserveSize
Definition: gzfstream.h:160
souffle::gzfstream::internal::gzfstreambuf::fileHandle
gzFile fileHandle
Definition: gzfstream.h:163
std
Definition: Brie.h:3053
souffle::gzfstream::internal::gzfstream::~gzfstream
~gzfstream() override=default
souffle
Definition: AggregateOp.h:25
souffle::gzfstream::internal::gzfstreambuf::close
gzfstreambuf * close()
Definition: gzfstream.h:81
souffle::gzfstream::internal::gzfstreambuf::~gzfstreambuf
~gzfstreambuf() override
Definition: gzfstream.h:96
souffle::gzfstream::igzfstream
Definition: gzfstream.h:203
souffle::gzfstream::internal::gzfstreambuf::gzfstreambuf
gzfstreambuf()
Definition: gzfstream.h:52
souffle::gzfstream::igzfstream::igzfstream
igzfstream()
Definition: gzfstream.h:205