OSDN Git Service

implement text insertion to texteditor_textfragment_t.
authorornse01 <ornse01@users.sourceforge.jp>
Fri, 1 Aug 2014 17:43:34 +0000 (17:43 +0000)
committerornse01 <ornse01@users.sourceforge.jp>
Fri, 1 Aug 2014 17:43:34 +0000 (17:43 +0000)
git-svn-id: http://svn.sourceforge.jp/svnroot/bchan/bchanf/trunk@615 20a0b8eb-f62a-4a12-8fe1-b598822500fb

src/control/test_texteditor_textfragment.c
src/control/texteditor_textfragment.c
src/control/texteditor_textfragment.h

index bf736a4..7634bc6 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * test_texteditor_textfragment.c
  *
- * Copyright (c) 2013 project bchan
+ * Copyright (c) 2013-2014 project bchan
  *
  * This software is provided 'as-is', without any express or implied
  * warranty. In no event will the authors be held liable for any damages
@@ -32,6 +32,7 @@
 #include       <bstdio.h>
 #include       <bstdlib.h>
 #include       <bstring.h>
+#include       <tcode.h>
 
 #include    <unittest_driver.h>
 
@@ -49,7 +50,443 @@ LOCAL UNITTEST_RESULT test_texteditor_textfragment_1()
        return UNITTEST_RESULT_PASS;
 }
 
+typedef struct {
+       TC *data;
+       W len;
+} test_data_t;
+
+typedef struct {
+       test_data_t original;
+       test_data_t *insert;
+       W insert_len;
+       W insert_pos;
+       test_data_t expected;
+       W expected_segment_num;
+} test_texteditor_insertcontext_t;
+
+LOCAL W test_texteditor_textfragment_initialvalue(texteditor_textfragment_t *fragment, test_data_t *original)
+{
+       texteditor_insertcontext_t context;
+       W err;
+
+       err = texteditor_insertcontext_initialize(&context, fragment, -1, 0);
+       if (err < 0) {
+               printf("texteditor_insertcontext_initialize error\n");
+               return err;
+       }
+
+       err = texteditor_insertcontext_insert(&context, (UB*)original->data, original->len);
+       if (err < 0) {
+               printf("texteditor_insertcontext_insert error\n");
+               texteditor_insertcontext_finalize(&context);
+               return err;
+       }
+
+       return texteditor_insertcontext_finalize(&context);
+}
+
+LOCAL UNITTEST_RESULT test_texteditor_insertcontext_common(test_texteditor_insertcontext_t *testdata)
+{
+       texteditor_textfragment_t fragment;
+       texteditor_insertcontext_t context;
+       W i, len, err;
+       UB *buf;
+       UNITTEST_RESULT result = UNITTEST_RESULT_PASS;
+
+       err = texteditor_textfragment_initialize(&fragment);
+       if (err < 0) {
+               return UNITTEST_RESULT_FAIL;
+       }
+
+       err = test_texteditor_textfragment_initialvalue(&fragment, &testdata->original);
+       if (err < 0) {
+               printf("texteditor value initialize error\n");
+               result = UNITTEST_RESULT_FAIL;
+       }
+
+       err = texteditor_insertcontext_initialize(&context, &fragment, -1, testdata->insert_pos);
+       if (err < 0) {
+               printf("texteditor_insertcontext_initialize error\n");
+               result = UNITTEST_RESULT_FAIL;
+       } else {
+               for (i = 0; i < testdata->insert_len; i++) {
+                       err = texteditor_insertcontext_insert(&context, (UB*)testdata->insert[i].data, testdata->insert[i].len);
+                       if (err < 0) {
+                               printf("tadfragment_cursor_insert error\n");
+                               result = UNITTEST_RESULT_FAIL;
+                       }
+               }
+
+               err = texteditor_insertcontext_finalize(&context);
+
+               len = texteditor_textfragment_getsegmentlength(&fragment);
+               if (len != testdata->expected_segment_num) {
+                       printf("texteditor_textfragment_getsegmentlength fail: expected = %d, result = %d\n", testdata->expected_segment_num, len);
+                       result = UNITTEST_RESULT_FAIL;
+               }
+
+               len = texteditor_textfragment_getbufferlength(&fragment);
+               if (len != testdata->expected.len) {
+                       printf("texteditor_textfragment_getbufferlength fail: expected = %d, result = %d\n", testdata->expected.len, len);
+                       result = UNITTEST_RESULT_FAIL;
+               }
+
+               buf = texteditor_textfragment_getbuffer(&fragment);
+               if (memcmp(buf, testdata->expected.data, testdata->expected.len) != 0) {
+                       printf("texteditor_textfragment_getbuffer fail\n");
+                       {
+                               W i;
+                               for (i = 0; i < testdata->expected.len; i++) {
+                                       printf("%02x, %02x\n", buf[i], ((UB*)testdata->expected.data)[i]);
+                               }
+                       }
+                       result = UNITTEST_RESULT_FAIL;
+               }
+       }
+
+       texteditor_textfragment_finalize(&fragment);
+
+       return result;
+}
+
+LOCAL UNITTEST_RESULT test_texteditor_insertcontext_1()
+{
+       test_data_t original = {
+               (TC[]){TK_A, TK_B, TK_C},
+               6
+       };
+       test_data_t *insert = NULL;
+       W insert_len = 0;
+       W insert_pos = 0;
+       test_data_t expected = {
+               (TC[]){TK_A, TK_B, TK_C},
+               6
+       };
+       W expected_segment_num = 3;
+       test_texteditor_insertcontext_t testdata = {
+               original,
+               insert, insert_len, insert_pos,
+               expected, expected_segment_num
+       };
+       return test_texteditor_insertcontext_common(&testdata);
+}
+
+LOCAL UNITTEST_RESULT test_texteditor_insertcontext_2()
+{
+       test_data_t original = {
+               (TC[]){TK_A, TK_B, TK_C},
+               6
+       };
+       test_data_t insert[] = {
+               { (TC[]){TK_D, TK_E}, 4 }
+       };
+       W insert_len = 1;
+       W insert_pos = 0;
+       test_data_t expected = {
+               (TC[]){TK_D, TK_E, TK_A, TK_B, TK_C},
+               10
+       };
+       W expected_segment_num = 5;
+       test_texteditor_insertcontext_t testdata = {
+               original,
+               insert, insert_len, insert_pos,
+               expected, expected_segment_num
+       };
+       return test_texteditor_insertcontext_common(&testdata);
+}
+
+LOCAL UNITTEST_RESULT test_texteditor_insertcontext_3()
+{
+       test_data_t original = {
+               (TC[]){TK_A, TK_B, TK_C},
+               6
+       };
+       test_data_t insert[] = {
+               { (TC[]){TK_D, TK_E}, 4 }
+       };
+       W insert_len = 1;
+       W insert_pos = 1;
+       test_data_t expected = {
+               (TC[]){TK_A, TK_D, TK_E, TK_B, TK_C},
+               10
+       };
+       W expected_segment_num = 5;
+       test_texteditor_insertcontext_t testdata = {
+               original,
+               insert, insert_len, insert_pos,
+               expected, expected_segment_num
+       };
+       return test_texteditor_insertcontext_common(&testdata);
+}
+
+LOCAL UNITTEST_RESULT test_texteditor_insertcontext_4()
+{
+       test_data_t original = {
+               (TC[]){TK_A, TK_B, TK_C},
+               6
+       };
+       test_data_t insert[] = {
+               { (TC[]){TK_D, TK_E}, 4 }
+       };
+       W insert_len = 1;
+       W insert_pos = 2;
+       test_data_t expected = {
+               (TC[]){TK_A, TK_B, TK_D, TK_E, TK_C},
+               10
+       };
+       W expected_segment_num = 5;
+       test_texteditor_insertcontext_t testdata = {
+               original,
+               insert, insert_len, insert_pos,
+               expected, expected_segment_num
+       };
+       return test_texteditor_insertcontext_common(&testdata);
+}
+
+LOCAL UNITTEST_RESULT test_texteditor_insertcontext_5()
+{
+       test_data_t original = {
+               (TC[]){TK_A, TK_B, TK_C},
+               6
+       };
+       test_data_t insert[] = {
+               { (TC[]){TK_D, TK_E}, 4 }
+       };
+       W insert_len = 1;
+       W insert_pos = 3;
+       test_data_t expected = {
+               (TC[]){TK_A, TK_B, TK_C, TK_D, TK_E},
+               10
+       };
+       W expected_segment_num = 5;
+       test_texteditor_insertcontext_t testdata = {
+               original,
+               insert, insert_len, insert_pos,
+               expected, expected_segment_num
+       };
+       return test_texteditor_insertcontext_common(&testdata);
+}
+
+LOCAL UNITTEST_RESULT test_texteditor_insertcontext_6()
+{
+       test_data_t original = {
+               (TC[]){TK_A, TK_B, TK_C},
+               6
+       };
+       test_data_t insert[] = {
+               { (TC[]){0xFE22, TK_D, TK_E}, 6 }
+       };
+       W insert_len = 1;
+       W insert_pos = 0;
+       test_data_t expected = {
+               (TC[]){0xFE22, TK_D, TK_E, 0xFE21, TK_A, TK_B, TK_C},
+               14
+       };
+       W expected_segment_num = 7;
+       test_texteditor_insertcontext_t testdata = {
+               original,
+               insert, insert_len, insert_pos,
+               expected, expected_segment_num
+       };
+       return test_texteditor_insertcontext_common(&testdata);
+}
+
+LOCAL UNITTEST_RESULT test_texteditor_insertcontext_7()
+{
+       test_data_t original = {
+               (TC[]){TK_A, TK_B, TK_C},
+               6
+       };
+       test_data_t insert[] = {
+               { (TC[]){0xFE22, TK_D, TK_E}, 6 }
+       };
+       W insert_len = 1;
+       W insert_pos = 1;
+       test_data_t expected = {
+               (TC[]){TK_A, 0xFE22, TK_D, TK_E, 0xFE21, TK_B, TK_C},
+               14
+       };
+       W expected_segment_num = 7;
+       test_texteditor_insertcontext_t testdata = {
+               original,
+               insert, insert_len, insert_pos,
+               expected, expected_segment_num
+       };
+       return test_texteditor_insertcontext_common(&testdata);
+}
+
+LOCAL UNITTEST_RESULT test_texteditor_insertcontext_8()
+{
+       test_data_t original = {
+               (TC[]){TK_A, TK_B, TK_C},
+               6
+       };
+       test_data_t insert[] = {
+               { (TC[]){0xFE22, TK_D, TK_E}, 6 }
+       };
+       W insert_len = 1;
+       W insert_pos = 2;
+       test_data_t expected = {
+               (TC[]){TK_A, TK_B, 0xFE22, TK_D, TK_E, 0xFE21, TK_C},
+               14
+       };
+       W expected_segment_num = 7;
+       test_texteditor_insertcontext_t testdata = {
+               original,
+               insert, insert_len, insert_pos,
+               expected, expected_segment_num
+       };
+       return test_texteditor_insertcontext_common(&testdata);
+}
+
+LOCAL UNITTEST_RESULT test_texteditor_insertcontext_9()
+{
+       test_data_t original = {
+               (TC[]){TK_A, TK_B, TK_C},
+               6
+       };
+       test_data_t insert[] = {
+               { (TC[]){0xFE22, TK_D, TK_E}, 6 }
+       };
+       W insert_len = 1;
+       W insert_pos = 3;
+       test_data_t expected = {
+               (TC[]){TK_A, TK_B, TK_C, 0xFE22, TK_D, TK_E, 0xFE21},
+               14
+       };
+       W expected_segment_num = 7;
+       test_texteditor_insertcontext_t testdata = {
+               original,
+               insert, insert_len, insert_pos,
+               expected, expected_segment_num
+       };
+       return test_texteditor_insertcontext_common(&testdata);
+}
+
+LOCAL UNITTEST_RESULT test_texteditor_insertcontext_10()
+{
+       test_data_t original = {
+               (TC[]){TK_A, TK_B, TK_C},
+               6
+       };
+       test_data_t insert[] = {
+               { (TC[]){0xFFA2, 0x0006, 0x0300, 0x0101, 0x0102, TK_D, TK_E}, 14 }
+       };
+       W insert_len = 1;
+       W insert_pos = 0;
+       test_data_t expected = {
+               (TC[]){0xFFA2, 0x0006, 0x0300, 0x0101, 0x0102,
+                          TK_D, TK_E,
+                          0xFFA2, 0x0006, 0x0300, 0x0101, 0x0101,
+                          TK_A, TK_B, TK_C },
+               30
+       };
+       W expected_segment_num = 7;
+       test_texteditor_insertcontext_t testdata = {
+               original,
+               insert, insert_len, insert_pos,
+               expected, expected_segment_num
+       };
+       return test_texteditor_insertcontext_common(&testdata);
+}
+
+LOCAL UNITTEST_RESULT test_texteditor_insertcontext_11()
+{
+       test_data_t original = {
+               (TC[]){TK_A, TK_B, TK_C},
+               6
+       };
+       test_data_t insert[] = {
+               { (TC[]){0xFFA2, 0x0006, 0x0300, 0x0101, 0x0102, TK_D, TK_E}, 14 }
+       };
+       W insert_len = 1;
+       W insert_pos = 1;
+       test_data_t expected = {
+               (TC[]){TK_A,
+                          0xFFA2, 0x0006, 0x0300, 0x0101, 0x0102,
+                          TK_D, TK_E,
+                          0xFFA2, 0x0006, 0x0300, 0x0101, 0x0101,
+                          TK_B, TK_C },
+               30
+       };
+       W expected_segment_num = 7;
+       test_texteditor_insertcontext_t testdata = {
+               original,
+               insert, insert_len, insert_pos,
+               expected, expected_segment_num
+       };
+       return test_texteditor_insertcontext_common(&testdata);
+}
+
+LOCAL UNITTEST_RESULT test_texteditor_insertcontext_12()
+{
+       test_data_t original = {
+               (TC[]){TK_A, TK_B, TK_C},
+               6
+       };
+       test_data_t insert[] = {
+               { (TC[]){0xFFA2, 0x0006, 0x0300, 0x0101, 0x0102, TK_D, TK_E}, 14 }
+       };
+       W insert_len = 1;
+       W insert_pos = 2;
+       test_data_t expected = {
+               (TC[]){TK_A, TK_B,
+                          0xFFA2, 0x0006, 0x0300, 0x0101, 0x0102,
+                          TK_D, TK_E,
+                          0xFFA2, 0x0006, 0x0300, 0x0101, 0x0101,
+                          TK_C },
+               30
+       };
+       W expected_segment_num = 7;
+       test_texteditor_insertcontext_t testdata = {
+               original,
+               insert, insert_len, insert_pos,
+               expected, expected_segment_num
+       };
+       return test_texteditor_insertcontext_common(&testdata);
+}
+
+LOCAL UNITTEST_RESULT test_texteditor_insertcontext_13()
+{
+       test_data_t original = {
+               (TC[]){TK_A, TK_B, TK_C},
+               6
+       };
+       test_data_t insert[] = {
+               { (TC[]){0xFFA2, 0x0006, 0x0300, 0x0101, 0x0102, TK_D, TK_E}, 14 }
+       };
+       W insert_len = 1;
+       W insert_pos = 3;
+       test_data_t expected = {
+               (TC[]){TK_A, TK_B, TK_C,
+                          0xFFA2, 0x0006, 0x0300, 0x0101, 0x0102,
+                          TK_D, TK_E,
+                          0xFFA2, 0x0006, 0x0300, 0x0101, 0x0101},
+               30
+       };
+       W expected_segment_num = 7;
+       test_texteditor_insertcontext_t testdata = {
+               original,
+               insert, insert_len, insert_pos,
+               expected, expected_segment_num
+       };
+       return test_texteditor_insertcontext_common(&testdata);
+}
+
 EXPORT VOID test_texteditor_textfragment_main(unittest_driver_t *driver)
 {
        UNITTEST_DRIVER_REGIST(driver, test_texteditor_textfragment_1);
+       UNITTEST_DRIVER_REGIST(driver, test_texteditor_insertcontext_1);
+       UNITTEST_DRIVER_REGIST(driver, test_texteditor_insertcontext_2);
+       UNITTEST_DRIVER_REGIST(driver, test_texteditor_insertcontext_3);
+       UNITTEST_DRIVER_REGIST(driver, test_texteditor_insertcontext_4);
+       UNITTEST_DRIVER_REGIST(driver, test_texteditor_insertcontext_5);
+       UNITTEST_DRIVER_REGIST(driver, test_texteditor_insertcontext_6);
+       UNITTEST_DRIVER_REGIST(driver, test_texteditor_insertcontext_7);
+       UNITTEST_DRIVER_REGIST(driver, test_texteditor_insertcontext_8);
+       UNITTEST_DRIVER_REGIST(driver, test_texteditor_insertcontext_9);
+       UNITTEST_DRIVER_REGIST(driver, test_texteditor_insertcontext_10);
+       UNITTEST_DRIVER_REGIST(driver, test_texteditor_insertcontext_11);
+       UNITTEST_DRIVER_REGIST(driver, test_texteditor_insertcontext_12);
+       UNITTEST_DRIVER_REGIST(driver, test_texteditor_insertcontext_13);
 }
index 710ad51..71565e8 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * texteditor_textfragment.c
  *
- * Copyright (c) 2013 project bchan
+ * Copyright (c) 2013-2014 project bchan
  *
  * This software is provided 'as-is', without any express or implied
  * warranty. In no event will the authors be held liable for any damages
@@ -29,6 +29,8 @@
 #include       <bstdio.h>
 
 #include       <tad/tadfragment.h>
+#include       "texteditor_characterstate.h"
+#include       "texteditor_insertfilter.h"
 
 #ifdef BCHAN_CONFIG_DEBUG
 # define DP(arg) printf arg
 # define DP_ER(msg, err) /**/
 #endif
 
+EXPORT UB* texteditor_textfragment_getbuffer(texteditor_textfragment_t *fragment)
+{
+       return tadfragment_getbuffer(&fragment->base);
+}
+
+EXPORT W texteditor_textfragment_getsegmentlength(texteditor_textfragment_t *fragment)
+{
+       return tadfragment_getsegmentlength(&fragment->base);
+}
+
+EXPORT W texteditor_textfragment_getbufferlength(texteditor_textfragment_t *fragment)
+{
+       return tadfragment_getbufferlength(&fragment->base);
+}
+
 EXPORT W texteditor_textfragment_initialize(texteditor_textfragment_t *fragment)
 {
        return tadfragment_initialize(&fragment->base);
@@ -47,3 +64,175 @@ EXPORT VOID texteditor_textfragment_finalize(texteditor_textfragment_t *fragment
 {
        tadfragment_finalize(&fragment->base);
 }
+
+/* texteditor_insertcontext */
+
+LOCAL W texteditor_insertcontext_bufferprepair(tadfragment_cursor_t *src, texteditor_characterstate_t *state, tadfragment_cursor_t *dest, W pos)
+{
+       W i, err;
+       tadfragment_cursor_segment segment;
+
+       i = 0;
+       for (; i < pos;) {
+               err = tadfragment_cursor_getdata(src, &segment);
+               if (err < 0) {
+                       break;
+               }
+               texteditor_charactorstate_input(state, &segment);
+
+               if (segment.type == TADFRAGMENT_CURSOR_SEGMENTTYPE_CHAR) {
+                       i++;
+               }
+
+               err = tadfragment_cursor_insert(dest, segment.p, segment.len);
+               if (err < 0) {
+                       break;
+               }
+
+               err = tadfragment_cursor_move(src, 1);
+               if (err < 0) {
+                       break;
+               }
+       }
+
+       if (i != pos) {
+               return -1;
+       }
+
+       return 0;
+}
+
+LOCAL W texteditor_insertcontext_bufferappend(texteditor_characterstate_t *state, tadlangcode *lang, Bool is_hankaku, UB *insert_data, W insert_len, tadfragment_cursor_t *dest)
+{
+       texteditor_insertfilter_t filter;
+       texteditor_insertfilter_result filter_result;
+       tadfragment_cursor_segment segment;
+       W err = 0;
+       Bool cont;
+
+       texteditor_insertfilter_initialize(&filter, lang, (is_hankaku != False) ? 0x0102 : 0x0101, insert_data, insert_len);
+       for (;;) {
+               cont = texteditor_insertfilter_next(&filter, &filter_result);
+               if (cont == False) {
+                       break;
+               }
+
+               err = tadfragment_cursor_insert(dest, filter_result.data, filter_result.len);
+               if (err < 0) {
+                       break;
+               }
+
+               tadfragment_cursor_getdata(dest, &segment);
+               texteditor_charactorstate_input(state, &segment);
+       }
+       texteditor_insertfilter_finalize(&filter);
+
+       return err;
+}
+
+LOCAL W texteditor_insertcontext_bufferafterappend(texteditor_characterstate_t *state, tadfragment_cursor_t *src, tadfragment_cursor_t *dest)
+{
+       tadfragment_cursor_segment segment;
+       W err = 0;
+       Bool is_end;
+
+       for (;;) {
+               is_end = tadfragment_cursor_isend(src);
+               if (is_end != False) {
+                       break;
+               }
+
+               err = tadfragment_cursor_getdata(src, &segment);
+               if (err < 0) {
+                       break;
+               }
+               texteditor_charactorstate_input(state, &segment);
+
+               err = tadfragment_cursor_insert(dest, segment.p, segment.len);
+               if (err < 0) {
+                       break;
+               }
+
+               err = tadfragment_cursor_move(src, 1);
+               if (err < 0) {
+                       break;
+               }
+       }
+
+       return err;
+}
+
+EXPORT W texteditor_insertcontext_insert(texteditor_insertcontext_t *ctx, UB *data, W len)
+{
+       tadlangcode lang;
+       Bool is_hankaku;
+
+       is_hankaku = texteditor_characterstate_ishankaku(&ctx->state);
+       texteditor_characterstate_getlangcode(&ctx->state, &lang);
+
+       return texteditor_insertcontext_bufferappend(&ctx->state, &lang, is_hankaku, data, len, &ctx->dest.cursor);
+}
+
+EXPORT W texteditor_insertcontext_initialize(texteditor_insertcontext_t *ctx, texteditor_textfragment_t *target, GID gid, W pos)
+{
+       W err;
+
+       ctx->target = target;
+       ctx->gid = gid;
+
+       tadfragment_cursor_initialize(&ctx->target_cursor, &ctx->target->base);
+       err = tadfragment_initialize(&ctx->dest.fragment);
+       if (err < 0) {
+               goto error_dest_fragment;
+       }
+       tadfragment_cursor_initialize(&ctx->dest.cursor, &ctx->dest.fragment);
+
+       texteditor_characterstate_initialize(&ctx->state);
+
+       err = texteditor_insertcontext_bufferprepair(&ctx->target_cursor, &ctx->state, &ctx->dest.cursor, pos);
+       if (err < 0) {
+               goto error_prepair;
+       }
+
+       ctx->pos_state.is_hankaku = texteditor_characterstate_ishankaku(&ctx->state);
+       texteditor_characterstate_getlangcode(&ctx->state, &ctx->pos_state.lang);
+
+       return 0;
+
+error_prepair:
+       texteditor_characterstate_finalize(&ctx->state);
+       tadfragment_cursor_finalize(&ctx->dest.cursor);
+       tadfragment_finalize(&ctx->dest.fragment);
+error_dest_fragment:
+       tadfragment_cursor_finalize(&ctx->target_cursor);
+
+       return err;
+}
+
+EXPORT W texteditor_insertcontext_finalize(texteditor_insertcontext_t *ctx)
+{
+       W len, err = 0;
+       UB *data;
+
+       err = texteditor_insertcontext_bufferafterappend(&ctx->state, &ctx->target_cursor, &ctx->dest.cursor);
+       if (err < 0) {
+               tadfragment_cursor_finalize(&ctx->dest.cursor);
+               tadfragment_cursor_finalize(&ctx->target_cursor);
+               goto finalize;
+       }
+
+       tadfragment_cursor_finalize(&ctx->dest.cursor);
+       tadfragment_cursor_finalize(&ctx->target_cursor);
+
+       tadfragment_truncate(&ctx->target->base, 0);
+       data = tadfragment_getbuffer(&ctx->dest.fragment);
+       len = tadfragment_getbufferlength(&ctx->dest.fragment);
+       err = tadfragment_pushback(&ctx->target->base, data, len);
+
+finalize:
+
+       texteditor_characterstate_finalize(&ctx->state);
+       tadfragment_finalize(&ctx->dest.fragment);
+
+       return err;
+}
index bfed670..af76ef4 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * texteditor_textfragment.h
  *
- * Copyright (c) 2013 project bchan
+ * Copyright (c) 2013-2014 project bchan
  *
  * This software is provided 'as-is', without any express or implied
  * warranty. In no event will the authors be held liable for any damages
@@ -27,6 +27,8 @@
 #include    <basic.h>
 
 #include       <tad/tadfragment.h>
+#include       "texteditor_characterstate.h"
+#include       "texteditor_insertfilter.h"
 
 #ifndef __TEXTEDITOR_TEXTFRAGMENT_H__
 #define __TEXTEDITOR_TEXTFRAGMENT_H__
 /* Detail name: textfragment */
 struct texteditor_textfragment_t_ {
        tadfragment_t base;
+       W *pos;
+       W pos_len;
 };
 typedef struct texteditor_textfragment_t_ texteditor_textfragment_t;
 
 IMPORT W texteditor_textfragment_initialize(texteditor_textfragment_t *fragment);
 IMPORT VOID texteditor_textfragment_finalize(texteditor_textfragment_t *fragment);
+IMPORT UB* texteditor_textfragment_getbuffer(texteditor_textfragment_t *fragment);
+IMPORT W texteditor_textfragment_getsegmentlength(texteditor_textfragment_t *fragment);
+IMPORT W texteditor_textfragment_getbufferlength(texteditor_textfragment_t *fragment);
+
+/* Functionality name: texteditor */
+/* Detail name: insertcontext */
+struct texteditor_insertcontext_t_ {
+       texteditor_textfragment_t *target;
+       tadfragment_cursor_t target_cursor;
+       struct {
+               tadfragment_t fragment;
+               tadfragment_cursor_t cursor;
+       } dest;
+       texteditor_characterstate_t state;
+       struct {
+               tadlangcode lang;
+               Bool is_hankaku;
+       } pos_state;
+       GID gid;
+};
+typedef struct texteditor_insertcontext_t_ texteditor_insertcontext_t;
+
+IMPORT W texteditor_insertcontext_initialize(texteditor_insertcontext_t *ctx, texteditor_textfragment_t *target, GID gid, W pos);
+IMPORT W texteditor_insertcontext_finalize(texteditor_insertcontext_t *ctx);
+IMPORT W texteditor_insertcontext_insert(texteditor_insertcontext_t *ctx, UB *data, W len);
 
 #endif