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