ARB
ps_filebuffer.hxx
Go to the documentation of this file.
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 
29 using namespace std;
30 
31 class 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 
51 public:
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 
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
void put_char(unsigned char _c)
void get_char(unsigned char &_c)
void put_long(long int _l)
long
Definition: AW_awar.cxx:152
void put_int(int _i)
void get_long(long int &_l)
STL namespace.
char buffer[MESSAGE_BUFFERSIZE]
Definition: seq_search.cxx:34
void put_uint(unsigned int _ui)
void get_uint(unsigned int &_ui)
unsigned char get_char()
#define CRASH
Definition: ps_assert.hxx:19
#define BUFFER_SIZE
Definition: SEC_read.cxx:17
void get_int(int &_i)