This source file includes following definitions.
- edit_buffer_get_byte_ptr
- edit_buffer_init
- edit_buffer_clean
- edit_buffer_get_byte
- edit_buffer_get_utf
- edit_buffer_get_prev_utf
- edit_buffer_count_lines
- edit_buffer_get_bol
- edit_buffer_get_eol
- edit_buffer_get_word_from_pos
- edit_buffer_find_word_start
- edit_buffer_insert
- edit_buffer_insert_ahead
- edit_buffer_delete
- edit_buffer_backspace
- edit_buffer_get_forward_offset
- edit_buffer_get_backward_offset
- edit_buffer_read_file
- edit_buffer_write_file
- edit_buffer_calc_percent
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 #include <config.h>
33
34 #include <ctype.h>
35 #include <stdlib.h>
36 #include <string.h>
37 #include <sys/types.h>
38
39 #include "lib/global.h"
40
41 #include "lib/vfs/vfs.h"
42
43 #include "edit-impl.h"
44 #include "editbuffer.h"
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89 #ifndef S_EDIT_BUF_SIZE
90 #define S_EDIT_BUF_SIZE 16
91 #endif
92
93
94 #define EDIT_BUF_SIZE (((off_t) 1) << S_EDIT_BUF_SIZE)
95
96
97 #define M_EDIT_BUF_SIZE (EDIT_BUF_SIZE - 1)
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116 static char *
117 edit_buffer_get_byte_ptr (const edit_buffer_t * buf, off_t byte_index)
118 {
119 void *b;
120
121 if (byte_index >= (buf->curs1 + buf->curs2) || byte_index < 0)
122 return NULL;
123
124 if (byte_index >= buf->curs1)
125 {
126 off_t p;
127
128 p = buf->curs1 + buf->curs2 - byte_index - 1;
129 b = g_ptr_array_index (buf->b2, p >> S_EDIT_BUF_SIZE);
130 return (char *) b + EDIT_BUF_SIZE - 1 - (p & M_EDIT_BUF_SIZE);
131 }
132
133 b = g_ptr_array_index (buf->b1, byte_index >> S_EDIT_BUF_SIZE);
134 return (char *) b + (byte_index & M_EDIT_BUF_SIZE);
135 }
136
137
138
139
140
141
142
143
144
145
146 void
147 edit_buffer_init (edit_buffer_t * buf, off_t size)
148 {
149 buf->b1 = g_ptr_array_new_full (32, g_free);
150 buf->b2 = g_ptr_array_new_full (32, g_free);
151
152 buf->curs1 = 0;
153 buf->curs2 = 0;
154
155 buf->size = size;
156 buf->lines = 0;
157 }
158
159
160
161
162
163
164
165
166 void
167 edit_buffer_clean (edit_buffer_t * buf)
168 {
169 if (buf->b1 != NULL)
170 g_ptr_array_free (buf->b1, TRUE);
171
172 if (buf->b2 != NULL)
173 g_ptr_array_free (buf->b2, TRUE);
174 }
175
176
177
178
179
180
181
182
183
184
185
186 int
187 edit_buffer_get_byte (const edit_buffer_t * buf, off_t byte_index)
188 {
189 char *p;
190
191 p = edit_buffer_get_byte_ptr (buf, byte_index);
192
193 return (p != NULL) ? *(unsigned char *) p : '\n';
194 }
195
196
197
198 #ifdef HAVE_CHARSET
199
200
201
202
203
204
205
206
207
208
209
210
211 int
212 edit_buffer_get_utf (const edit_buffer_t * buf, off_t byte_index, int *char_length)
213 {
214 gchar *str = NULL;
215 gunichar res;
216 gunichar ch;
217 gchar *next_ch = NULL;
218
219 if (byte_index >= (buf->curs1 + buf->curs2) || byte_index < 0)
220 {
221 *char_length = 0;
222 return '\n';
223 }
224
225 str = edit_buffer_get_byte_ptr (buf, byte_index);
226 if (str == NULL)
227 {
228 *char_length = 0;
229 return 0;
230 }
231
232 res = g_utf8_get_char_validated (str, -1);
233 if (res == (gunichar) (-2) || res == (gunichar) (-1))
234 {
235
236 size_t i;
237 gchar utf8_buf[UTF8_CHAR_LEN + 1];
238
239 for (i = 0; i < UTF8_CHAR_LEN; i++)
240 utf8_buf[i] = edit_buffer_get_byte (buf, byte_index + i);
241 utf8_buf[i] = '\0';
242 res = g_utf8_get_char_validated (utf8_buf, -1);
243 }
244
245 if (res == (gunichar) (-2) || res == (gunichar) (-1))
246 {
247 ch = *str;
248 *char_length = 0;
249 }
250 else
251 {
252 ch = res;
253
254 next_ch = g_utf8_next_char (str);
255 *char_length = next_ch - str;
256 }
257
258 return (int) ch;
259 }
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274 int
275 edit_buffer_get_prev_utf (const edit_buffer_t * buf, off_t byte_index, int *char_length)
276 {
277 size_t i;
278 gchar utf8_buf[3 * UTF8_CHAR_LEN + 1];
279 gchar *str;
280 gchar *cursor_buf_ptr;
281 gunichar res;
282
283 if (byte_index > (buf->curs1 + buf->curs2) || byte_index <= 0)
284 {
285 *char_length = 0;
286 return 0;
287 }
288
289 for (i = 0; i < (3 * UTF8_CHAR_LEN); i++)
290 utf8_buf[i] = edit_buffer_get_byte (buf, byte_index + i - (2 * UTF8_CHAR_LEN));
291 utf8_buf[i] = '\0';
292
293 cursor_buf_ptr = utf8_buf + (2 * UTF8_CHAR_LEN);
294 str = g_utf8_find_prev_char (utf8_buf, cursor_buf_ptr);
295
296 if (str == NULL || g_utf8_next_char (str) != cursor_buf_ptr)
297 {
298 *char_length = 1;
299 return *(cursor_buf_ptr - 1);
300 }
301
302 res = g_utf8_get_char_validated (str, -1);
303 if (res == (gunichar) (-2) || res == (gunichar) (-1))
304 {
305 *char_length = 1;
306 return *(cursor_buf_ptr - 1);
307 }
308
309 *char_length = cursor_buf_ptr - str;
310 return (int) res;
311 }
312 #endif
313
314
315
316
317
318
319
320
321
322
323
324
325 long
326 edit_buffer_count_lines (const edit_buffer_t * buf, off_t first, off_t last)
327 {
328 long lines = 0;
329
330 first = MAX (first, 0);
331 last = MIN (last, buf->size);
332
333 while (first < last)
334 if (edit_buffer_get_byte (buf, first++) == '\n')
335 lines++;
336
337 return lines;
338 }
339
340
341
342
343
344
345
346
347
348
349
350 off_t
351 edit_buffer_get_bol (const edit_buffer_t * buf, off_t current)
352 {
353 if (current <= 0)
354 return 0;
355
356 for (; edit_buffer_get_byte (buf, current - 1) != '\n'; current--)
357 ;
358
359 return current;
360 }
361
362
363
364
365
366
367
368
369
370
371
372 off_t
373 edit_buffer_get_eol (const edit_buffer_t * buf, off_t current)
374 {
375 if (current >= buf->size)
376 return buf->size;
377
378 for (; edit_buffer_get_byte (buf, current) != '\n'; current++)
379 ;
380
381 return current;
382 }
383
384
385
386
387
388
389
390
391
392
393
394
395
396 GString *
397 edit_buffer_get_word_from_pos (const edit_buffer_t * buf, off_t start_pos, off_t * start,
398 gsize * cut)
399 {
400 off_t word_start;
401 gsize cut_len = 0;
402 GString *match_expr;
403 int c1, c2;
404
405 for (word_start = start_pos; word_start != 0; word_start--, cut_len++)
406 {
407 c1 = edit_buffer_get_byte (buf, word_start);
408 c2 = edit_buffer_get_byte (buf, word_start - 1);
409
410 if (is_break_char (c1) != is_break_char (c2) || c1 == '\n' || c2 == '\n')
411 break;
412 }
413
414 match_expr = g_string_sized_new (16);
415
416 do
417 {
418 c1 = edit_buffer_get_byte (buf, word_start + match_expr->len);
419 c2 = edit_buffer_get_byte (buf, word_start + match_expr->len + 1);
420 g_string_append_c (match_expr, c1);
421 }
422 while (!(is_break_char (c1) != is_break_char (c2) || c1 == '\n' || c2 == '\n'));
423
424 *start = word_start;
425 *cut = cut_len;
426
427 return match_expr;
428 }
429
430
431
432
433
434
435
436
437
438
439
440
441
442 gboolean
443 edit_buffer_find_word_start (const edit_buffer_t * buf, off_t * word_start, gsize * word_len)
444 {
445 int c;
446 off_t i;
447
448
449 if (buf->curs1 <= 0)
450 return FALSE;
451
452 c = edit_buffer_get_previous_byte (buf);
453
454 if (is_break_char (c))
455 return FALSE;
456
457
458 for (i = 1;; i++)
459 {
460 int last;
461
462 last = c;
463 c = edit_buffer_get_byte (buf, buf->curs1 - i - 1);
464
465 if (is_break_char (c))
466 {
467
468 if (isdigit (last))
469 return FALSE;
470
471 break;
472 }
473 }
474
475
476 *word_start = buf->curs1 - i;
477 *word_len = (gsize) i;
478
479 return TRUE;
480 }
481
482
483
484
485
486
487
488
489
490
491 void
492 edit_buffer_insert (edit_buffer_t * buf, int c)
493 {
494 void *b;
495 off_t i;
496
497 i = buf->curs1 & M_EDIT_BUF_SIZE;
498
499
500 if (i == 0)
501 g_ptr_array_add (buf->b1, g_malloc0 (EDIT_BUF_SIZE));
502
503
504 b = g_ptr_array_index (buf->b1, buf->curs1 >> S_EDIT_BUF_SIZE);
505 *((unsigned char *) b + i) = (unsigned char) c;
506
507
508 buf->curs1++;
509
510
511 buf->size++;
512 }
513
514
515
516
517
518
519
520
521
522
523 void
524 edit_buffer_insert_ahead (edit_buffer_t * buf, int c)
525 {
526 void *b;
527 off_t i;
528
529 i = buf->curs2 & M_EDIT_BUF_SIZE;
530
531
532 if (i == 0)
533 g_ptr_array_add (buf->b2, g_malloc0 (EDIT_BUF_SIZE));
534
535
536 b = g_ptr_array_index (buf->b2, buf->curs2 >> S_EDIT_BUF_SIZE);
537 *((unsigned char *) b + EDIT_BUF_SIZE - 1 - i) = (unsigned char) c;
538
539
540 buf->curs2++;
541
542
543 buf->size++;
544 }
545
546
547
548
549
550
551
552
553
554
555 int
556 edit_buffer_delete (edit_buffer_t * buf)
557 {
558 void *b;
559 unsigned char c;
560 off_t prev;
561 off_t i;
562
563 prev = buf->curs2 - 1;
564
565 b = g_ptr_array_index (buf->b2, prev >> S_EDIT_BUF_SIZE);
566 i = prev & M_EDIT_BUF_SIZE;
567 c = *((unsigned char *) b + EDIT_BUF_SIZE - 1 - i);
568
569 if (i == 0)
570 {
571 guint j;
572
573 j = buf->b2->len - 1;
574 b = g_ptr_array_index (buf->b2, j);
575 g_ptr_array_remove_index (buf->b2, j);
576 }
577
578 buf->curs2 = prev;
579
580
581 buf->size--;
582
583 return c;
584 }
585
586
587
588
589
590
591
592
593
594
595 int
596 edit_buffer_backspace (edit_buffer_t * buf)
597 {
598 void *b;
599 unsigned char c;
600 off_t prev;
601 off_t i;
602
603 prev = buf->curs1 - 1;
604
605 b = g_ptr_array_index (buf->b1, prev >> S_EDIT_BUF_SIZE);
606 i = prev & M_EDIT_BUF_SIZE;
607 c = *((unsigned char *) b + i);
608
609 if (i == 0)
610 {
611 guint j;
612
613 j = buf->b1->len - 1;
614 b = g_ptr_array_index (buf->b1, j);
615 g_ptr_array_remove_index (buf->b1, j);
616 }
617
618 buf->curs1 = prev;
619
620
621 buf->size--;
622
623 return c;
624 }
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640 off_t
641 edit_buffer_get_forward_offset (const edit_buffer_t * buf, off_t current, long lines, off_t upto)
642 {
643 if (upto != 0)
644 return (off_t) edit_buffer_count_lines (buf, current, upto);
645
646 lines = MAX (lines, 0);
647
648 while (lines-- != 0)
649 {
650 long next;
651
652 next = edit_buffer_get_eol (buf, current) + 1;
653 if (next > buf->size)
654 break;
655 current = next;
656 }
657
658 return current;
659 }
660
661
662
663
664
665
666
667
668
669
670
671
672 off_t
673 edit_buffer_get_backward_offset (const edit_buffer_t * buf, off_t current, long lines)
674 {
675 lines = MAX (lines, 0);
676 current = edit_buffer_get_bol (buf, current);
677
678 while (lines-- != 0 && current != 0)
679 current = edit_buffer_get_bol (buf, current - 1);
680
681 return current;
682 }
683
684
685
686
687
688
689
690
691
692
693
694
695 off_t
696 edit_buffer_read_file (edit_buffer_t * buf, int fd, off_t size,
697 edit_buffer_read_file_status_msg_t * sm, gboolean * aborted)
698 {
699 off_t ret = 0;
700 off_t i, j;
701 off_t data_size;
702 void *b;
703 status_msg_t *s = STATUS_MSG (sm);
704 unsigned short update_cnt = 0;
705
706 *aborted = FALSE;
707
708 buf->lines = 0;
709 buf->curs2 = size;
710 i = buf->curs2 >> S_EDIT_BUF_SIZE;
711
712
713 data_size = buf->curs2 & M_EDIT_BUF_SIZE;
714 if (data_size != 0)
715 {
716 b = g_malloc0 (EDIT_BUF_SIZE);
717 g_ptr_array_add (buf->b2, b);
718 b = (char *) b + EDIT_BUF_SIZE - data_size;
719 ret = mc_read (fd, b, data_size);
720
721
722 for (j = 0; j < ret; j++)
723 if (*((char *) b + j) == '\n')
724 buf->lines++;
725
726 if (ret < 0 || ret != data_size)
727 return ret;
728 }
729
730
731 data_size = EDIT_BUF_SIZE;
732 for (--i; i >= 0; i--)
733 {
734 off_t sz;
735
736 b = g_malloc0 (data_size);
737 g_ptr_array_add (buf->b2, b);
738 sz = mc_read (fd, b, data_size);
739 if (sz >= 0)
740 ret += sz;
741
742
743 for (j = 0; j < sz; j++)
744 if (*((char *) b + j) == '\n')
745 buf->lines++;
746
747 if (s != NULL && s->update != NULL)
748 {
749 update_cnt = (update_cnt + 1) & 0xf;
750 if (update_cnt == 0)
751 {
752
753 if (sm->buf == NULL)
754 sm->buf = buf;
755
756 sm->loaded = ret;
757 if (s->update (s) == B_CANCEL)
758 {
759 *aborted = TRUE;
760 return (-1);
761 }
762 }
763 }
764
765 if (sz != data_size)
766 break;
767 }
768
769
770 for (i = 0; i < (off_t) buf->b2->len / 2; i++)
771 {
772 void **b1, **b2;
773
774 b1 = &g_ptr_array_index (buf->b2, i);
775 b2 = &g_ptr_array_index (buf->b2, buf->b2->len - 1 - i);
776
777 b = *b1;
778 *b1 = *b2;
779 *b2 = b;
780
781 if (s != NULL && s->update != NULL)
782 {
783 update_cnt = (update_cnt + 1) & 0xf;
784 if (update_cnt == 0)
785 {
786 sm->loaded = ret;
787 if (s->update (s) == B_CANCEL)
788 {
789 *aborted = TRUE;
790 return (-1);
791 }
792 }
793 }
794 }
795
796 return ret;
797 }
798
799
800
801
802
803
804
805
806
807
808
809 off_t
810 edit_buffer_write_file (edit_buffer_t * buf, int fd)
811 {
812 off_t ret = 0;
813 off_t i;
814 off_t data_size, sz;
815 void *b;
816
817
818 if (buf->b1->len != 0)
819 {
820 data_size = EDIT_BUF_SIZE;
821 for (i = 0; i < (off_t) buf->b1->len - 1; i++)
822 {
823 b = g_ptr_array_index (buf->b1, i);
824 sz = mc_write (fd, b, data_size);
825 if (sz >= 0)
826 ret += sz;
827 else if (i == 0)
828 ret = sz;
829 if (sz != data_size)
830 return ret;
831 }
832
833
834 data_size = ((buf->curs1 - 1) & M_EDIT_BUF_SIZE) + 1;
835 b = g_ptr_array_index (buf->b1, i);
836 sz = mc_write (fd, b, data_size);
837 if (sz >= 0)
838 ret += sz;
839 if (sz != data_size)
840 return ret;
841 }
842
843
844 if (buf->b2->len != 0)
845 {
846
847 i = buf->b2->len - 1;
848 b = g_ptr_array_index (buf->b2, i);
849 data_size = ((buf->curs2 - 1) & M_EDIT_BUF_SIZE) + 1;
850 sz = mc_write (fd, (char *) b + EDIT_BUF_SIZE - data_size, data_size);
851 if (sz >= 0)
852 ret += sz;
853
854 if (sz == data_size)
855 {
856
857 data_size = EDIT_BUF_SIZE;
858 while (--i >= 0)
859 {
860 b = g_ptr_array_index (buf->b2, i);
861 sz = mc_write (fd, b, data_size);
862 if (sz >= 0)
863 ret += sz;
864 if (sz != data_size)
865 break;
866 }
867 }
868 }
869
870 return ret;
871 }
872
873
874
875
876
877
878
879
880
881
882
883 int
884 edit_buffer_calc_percent (const edit_buffer_t * buf, off_t offset)
885 {
886 int percent;
887
888 if (buf->size == 0)
889 percent = 0;
890 else if (offset >= buf->size)
891 percent = 100;
892 else if (offset > (INT_MAX / 100))
893 percent = offset / (buf->size / 100);
894 else
895 percent = offset * 100 / buf->size;
896
897 return percent;
898 }
899
900