/*
* 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
#include <bstdio.h>
#include <bstdlib.h>
#include <bstring.h>
+#include <tcode.h>
#include <unittest_driver.h>
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);
}
/*
* 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
#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);
{
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;
+}