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, gsize *cut)
398 {
399 off_t word_start;
400 gsize cut_len = 0;
401 GString *match_expr;
402 int c1, c2;
403
404 for (word_start = start_pos; word_start != 0; word_start--, cut_len++)
405 {
406 c1 = edit_buffer_get_byte (buf, word_start);
407 c2 = edit_buffer_get_byte (buf, word_start - 1);
408
409 if (is_break_char (c1) != is_break_char (c2) || c1 == '\n' || c2 == '\n')
410 break;
411 }
412
413 match_expr = g_string_sized_new (16);
414
415 do
416 {
417 c1 = edit_buffer_get_byte (buf, word_start + match_expr->len);
418 c2 = edit_buffer_get_byte (buf, word_start + match_expr->len + 1);
419 g_string_append_c (match_expr, c1);
420 }
421 while (!(is_break_char (c1) != is_break_char (c2) || c1 == '\n' || c2 == '\n'));
422
423 *start = word_start;
424 *cut = cut_len;
425
426 return match_expr;
427 }
428
429
430
431
432
433
434
435
436
437
438
439
440
441 gboolean
442 edit_buffer_find_word_start (const edit_buffer_t *buf, off_t *word_start, gsize *word_len)
443 {
444 int c;
445 off_t i;
446
447
448 if (buf->curs1 <= 0)
449 return FALSE;
450
451 c = edit_buffer_get_previous_byte (buf);
452
453 if (is_break_char (c))
454 return FALSE;
455
456
457 for (i = 1;; i++)
458 {
459 int last;
460
461 last = c;
462 c = edit_buffer_get_byte (buf, buf->curs1 - i - 1);
463
464 if (is_break_char (c))
465 {
466
467 if (isdigit (last))
468 return FALSE;
469
470 break;
471 }
472 }
473
474
475 *word_start = buf->curs1 - i;
476 *word_len = (gsize) i;
477
478 return TRUE;
479 }
480
481
482
483
484
485
486
487
488
489
490 void
491 edit_buffer_insert (edit_buffer_t *buf, int c)
492 {
493 void *b;
494 off_t i;
495
496 i = buf->curs1 & M_EDIT_BUF_SIZE;
497
498
499 if (i == 0)
500 g_ptr_array_add (buf->b1, g_malloc0 (EDIT_BUF_SIZE));
501
502
503 b = g_ptr_array_index (buf->b1, buf->curs1 >> S_EDIT_BUF_SIZE);
504 *((unsigned char *) b + i) = (unsigned char) c;
505
506
507 buf->curs1++;
508
509
510 buf->size++;
511 }
512
513
514
515
516
517
518
519
520
521
522 void
523 edit_buffer_insert_ahead (edit_buffer_t *buf, int c)
524 {
525 void *b;
526 off_t i;
527
528 i = buf->curs2 & M_EDIT_BUF_SIZE;
529
530
531 if (i == 0)
532 g_ptr_array_add (buf->b2, g_malloc0 (EDIT_BUF_SIZE));
533
534
535 b = g_ptr_array_index (buf->b2, buf->curs2 >> S_EDIT_BUF_SIZE);
536 *((unsigned char *) b + EDIT_BUF_SIZE - 1 - i) = (unsigned char) c;
537
538
539 buf->curs2++;
540
541
542 buf->size++;
543 }
544
545
546
547
548
549
550
551
552
553
554 int
555 edit_buffer_delete (edit_buffer_t *buf)
556 {
557 void *b;
558 unsigned char c;
559 off_t prev;
560 off_t i;
561
562 prev = buf->curs2 - 1;
563
564 b = g_ptr_array_index (buf->b2, prev >> S_EDIT_BUF_SIZE);
565 i = prev & M_EDIT_BUF_SIZE;
566 c = *((unsigned char *) b + EDIT_BUF_SIZE - 1 - i);
567
568 if (i == 0)
569 {
570 guint j;
571
572 j = buf->b2->len - 1;
573 b = g_ptr_array_index (buf->b2, j);
574 g_ptr_array_remove_index (buf->b2, j);
575 }
576
577 buf->curs2 = prev;
578
579
580 buf->size--;
581
582 return c;
583 }
584
585
586
587
588
589
590
591
592
593
594 int
595 edit_buffer_backspace (edit_buffer_t *buf)
596 {
597 void *b;
598 unsigned char c;
599 off_t prev;
600 off_t i;
601
602 prev = buf->curs1 - 1;
603
604 b = g_ptr_array_index (buf->b1, prev >> S_EDIT_BUF_SIZE);
605 i = prev & M_EDIT_BUF_SIZE;
606 c = *((unsigned char *) b + i);
607
608 if (i == 0)
609 {
610 guint j;
611
612 j = buf->b1->len - 1;
613 b = g_ptr_array_index (buf->b1, j);
614 g_ptr_array_remove_index (buf->b1, j);
615 }
616
617 buf->curs1 = prev;
618
619
620 buf->size--;
621
622 return c;
623 }
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639 off_t
640 edit_buffer_get_forward_offset (const edit_buffer_t *buf, off_t current, long lines, off_t upto)
641 {
642 if (upto != 0)
643 return (off_t) edit_buffer_count_lines (buf, current, upto);
644
645 lines = MAX (lines, 0);
646
647 while (lines-- != 0)
648 {
649 long next;
650
651 next = edit_buffer_get_eol (buf, current) + 1;
652 if (next > buf->size)
653 break;
654 current = next;
655 }
656
657 return current;
658 }
659
660
661
662
663
664
665
666
667
668
669
670
671 off_t
672 edit_buffer_get_backward_offset (const edit_buffer_t *buf, off_t current, long lines)
673 {
674 lines = MAX (lines, 0);
675 current = edit_buffer_get_bol (buf, current);
676
677 while (lines-- != 0 && current != 0)
678 current = edit_buffer_get_bol (buf, current - 1);
679
680 return current;
681 }
682
683
684
685
686
687
688
689
690
691
692
693
694 off_t
695 edit_buffer_read_file (edit_buffer_t *buf, int fd, off_t size,
696 edit_buffer_read_file_status_msg_t *sm, gboolean *aborted)
697 {
698 off_t ret = 0;
699 off_t i, j;
700 off_t data_size;
701 void *b;
702 status_msg_t *s = STATUS_MSG (sm);
703 unsigned short update_cnt = 0;
704
705 *aborted = FALSE;
706
707 buf->lines = 0;
708 buf->curs2 = size;
709 i = buf->curs2 >> S_EDIT_BUF_SIZE;
710
711
712 data_size = buf->curs2 & M_EDIT_BUF_SIZE;
713 if (data_size != 0)
714 {
715 b = g_malloc0 (EDIT_BUF_SIZE);
716 g_ptr_array_add (buf->b2, b);
717 b = (char *) b + EDIT_BUF_SIZE - data_size;
718 ret = mc_read (fd, b, data_size);
719
720
721 for (j = 0; j < ret; j++)
722 if (*((char *) b + j) == '\n')
723 buf->lines++;
724
725 if (ret < 0 || ret != data_size)
726 return ret;
727 }
728
729
730 data_size = EDIT_BUF_SIZE;
731 for (--i; i >= 0; i--)
732 {
733 off_t sz;
734
735 b = g_malloc0 (data_size);
736 g_ptr_array_add (buf->b2, b);
737 sz = mc_read (fd, b, data_size);
738 if (sz >= 0)
739 ret += sz;
740
741
742 for (j = 0; j < sz; j++)
743 if (*((char *) b + j) == '\n')
744 buf->lines++;
745
746 if (s != NULL && s->update != NULL)
747 {
748 update_cnt = (update_cnt + 1) & 0xf;
749 if (update_cnt == 0)
750 {
751
752 if (sm->buf == NULL)
753 sm->buf = buf;
754
755 sm->loaded = ret;
756 if (s->update (s) == B_CANCEL)
757 {
758 *aborted = TRUE;
759 return (-1);
760 }
761 }
762 }
763
764 if (sz != data_size)
765 break;
766 }
767
768
769 for (i = 0; i < (off_t) buf->b2->len / 2; i++)
770 {
771 void **b1, **b2;
772
773 b1 = &g_ptr_array_index (buf->b2, i);
774 b2 = &g_ptr_array_index (buf->b2, buf->b2->len - 1 - i);
775
776 b = *b1;
777 *b1 = *b2;
778 *b2 = b;
779
780 if (s != NULL && s->update != NULL)
781 {
782 update_cnt = (update_cnt + 1) & 0xf;
783 if (update_cnt == 0)
784 {
785 sm->loaded = ret;
786 if (s->update (s) == B_CANCEL)
787 {
788 *aborted = TRUE;
789 return (-1);
790 }
791 }
792 }
793 }
794
795 return ret;
796 }
797
798
799
800
801
802
803
804
805
806
807
808 off_t
809 edit_buffer_write_file (edit_buffer_t *buf, int fd)
810 {
811 off_t ret = 0;
812 off_t i;
813 off_t data_size, sz;
814 void *b;
815
816
817 if (buf->b1->len != 0)
818 {
819 data_size = EDIT_BUF_SIZE;
820 for (i = 0; i < (off_t) buf->b1->len - 1; i++)
821 {
822 b = g_ptr_array_index (buf->b1, i);
823 sz = mc_write (fd, b, data_size);
824 if (sz >= 0)
825 ret += sz;
826 else if (i == 0)
827 ret = sz;
828 if (sz != data_size)
829 return ret;
830 }
831
832
833 data_size = ((buf->curs1 - 1) & M_EDIT_BUF_SIZE) + 1;
834 b = g_ptr_array_index (buf->b1, i);
835 sz = mc_write (fd, b, data_size);
836 if (sz >= 0)
837 ret += sz;
838 if (sz != data_size)
839 return ret;
840 }
841
842
843 if (buf->b2->len != 0)
844 {
845
846 i = buf->b2->len - 1;
847 b = g_ptr_array_index (buf->b2, i);
848 data_size = ((buf->curs2 - 1) & M_EDIT_BUF_SIZE) + 1;
849 sz = mc_write (fd, (char *) b + EDIT_BUF_SIZE - data_size, data_size);
850 if (sz >= 0)
851 ret += sz;
852
853 if (sz == data_size)
854 {
855
856 data_size = EDIT_BUF_SIZE;
857 while (--i >= 0)
858 {
859 b = g_ptr_array_index (buf->b2, i);
860 sz = mc_write (fd, b, data_size);
861 if (sz >= 0)
862 ret += sz;
863 if (sz != data_size)
864 break;
865 }
866 }
867 }
868
869 return ret;
870 }
871
872
873
874
875
876
877
878
879
880
881
882 int
883 edit_buffer_calc_percent (const edit_buffer_t *buf, off_t offset)
884 {
885 int percent;
886
887 if (buf->size == 0)
888 percent = 0;
889 else if (offset >= buf->size)
890 percent = 100;
891 else if (offset > (INT_MAX / 100))
892 percent = offset / (buf->size / 100);
893 else
894 percent = offset * 100 / buf->size;
895
896 return percent;
897 }
898
899