This source file includes following definitions.
- mcview_set_datasource_stdio_pipe
- mcview_set_datasource_none
- mcview_get_filesize
- mcview_update_filesize
- mcview_get_ptr_file
- mcview_get_utf
- mcview_get_ptr_string
- mcview_get_byte_string
- mcview_get_byte_none
- mcview_set_byte
- mcview_file_load_data
- mcview_close_datasource
- mcview_set_datasource_file
- mcview_load_command_output
- mcview_set_datasource_vfs_pipe
- mcview_set_datasource_string
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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55 #include <config.h>
56
57 #include "lib/global.h"
58 #include "lib/vfs/vfs.h"
59 #include "lib/util.h"
60 #include "lib/widget.h"
61
62 #include "internal.h"
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78 static void
79 mcview_set_datasource_stdio_pipe (WView *view, mc_pipe_t *p)
80 {
81 p->out.len = MC_PIPE_BUFSIZE;
82 p->out.null_term = FALSE;
83 p->err.len = MC_PIPE_BUFSIZE;
84 p->err.null_term = TRUE;
85 view->datasource = DS_STDIO_PIPE;
86 view->ds_stdio_pipe = p;
87 view->pipe_first_err_msg = TRUE;
88
89 mcview_growbuf_init (view);
90 }
91
92
93
94
95
96 void
97 mcview_set_datasource_none (WView *view)
98 {
99 view->datasource = DS_NONE;
100 }
101
102
103
104 off_t
105 mcview_get_filesize (WView *view)
106 {
107 switch (view->datasource)
108 {
109 case DS_STDIO_PIPE:
110 case DS_VFS_PIPE:
111 return mcview_growbuf_filesize (view);
112 case DS_FILE:
113 return view->ds_file_filesize;
114 case DS_STRING:
115 return view->ds_string_len;
116 default:
117 return 0;
118 }
119 }
120
121
122
123 void
124 mcview_update_filesize (WView *view)
125 {
126 if (view->datasource == DS_FILE)
127 {
128 struct stat st;
129 if (mc_fstat (view->ds_file_fd, &st) != -1)
130 view->ds_file_filesize = st.st_size;
131 }
132 }
133
134
135
136 char *
137 mcview_get_ptr_file (WView *view, off_t byte_index)
138 {
139 g_assert (view->datasource == DS_FILE);
140
141 mcview_file_load_data (view, byte_index);
142 if (mcview_already_loaded (view->ds_file_offset, byte_index, view->ds_file_datalen))
143 return (char *) (view->ds_file_data + (byte_index - view->ds_file_offset));
144 return NULL;
145 }
146
147
148
149
150
151 gboolean
152 mcview_get_utf (WView *view, off_t byte_index, int *ch, int *ch_len)
153 {
154 gchar *str = NULL;
155 int res;
156 gchar utf8buf[UTF8_CHAR_LEN + 1];
157
158 switch (view->datasource)
159 {
160 case DS_STDIO_PIPE:
161 case DS_VFS_PIPE:
162 str = mcview_get_ptr_growing_buffer (view, byte_index);
163 break;
164 case DS_FILE:
165 str = mcview_get_ptr_file (view, byte_index);
166 break;
167 case DS_STRING:
168 str = mcview_get_ptr_string (view, byte_index);
169 break;
170 case DS_NONE:
171 default:
172 break;
173 }
174
175 *ch = 0;
176
177 if (str == NULL)
178 return FALSE;
179
180 res = g_utf8_get_char_validated (str, -1);
181
182 if (res < 0)
183 {
184
185 int i;
186
187 for (i = 0; i < UTF8_CHAR_LEN; i++)
188 {
189 if (mcview_get_byte (view, byte_index + i, &res))
190 utf8buf[i] = res;
191 else
192 {
193 utf8buf[i] = '\0';
194 break;
195 }
196 }
197 utf8buf[UTF8_CHAR_LEN] = '\0';
198 str = utf8buf;
199 res = g_utf8_get_char_validated (str, -1);
200 }
201
202 if (res < 0)
203 {
204
205 *ch = *str;
206 *ch_len = 1;
207 }
208 else
209 {
210 gchar *next_ch = NULL;
211
212 *ch = res;
213
214 next_ch = g_utf8_next_char (str);
215 *ch_len = next_ch - str;
216 }
217
218 return TRUE;
219 }
220
221
222
223 char *
224 mcview_get_ptr_string (WView *view, off_t byte_index)
225 {
226 g_assert (view->datasource == DS_STRING);
227
228 if (byte_index >= 0 && byte_index < (off_t) view->ds_string_len)
229 return (char *) (view->ds_string_data + byte_index);
230 return NULL;
231 }
232
233
234
235 gboolean
236 mcview_get_byte_string (WView *view, off_t byte_index, int *retval)
237 {
238 char *p;
239
240 if (retval != NULL)
241 *retval = -1;
242
243 p = mcview_get_ptr_string (view, byte_index);
244 if (p == NULL)
245 return FALSE;
246
247 if (retval != NULL)
248 *retval = (unsigned char) (*p);
249 return TRUE;
250 }
251
252
253
254 gboolean
255 mcview_get_byte_none (WView *view, off_t byte_index, int *retval)
256 {
257 (void) &view;
258 (void) byte_index;
259
260 g_assert (view->datasource == DS_NONE);
261
262 if (retval != NULL)
263 *retval = -1;
264 return FALSE;
265 }
266
267
268
269 void
270 mcview_set_byte (WView *view, off_t offset, byte b)
271 {
272 (void) &b;
273 (void) offset;
274
275 g_assert (offset < mcview_get_filesize (view));
276 g_assert (view->datasource == DS_FILE);
277
278 view->ds_file_datalen = 0;
279 }
280
281
282
283
284 void
285 mcview_file_load_data (WView *view, off_t byte_index)
286 {
287 off_t blockoffset;
288 ssize_t res;
289 size_t bytes_read;
290
291 g_assert (view->datasource == DS_FILE);
292
293 if (mcview_already_loaded (view->ds_file_offset, byte_index, view->ds_file_datalen))
294 return;
295
296 if (byte_index >= view->ds_file_filesize)
297 return;
298
299 blockoffset = mcview_offset_rounddown (byte_index, view->ds_file_datasize);
300 if (mc_lseek (view->ds_file_fd, blockoffset, SEEK_SET) == -1)
301 goto error;
302
303 bytes_read = 0;
304 while (bytes_read < view->ds_file_datasize)
305 {
306 res =
307 mc_read (view->ds_file_fd, view->ds_file_data + bytes_read,
308 view->ds_file_datasize - bytes_read);
309 if (res == -1)
310 goto error;
311 if (res == 0)
312 break;
313 bytes_read += (size_t) res;
314 }
315 view->ds_file_offset = blockoffset;
316 if ((off_t) bytes_read > view->ds_file_filesize - view->ds_file_offset)
317 {
318
319 view->ds_file_datalen = view->ds_file_filesize - view->ds_file_offset;
320 }
321 else
322 {
323 view->ds_file_datalen = bytes_read;
324 }
325 return;
326
327 error:
328 view->ds_file_datalen = 0;
329 }
330
331
332
333 void
334 mcview_close_datasource (WView *view)
335 {
336 switch (view->datasource)
337 {
338 case DS_NONE:
339 break;
340 case DS_STDIO_PIPE:
341 if (view->ds_stdio_pipe != NULL)
342 {
343 mcview_growbuf_done (view);
344 mcview_display (view);
345 }
346 mcview_growbuf_free (view);
347 break;
348 case DS_VFS_PIPE:
349 if (view->ds_vfs_pipe != -1)
350 mcview_growbuf_done (view);
351 mcview_growbuf_free (view);
352 break;
353 case DS_FILE:
354 (void) mc_close (view->ds_file_fd);
355 view->ds_file_fd = -1;
356 MC_PTR_FREE (view->ds_file_data);
357 break;
358 case DS_STRING:
359 MC_PTR_FREE (view->ds_string_data);
360 break;
361 default:
362 break;
363 }
364 view->datasource = DS_NONE;
365 }
366
367
368
369 void
370 mcview_set_datasource_file (WView *view, int fd, const struct stat *st)
371 {
372 view->datasource = DS_FILE;
373 view->ds_file_fd = fd;
374 view->ds_file_filesize = st->st_size;
375 view->ds_file_offset = 0;
376 view->ds_file_data = g_malloc (4096);
377 view->ds_file_datalen = 0;
378 view->ds_file_datasize = 4096;
379 }
380
381
382
383 gboolean
384 mcview_load_command_output (WView *view, const char *command)
385 {
386 mc_pipe_t *p;
387 GError *error = NULL;
388
389 mcview_close_datasource (view);
390
391 p = mc_popen (command, TRUE, TRUE, &error);
392 if (p == NULL)
393 {
394 mcview_display (view);
395 mcview_show_error (view, error->message);
396 g_error_free (error);
397 return FALSE;
398 }
399
400
401 mcview_set_datasource_stdio_pipe (view, p);
402 if (!mcview_get_byte (view, 0, NULL))
403 {
404 mcview_close_datasource (view);
405 mcview_display (view);
406 return FALSE;
407 }
408
409 return TRUE;
410 }
411
412
413
414 void
415 mcview_set_datasource_vfs_pipe (WView *view, int fd)
416 {
417 g_assert (fd != -1);
418
419 view->datasource = DS_VFS_PIPE;
420 view->ds_vfs_pipe = fd;
421
422 mcview_growbuf_init (view);
423 }
424
425
426
427 void
428 mcview_set_datasource_string (WView *view, const char *s)
429 {
430 view->datasource = DS_STRING;
431 view->ds_string_len = strlen (s);
432 view->ds_string_data = (byte *) g_strndup (s, view->ds_string_len);
433 }
434
435