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 ();
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_foreach (view->growbuf_blockptr, (GFunc) g_free, NULL);
100
101 (void) g_ptr_array_free (view->growbuf_blockptr, TRUE);
102
103 view->growbuf_blockptr = NULL;
104 view->growbuf_in_use = FALSE;
105 }
106
107
108
109 off_t
110 mcview_growbuf_filesize (WView * view)
111 {
112 g_assert (view->growbuf_in_use);
113
114 if (view->growbuf_blockptr->len == 0)
115 return 0;
116 else
117 return ((off_t) view->growbuf_blockptr->len - 1) * VIEW_PAGE_SIZE + view->growbuf_lastindex;
118 }
119
120
121
122
123
124
125
126 void
127 mcview_growbuf_read_until (WView * view, off_t ofs)
128 {
129 gboolean short_read = FALSE;
130
131 g_assert (view->growbuf_in_use);
132
133 if (view->growbuf_finished)
134 return;
135
136 while (mcview_growbuf_filesize (view) < ofs || short_read)
137 {
138 ssize_t nread = 0;
139 byte *p;
140 size_t bytesfree;
141
142 if (view->growbuf_lastindex == VIEW_PAGE_SIZE)
143 {
144
145 byte *newblock = g_try_malloc (VIEW_PAGE_SIZE);
146 if (newblock == NULL)
147 return;
148
149 g_ptr_array_add (view->growbuf_blockptr, newblock);
150 view->growbuf_lastindex = 0;
151 }
152
153 p = (byte *) g_ptr_array_index (view->growbuf_blockptr,
154 view->growbuf_blockptr->len - 1) + view->growbuf_lastindex;
155
156 bytesfree = VIEW_PAGE_SIZE - view->growbuf_lastindex;
157
158 if (view->datasource == DS_STDIO_PIPE)
159 {
160 mc_pipe_t *sp = view->ds_stdio_pipe;
161 GError *error = NULL;
162
163 if (bytesfree > MC_PIPE_BUFSIZE)
164 bytesfree = MC_PIPE_BUFSIZE;
165
166 sp->out.len = bytesfree;
167 sp->err.len = MC_PIPE_BUFSIZE;
168
169 mc_pread (sp, &error);
170
171 if (error != NULL)
172 {
173 mcview_show_error (view, error->message);
174 g_error_free (error);
175 mcview_growbuf_done (view);
176 return;
177 }
178
179 if (view->pipe_first_err_msg && sp->err.len > 0)
180 {
181
182
183
184
185
186 view->pipe_first_err_msg = FALSE;
187
188 mcview_show_error (view, sp->err.buf);
189 }
190
191 if (sp->out.len > 0)
192 {
193 memmove (p, sp->out.buf, sp->out.len);
194 nread = sp->out.len;
195 }
196 else if (sp->out.len == MC_PIPE_STREAM_EOF || sp->out.len == MC_PIPE_ERROR_READ)
197 {
198 if (sp->out.len == MC_PIPE_ERROR_READ)
199 {
200 char *err_msg;
201
202 err_msg = g_strdup_printf (_("Failed to read data from child stdout:\n%s"),
203 unix_error_string (sp->out.error));
204 mcview_show_error (view, err_msg);
205 g_free (err_msg);
206 }
207
208
209
210
211
212
213 mcview_growbuf_done (view);
214
215 mcview_display (view);
216 return;
217 }
218 }
219 else
220 {
221 g_assert (view->datasource == DS_VFS_PIPE);
222 do
223 {
224 nread = mc_read (view->ds_vfs_pipe, p, bytesfree);
225 }
226 while (nread == -1 && errno == EINTR);
227
228 if (nread <= 0)
229 {
230 mcview_growbuf_done (view);
231 return;
232 }
233 }
234 short_read = ((size_t) nread < bytesfree);
235 view->growbuf_lastindex += nread;
236 }
237 }
238
239
240
241 gboolean
242 mcview_get_byte_growing_buffer (WView * view, off_t byte_index, int *retval)
243 {
244 char *p;
245
246 g_assert (view->growbuf_in_use);
247
248 if (retval != NULL)
249 *retval = -1;
250
251 if (byte_index < 0)
252 return FALSE;
253
254 p = mcview_get_ptr_growing_buffer (view, byte_index);
255 if (p == NULL)
256 return FALSE;
257
258 if (retval != NULL)
259 *retval = (unsigned char) (*p);
260
261 return TRUE;
262 }
263
264
265
266 char *
267 mcview_get_ptr_growing_buffer (WView * view, off_t byte_index)
268 {
269 off_t pageno, pageindex;
270
271 g_assert (view->growbuf_in_use);
272
273 if (byte_index < 0)
274 return NULL;
275
276 pageno = byte_index / VIEW_PAGE_SIZE;
277 pageindex = byte_index % VIEW_PAGE_SIZE;
278
279 mcview_growbuf_read_until (view, byte_index + 1);
280 if (view->growbuf_blockptr->len == 0)
281 return NULL;
282 if (pageno < (off_t) view->growbuf_blockptr->len - 1)
283 return ((char *) g_ptr_array_index (view->growbuf_blockptr, pageno) + pageindex);
284 if (pageno == (off_t) view->growbuf_blockptr->len - 1
285 && pageindex < (off_t) view->growbuf_lastindex)
286 return ((char *) g_ptr_array_index (view->growbuf_blockptr, pageno) + pageindex);
287 return NULL;
288 }
289
290