OpenMD 3.0
Molecular Dynamics in the Open
Loading...
Searching...
No Matches
gzstream.cpp
1// ============================================================================
2// gzstream, C++ iostream classes wrapping the zlib compression library.
3// Copyright (C) 2001 Deepak Bandyopadhyay, Lutz Kettner
4//
5// This library is free software; you can redistribute it and/or
6// modify it under the terms of the GNU Lesser General Public
7// License as published by the Free Software Foundation; either
8// version 2.1 of the License, or (at your option) any later version.
9//
10// This library is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13// Lesser General Public License for more details.
14//
15// You should have received a copy of the GNU Lesser General Public
16// License along with this library; if not, write to the Free Software
17// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18// ============================================================================
19//
20// File : gzstream.C
21// Revision : $Revision$
22// Revision_date : $Date$
23// Author(s) : Deepak Bandyopadhyay, Lutz Kettner
24//
25// Standard streambuf implementation following Nicolai Josuttis, "The
26// Standard C++ Library".
27// ============================================================================
28
29#include "io/gzstream.hpp"
30
31#include <cstring> // for memcpy
32#include <iostream>
33
34namespace OpenMD {
35
36 // ----------------------------------------------------------------------------
37 // Internal classes to implement gzstream. See header file for user classes.
38 // ----------------------------------------------------------------------------
39
40 // --------------------------------------
41 // class gzstreambuf:
42 // --------------------------------------
43
44 gzstreambuf* gzstreambuf::open(const char* name, int open_mode) {
45 if (is_open()) return (gzstreambuf*)0;
46 mode = open_mode;
47 // no append nor read/write mode
48 if ((mode & std::ios::ate) || (mode & std::ios::app) ||
49 ((mode & std::ios::in) && (mode & std::ios::out)))
50 return (gzstreambuf*)0;
51 char fmode[10];
52 char* fmodeptr = fmode;
53 if (mode & std::ios::in)
54 *fmodeptr++ = 'r';
55 else if (mode & std::ios::out)
56 *fmodeptr++ = 'w';
57 *fmodeptr++ = 'b';
58 *fmodeptr = '\0';
59 file = gzopen(name, fmode);
60 if (file == 0) return (gzstreambuf*)0;
61 opened = 1;
62 return this;
63 }
64
65 gzstreambuf* gzstreambuf::close() {
66 if (is_open()) {
67 sync();
68 opened = 0;
69 if (gzclose(file) == Z_OK) return this;
70 }
71 return (gzstreambuf*)0;
72 }
73
74 int gzstreambuf::underflow() { // used for input buffer only
75 if (gptr() && (gptr() < egptr()))
76 return *reinterpret_cast<unsigned char*>(gptr());
77
78 if (!(mode & std::ios::in) || !opened) return EOF;
79 // Josuttis' implementation of inbuf
80 int n_putback = gptr() - eback();
81 if (n_putback > 4) n_putback = 4;
82 memcpy(buffer + (4 - n_putback), gptr() - n_putback, n_putback);
83
84 int num = gzread(file, buffer + 4, bufferSize - 4);
85 if (num <= 0) // ERROR or EOF
86 return EOF;
87
88 // reset buffer pointers
89 setg(buffer + (4 - n_putback), // beginning of putback area
90 buffer + 4, // read position
91 buffer + 4 + num); // end of buffer
92
93 // return next character
94 return *reinterpret_cast<unsigned char*>(gptr());
95 }
96
97 int gzstreambuf::flush_buffer() {
98 // Separate the writing of the buffer from overflow() and
99 // sync() operation.
100 int w = pptr() - pbase();
101 if (gzwrite(file, pbase(), w) != w) return EOF;
102 pbump(-w);
103 return w;
104 }
105
106 int gzstreambuf::overflow(int c) { // used for output buffer only
107 if (!(mode & std::ios::out) || !opened) return EOF;
108 if (c != EOF) {
109 *pptr() = c;
110 pbump(1);
111 }
112 if (flush_buffer() == EOF) return EOF;
113 return c;
114 }
115
116 int gzstreambuf::sync() {
117 // Changed to use flush_buffer() instead of overflow( EOF)
118 // which caused improper behavior with std::endl and flush(),
119 // bug reported by Vincent Ricard.
120 if (pptr() && pptr() > pbase()) {
121 if (flush_buffer() == EOF) return -1;
122 }
123 return 0;
124 }
125
126 // --------------------------------------
127 // class gzstreambase:
128 // --------------------------------------
129
130 gzstreambase::gzstreambase(const char* name, int mode) {
131 init(&buf);
132 open(name, mode);
133 }
134
135 gzstreambase::~gzstreambase() { buf.close(); }
136
137 void gzstreambase::open(const char* name, int open_mode) {
138 if (!buf.open(name, open_mode)) clear(rdstate() | std::ios::badbit);
139 }
140
141 void gzstreambase::close() {
142 if (buf.is_open())
143 if (!buf.close()) clear(rdstate() | std::ios::badbit);
144 }
145
146} // namespace OpenMD
This basic Periodic Table class was originally taken from the data.cpp file in OpenBabel.