This source file includes following definitions.
- mcview_growbuf_init
- mcview_growbuf_done
- mcview_growbuf_free
- mcview_growbuf_filesize
- mcview_growbuf_read_until
- mcview_get_byte_growing_buffer
- mcview_get_ptr_growing_buffer
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36 #include <config.h>
37 #include <errno.h>
38
39 #include "lib/global.h"
40 #include "lib/vfs/vfs.h"
41 #include "lib/util.h"
42 #include "lib/widget.h"
43
44 #include "internal.h"
45
46
47 #define VIEW_PAGE_SIZE ((size_t) 8192)
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64 void
65 mcview_growbuf_init (WView *view)
66 {
67 view->growbuf_in_use = TRUE;
68 view->growbuf_blockptr = g_ptr_array_new_with_free_func (g_free);
69 view->growbuf_lastindex = VIEW_PAGE_SIZE;
70 view->growbuf_finished = FALSE;
71 }
72
73
74
75 void
76 mcview_growbuf_done (WView *view)
77 {
78 view->growbuf_finished = TRUE;
79
80 if (view->datasource == DS_STDIO_PIPE)
81 {
82 mc_pclose (view->ds_stdio_pipe, NULL);
83 view->ds_stdio_pipe = NULL;
84 }
85 else
86 {
87 (void) mc_close (view->ds_vfs_pipe);
88 view->ds_vfs_pipe = -1;
89 }
90 }
91
92
93
94 void
95 mcview_growbuf_free (WView *view)
96 {
97 g_assert (view->growbuf_in_use);
98
99 g_ptr_array_free (view->growbuf_blockptr, TRUE);
100 view->growbuf_blockptr = NULL;
101 view->growbuf_in_use = FALSE;
102 }
103
104
105
106 off_t
107 mcview_growbuf_filesize (WView *view)
108 {
109 g_assert (view->growbuf_in_use);
110
111 if (view->growbuf_blockptr->len == 0)
112 return 0;
113 else
114 return ((off_t) view->growbuf_blockptr->len - 1) * VIEW_PAGE_SIZE + view->growbuf_lastindex;
115 }
116
117
118
119
120
121
122
123 void
124 mcview_growbuf_read_until (WView *view, off_t ofs)
125 {
126 gboolean short_read = FALSE;
127
128 g_assert (view->growbuf_in_use);
129
130 if (view->growbuf_finished)
131 return;
132
133 while (mcview_growbuf_filesize (view) < ofs || short_read)
134 {
135 ssize_t nread = 0;
136 byte *p;
137 size_t bytesfree;
138
139 if (view->growbuf_lastindex == VIEW_PAGE_SIZE)
140 {
141
142 byte *newblock = g_try_malloc (VIEW_PAGE_SIZE);
143 if (newblock == NULL)
144 return;
145
146 g_ptr_array_add (view->growbuf_blockptr, newblock);
147 view->growbuf_lastindex = 0;
148 }
149
150 p = (byte *) g_ptr_array_index (view->growbuf_blockptr,
151 view->growbuf_blockptr->len - 1) + view->growbuf_lastindex;
152
153 bytesfree = VIEW_PAGE_SIZE - view->growbuf_lastindex;
154
155 if (view->datasource == DS_STDIO_PIPE)
156 {
157 mc_pipe_t *sp = view->ds_stdio_pipe;
158 GError *error = NULL;
159
160 if (bytesfree > MC_PIPE_BUFSIZE)
161 bytesfree = MC_PIPE_BUFSIZE;
162
163 sp->out.len = bytesfree;
164 sp->err.len = MC_PIPE_BUFSIZE;
165
166 mc_pread (sp, &error);
167
168 if (error != NULL)
169 {
170 mcview_show_error (view, error->message);
171 g_error_free (error);
172 mcview_growbuf_done (view);
173 return;
174 }
175
176 if (view->pipe_first_err_msg && sp->err.len > 0)
177 {
178
179
180
181
182
183 view->pipe_first_err_msg = FALSE;
184
185 mcview_show_error (view, sp->err.buf);
186
187
188
189
190
191
192
193
194 if (view->ds_stdio_pipe == NULL)
195 return;
196 }
197
198 if (sp->out.len > 0)
199 {
200 memmove (p, sp->out.buf, sp->out.len);
201 nread = sp->out.len;
202 }
203 else if (sp->out.len == MC_PIPE_STREAM_EOF || sp->out.len == MC_PIPE_ERROR_READ)
204 {
205 if (sp->out.len == MC_PIPE_ERROR_READ)
206 {
207 char *err_msg;
208
209 err_msg = g_strdup_printf (_("Failed to read data from child stdout:\n%s"),
210 unix_error_string (sp->out.error));
211 mcview_show_error (view, err_msg);
212 g_free (err_msg);
213 }
214
215
216
217
218
219
220 mcview_growbuf_done (view);
221
222 mcview_display (view);
223 return;
224 }
225 }
226 else
227 {
228 g_assert (view->datasource == DS_VFS_PIPE);
229 do
230 {
231 nread = mc_read (view->ds_vfs_pipe, p, bytesfree);
232 }
233 while (nread == -1 && errno == EINTR);
234
235 if (nread <= 0)
236 {
237 mcview_growbuf_done (view);
238 return;
239 }
240 }
241 short_read = ((size_t) nread < bytesfree);
242 view->growbuf_lastindex += nread;
243 }
244 }
245
246
247
248 gboolean
249 mcview_get_byte_growing_buffer (WView *view, off_t byte_index, int *retval)
250 {
251 char *p;
252
253 g_assert (view->growbuf_in_use);
254
255 if (retval != NULL)
256 *retval = -1;
257
258 if (byte_index < 0)
259 return FALSE;
260
261 p = mcview_get_ptr_growing_buffer (view, byte_index);
262 if (p == NULL)
263 return FALSE;
264
265 if (retval != NULL)
266 *retval = (unsigned char) (*p);
267
268 return TRUE;
269 }
270
271
272
273 char *
274 mcview_get_ptr_growing_buffer (WView *view, off_t byte_index)
275 {
276 off_t pageno, pageindex;
277
278 g_assert (view->growbuf_in_use);
279
280 if (byte_index < 0)
281 return NULL;
282
283 pageno = byte_index / VIEW_PAGE_SIZE;
284 pageindex = byte_index % VIEW_PAGE_SIZE;
285
286 mcview_growbuf_read_until (view, byte_index + 1);
287 if (view->growbuf_blockptr->len == 0)
288 return NULL;
289 if (pageno < (off_t) view->growbuf_blockptr->len - 1)
290 return ((char *) g_ptr_array_index (view->growbuf_blockptr, pageno) + pageindex);
291 if (pageno == (off_t) view->growbuf_blockptr->len - 1
292 && pageindex < (off_t) view->growbuf_lastindex)
293 return ((char *) g_ptr_array_index (view->growbuf_blockptr, pageno) + pageindex);
294 return NULL;
295 }
296
297