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