ARB
ps_filebuffer.cxx
Go to the documentation of this file.
1 
2 #include "ps_filebuffer.hxx"
3 
4 using namespace std;
5 
6 void PS_FileBuffer::put(const void *_data, int _length) {
7  if (is_readonly) {
8  fprintf(stderr, "sorry, i can't write to files opened readonly\n");
9  CRASH();
10  }
11  if (_length > BUFFER_SIZE) {
12  fprintf(stderr, "sorry, i can't write %i bytes at once, only %i\n", _length, BUFFER_SIZE);
13  CRASH();
14  }
15  if (_length == 0) return;
16  if (size + _length < BUFFER_SIZE) {
17  memcpy(&buffer[size], _data, _length);
18  size += _length;
19  }
20  else {
21  flush();
22  memcpy(buffer, _data, _length);
23  size = _length;
24  }
25 }
26 
27 
28 void PS_FileBuffer::get(void *_data, int _length) {
29  if (_length > BUFFER_SIZE) {
30  fprintf(stderr, "sorry, i can't read %i bytes at once, only %i\n", _length, BUFFER_SIZE);
31  CRASH();
32  }
33  if (_length == 0) return;
34  if (position + _length <= size) {
35  memcpy(_data, &buffer[position], _length);
36  position += _length;
37  }
38  else {
39  refill();
40  memcpy(_data, buffer, _length);
41  position = _length;
42  }
43 }
44 
45 
46 void PS_FileBuffer::put_ulong(unsigned long int _ul) {
47  if (_ul <= 0x7F) { // bit7 == 0 -> 1 byte integer
48  put_char(_ul);
49  }
50  else if (_ul <= 0x3FFF) {
51  put_char((_ul>>8) | 0x80); // bit7==1 && bit6==0 -> 2 byte integer
52  put_char(_ul & 0xFF);
53  }
54  else if (_ul <= 0x1FFFFF) {
55  put_char((_ul>>16) | 0xC0); // bit7==1 && bit6==1 && bit5==0 -> 3 byte integer
56  put_char((_ul>>8) & 0xFF);
57  put_char(_ul & 0xFF);
58  }
59  else if (_ul <= 0x0FFFFFFF) {
60  put_char((_ul>>24) | 0xE0); // bit7==1 && bit6==1 && bit5==1 && bit4==0 -> 4 byte integer
61  put_char((_ul>>16) & 0xFF);
62  put_char((_ul>>8) & 0xFF);
63  put_char(_ul & 0xFF);
64  }
65  else { // else -> 5 byte integer
66  put_char(0xF0);
67  put_char((_ul>>24) & 0xFF);
68  put_char((_ul>>16) & 0xFF);
69  put_char((_ul>>8) & 0xFF);
70  put_char(_ul & 0xFF);
71  }
72 
73 }
74 
75 
76 void PS_FileBuffer::get_ulong(unsigned long int &_ul) {
77  unsigned char c;
78  get_char(c);
79 
80  if ((c & 0x80) == 0) { // 1-byte
81  _ul = c;
82  }
83  else {
84  if ((c & 0xC0) == 0x80) { // 2-byte
85  _ul = (unsigned long)(c & 0x3F) << 8;
86  }
87  else {
88  if ((c & 0xE0) == 0xC0) { // 3-byte
89  _ul = (unsigned long)(c & 0x1F) << 16;
90  }
91  else {
92  if ((c & 0xF0) == 0xE0) { // 4-byte
93  _ul = (unsigned long)(c & 0x0F) << 24;
94  }
95  else {
96  get_char(c);
97  _ul = (unsigned long)c << 24;
98  }
99  get_char(c);
100  _ul = (unsigned long)c << 16;
101  }
102  get_char(c);
103  _ul |= (unsigned long)c << 8;
104  }
105  get_char(c);
106  _ul |= c;
107  }
108 }
109 
110 
111 void PS_FileBuffer::peek(void *_data, int _length) {
112  if (_length > BUFFER_SIZE) {
113  fprintf(stderr, "sorry, i can't read %i bytes at once, only %i\n", _length, BUFFER_SIZE);
114  CRASH();
115  }
116  if (position + _length <= size) {
117  memcpy(_data, &buffer[position], _length);
118  }
119  else {
120  refill();
121  memcpy(_data, buffer, _length);
122  }
123 }
124 
125 
127  ssize_t written = write(file_handle, buffer, size);
128  if (written != size) {
129  fprintf(stderr, "failed to write %i bytes to file %s (total_write = %lu)\n", size, file_name, total_write);
130  CRASH();
131  }
132  total_write += written;
133  size = 0;
134  position = 0;
135 }
136 
137 
138 void PS_FileBuffer::refill() {
139  // move unread data to start of buffer
140  int unread = size-position;
141  memcpy(buffer, &buffer[position], unread);
142  // read data from file
143  ssize_t readen = read(file_handle, &buffer[size-position], BUFFER_SIZE-unread);
144  if (readen < 1) {
145  fprintf(stderr, "failed to refill buffer from file %s (total_read = %lu)\n", file_name, total_read);
146  CRASH();
147  }
148  total_read += readen;
149  size = unread+readen;
150  position = 0;
151 }
152 
153 void PS_FileBuffer::reinit(const char *_name, bool _readonly) {
154  // finish old file
155  if (!is_readonly) flush();
156  if (file_name) free(file_name);
157  if (file_handle != -1) close(file_handle);
158 
159  // init. file
160  file_name = strdup(_name);
161  is_readonly = _readonly;
162  if (is_readonly) {
163  file_flags = O_RDONLY;
164  file_mode = 0;
165  }
166  else {
167  file_flags = O_WRONLY | O_CREAT | O_EXCL;
168  file_mode = S_IRUSR | S_IWUSR;
169  }
170  file_handle = open(file_name, file_flags, file_mode);
171  if (file_handle == -1) {
172  if (_readonly) {
173  fprintf(stderr, "failed to open file '%s' for reading\n", file_name);
174  }
175  else {
176  fprintf(stderr, "failed to create file '%s' for writing\nmaybe it already exists ?\n", file_name);
177  }
178  CRASH();
179  }
180 
181  // init. buffer
182  clear();
183 
184  // debug
185  total_read = 0;
186  total_write = 0;
187 }
188 
189 PS_FileBuffer::PS_FileBuffer(const char *_name, bool _readonly) :
190  file_name(strdup(_name)),
191  is_readonly(_readonly),
192  file_pos(-1)
193 {
194  // init. file
195 
196  if (is_readonly) {
197  file_flags = O_RDONLY;
198  file_mode = 0;
199  }
200  else {
201  file_flags = O_WRONLY | O_CREAT | O_EXCL;
202  file_mode = S_IRUSR | S_IWUSR;
203  }
204  file_handle = open(file_name, file_flags, file_mode);
205  if (file_handle == -1) {
206  if (_readonly) {
207  fprintf(stderr, "failed to open file '%s' for reading\n", file_name);
208  }
209  else {
210  fprintf(stderr, "failed to create file '%s' for writing\nmaybe it already exists ?\n", file_name);
211  }
212  CRASH();
213  }
214 
215  // init. buffer
216  size = 0;
217  position = 0;
218  buffer = (unsigned char *)malloc(BUFFER_SIZE);
219  if (!buffer) {
220  fprintf(stderr, "failed to allocate memory for buffer for file %s\n", file_name);
221  CRASH();
222  }
223 
224  // debug
225  total_read = 0;
226  total_write = 0;
227 }
void put_ulong(unsigned long int _ul)
void get(void *_data, int _length)
long
Definition: AW_awar.cxx:154
STL namespace.
char buffer[MESSAGE_BUFFERSIZE]
Definition: seq_search.cxx:34
#define CRASH
Definition: ps_assert.hxx:19
#define BUFFER_SIZE
Definition: SEC_read.cxx:17
void peek(void *_data, int _length)
void put(const void *_data, int _length)
static const int BUFFER_SIZE
void get_ulong(unsigned long int &_ul)
void reinit(const char *name, bool _readonly)