source: branches/stable/PROBE_SET/ps_filebuffer.hxx

Last change on this file was 16766, checked in by westram, 6 years ago
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 4.9 KB
Line 
1// =============================================================== //
2//                                                                 //
3//   File      : ps_filebuffer.hxx                                 //
4//   Purpose   :                                                   //
5//                                                                 //
6//   Coded by Wolfram Foerster in October 2002                     //
7//   Institute of Microbiology (Technical University Munich)       //
8//   http://www.arb-home.de/                                       //
9//                                                                 //
10// =============================================================== //
11
12#ifndef PS_FILEBUFFER_HXX
13#define PS_FILEBUFFER_HXX
14
15#ifndef PS_ASSERT_HXX
16#include "ps_assert.hxx"
17#endif
18#ifndef ARBTOOLS_H
19#include <arbtools.h>
20#endif
21
22#include <cstdio>
23#include <cstdlib>
24#include <cstring>
25#include <fcntl.h>
26#include <sys/stat.h>
27#include <unistd.h>
28
29using namespace std;
30
31class PS_FileBuffer : virtual Noncopyable {
32    // filehandling
33    int   file_handle;
34    char *file_name;
35    int   file_flags;
36    int   file_mode;
37    bool  is_readonly;
38    long  file_pos;
39    // bufferhandling
40    unsigned char *buffer;
41    int            size;                // how much is in buffer
42    int            position;            // where am i in the buffer
43    // debug
44    unsigned long int total_read;
45    unsigned long int total_write;
46
47    PS_FileBuffer();
48
49    void refill();                      // refill buffer from file
50
51public:
52    static const bool READONLY    = true;
53    static const bool WRITEONLY   = false;
54    static const int  BUFFER_SIZE = 4096;
55
56    //
57    // IO-functions
58    //
59
60    // raw
61    void put (const void *_data, int _length);
62    void get (void *_data, int _length);
63    void peek(void *_data, int _length);         // read but don't advance position
64
65    // char
66    void put_char(unsigned char  _c) {
67        if (is_readonly) {
68            fprintf(stderr, "sorry, i can't write to files opened readonly\n");
69            CRASH();
70        }
71        if (size+1 < BUFFER_SIZE) {
72            buffer[size] = _c;
73            ++size;
74        }
75        else {
76            flush();
77            buffer[0] = _c;
78            size      = 1;
79        }
80    }
81    void get_char(unsigned char &_c) {
82        if (position < size) {
83            _c = buffer[position];
84            ++position;
85        }
86        else {
87            refill();
88            _c       = buffer[0];
89            position = 1;
90        }
91    }
92    unsigned char get_char() {
93        if (position < size) {
94            return buffer[position++];
95        }
96        else {
97            refill();
98            position = 1;
99            return buffer[0];
100        }
101    }
102
103    // long
104    void put_ulong(unsigned long int  _ul);
105    void get_ulong(unsigned long int &_ul);
106    void put_long(long int  _l) {
107        unsigned long int ul;
108        if (_l < 0) {
109            ul = (-_l << 1) | 1;
110        }
111        else {
112            ul = _l << 1;
113        }
114        put_ulong(ul);
115    }
116    void get_long(long int &_l) {
117        unsigned long int ul;
118        get_ulong(ul);
119        if (ul & 1) {
120            _l = -(long)(ul >> 1);
121        }
122        else {
123            _l = ul >> 1;
124        }
125    }
126
127    // int
128    void put_uint(unsigned int  _ui) {
129        put_ulong(_ui);
130    }
131    void get_uint(unsigned int &_ui) {
132        unsigned long int ul;
133        get_ulong(ul);
134        _ui=(unsigned int)ul;
135    }
136    void put_int(int  _i) {
137        put_long(_i);
138    }
139    void get_int(int &_i) {
140        long int l;
141        get_long(l);
142        _i=(int)l;
143    }
144
145
146    //
147    // utility-functions
148    //
149    bool store_pos() {
150        if (!is_readonly) return false; // cannot jump in a writeable file
151        file_pos = lseek(file_handle, 0, SEEK_CUR);
152        return file_pos >= 0;
153    }
154
155    bool restore_pos() {
156        if (!is_readonly) return false; // cannot jump in a writeable file
157        if (file_pos < 0) return false;
158        if (lseek(file_handle, file_pos, SEEK_SET) < 0) return false;
159        size     = 0;
160        position = 0;
161        refill();
162        return true;
163    }
164
165    bool empty() {
166        if (size == 0) return true;
167        return position < size;
168    }
169
170    void clear() {                       // 'clear' buffer
171        size     = 0;
172        position = 0;
173    }
174
175    bool isReadonly() {
176        return is_readonly;
177    }
178
179    void flush();                       // write buffer to file
180
181    //
182    // initialization-functions
183    //
184    void reinit(const char *name, bool _readonly);   // reinit. with new file
185
186    PS_FileBuffer(const char *_name, bool _readonly);
187
188    ~PS_FileBuffer() {
189        // finish file
190        if (!is_readonly) flush();
191        if (file_name) free(file_name);
192        if (file_handle != -1) close(file_handle);
193        // finish buffer
194        if (buffer) free(buffer);
195    }
196
197};
198
199#else
200#error ps_filebuffer.hxx included twice
201#endif // PS_FILEBUFFER_HXX
Note: See TracBrowser for help on using the repository browser.