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