source: branches/tree/PROBE_SET/ps_filebuffer.cxx

Last change on this file was 18732, checked in by westram, 3 years ago
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 6.0 KB
Line 
1
2#include "ps_filebuffer.hxx"
3
4using namespace std;
5
6void 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
28void 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
46void 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
76void 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
111void 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
126void PS_FileBuffer::flush() {
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
138void 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
153void 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
189PS_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}
Note: See TracBrowser for help on using the repository browser.