From 606d379a66e25eabbe9ab55edc3bdd21eaad5a76 Mon Sep 17 00:00:00 2001 From: ornse01 Date: Tue, 23 Sep 2014 16:50:00 +0000 Subject: [PATCH] implement filtering for TAD segments nesting. git-svn-id: http://svn.sourceforge.jp/svnroot/bchan/bchanf/trunk@630 20a0b8eb-f62a-4a12-8fe1-b598822500fb --- src/control/test_texteditor_stackfilter.c | 218 ++++++++++++++++++++++++++++++ src/control/texteditor_stackfilter.c | 109 +++++++++++++++ src/control/texteditor_stackfilter.h | 59 ++++++++ 3 files changed, 386 insertions(+) create mode 100644 src/control/test_texteditor_stackfilter.c create mode 100644 src/control/texteditor_stackfilter.c create mode 100644 src/control/texteditor_stackfilter.h diff --git a/src/control/test_texteditor_stackfilter.c b/src/control/test_texteditor_stackfilter.c new file mode 100644 index 0000000..e994c3a --- /dev/null +++ b/src/control/test_texteditor_stackfilter.c @@ -0,0 +1,218 @@ +/* + * test_texteditor_stackfilter.c + * + * Copyright (c) 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 + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source + * distribution. + * + */ + +#include "test_control.h" + +#include "texteditor_stackfilter.h" + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +typedef struct { + TC *src; + W src_len; + TC *expected; + W expected_len; +} test_texteditor_stackfilter_testdata_t; + +LOCAL UNITTEST_RESULT test_texteditor_stackfilter_common(test_texteditor_stackfilter_testdata_t *testdata) +{ + texteditor_stackfilter_t filter; + taddecoder_t decoder; + tadsegment segment, *filterd; + tadfragment_t fragment; + tadfragment_cursor_t cursor; + UB *buf; + Bool cont; + W input_result, err, len; + UNITTEST_RESULT result = UNITTEST_RESULT_PASS; + + err = tadfragment_initialize(&fragment); + if (err < 0) { + return UNITTEST_RESULT_FAIL; + } + + texteditor_stackfilter_initialize(&filter); + + taddecoder_initialize(&decoder, testdata->src, testdata->src_len); + + tadfragment_cursor_initialize(&cursor, &fragment); + for (;;) { + cont = taddecoder_next(&decoder, &segment); + if (cont == False) { + break; + } + input_result = texteditor_stackfilter_setinput(&filter, &segment); + if (input_result == TEXTEDITOR_STACKFILTER_SETINPUT_RESULT_FULL) { + for (;;) { + cont = texteditor_stackfilter_getoutput(&filter, &filterd); + if (cont == False) { + break; + } + tadfragment_cursor_insertsegment(&cursor, filterd); + } + input_result = texteditor_stackfilter_setinput(&filter, &segment); + } + if (input_result != TEXTEDITOR_STACKFILTER_SETINPUT_RESULT_OK) { + result = UNITTEST_RESULT_FAIL; + break; + } + } + for (;;) { + cont = texteditor_stackfilter_getoutput(&filter, &filterd); + if (cont == False) { + break; + } + tadfragment_cursor_insertsegment(&cursor, filterd); + } + tadfragment_cursor_finalize(&cursor); + + taddecoder_finalize(&decoder); + + texteditor_stackfilter_finalize(&filter); + + buf = tadfragment_getbuffer(&fragment); + len = tadfragment_getbufferlength(&fragment); + + if (len != testdata->expected_len * sizeof(TC)) { + printf("length error: expected = %d, result = %d\n", testdata->expected_len * sizeof(TC), len); + result = UNITTEST_RESULT_FAIL; + } else if (memcmp(buf, testdata->expected, len) != 0) { + printf("buffer error\n"); + result = UNITTEST_RESULT_FAIL; + } + + tadfragment_finalize(&fragment); + + return result; +} + +LOCAL UNITTEST_RESULT test_texteditor_stackfilter_1() +{ + TC src[] = (TC[]){ + 0xffe1, 0x0018, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0xff88, 0xff88, + 0x0021, 0x0000, 0x2422, 0xffa2, + 0x0006, 0x0300, 0x0101, 0x0101, + 0x2422, + }; + W src_len = 21; + TC expected[] = (TC[]){ + 0xffe1, 0x0018, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0xff88, 0xff88, + 0x0021, 0x0000, 0x2422, 0xffa2, + 0x0006, 0x0300, 0x0101, 0x0101, + 0x2422, + }; + W expected_len = 21; + test_texteditor_stackfilter_testdata_t testdata = { + src, src_len, expected, expected_len + }; + return test_texteditor_stackfilter_common(&testdata); +} + +LOCAL UNITTEST_RESULT test_texteditor_stackfilter_2() +{ + TC src[] = (TC[]){ + 0x2422, 0x2422, + }; + W src_len = 2; + TC expected[] = (TC[]){ + 0x2422, 0x2422, + }; + W expected_len = 2; + test_texteditor_stackfilter_testdata_t testdata = { + src, src_len, expected, expected_len + }; + return test_texteditor_stackfilter_common(&testdata); +} + +LOCAL UNITTEST_RESULT test_texteditor_stackfilter_3() +{ + TC src[] = (TC[]){ + 0x2422, + 0xffe3, 0x0018, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0xff88, 0xff88, + 0x0000, 0x0000, + 0xffb0, 0x0012, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, + 0xffe4, 0x0000, + 0x2422, + }; + W src_len = 29; + TC expected[] = (TC[]){ + 0x2422, 0x2422, + }; + W expected_len = 2; + test_texteditor_stackfilter_testdata_t testdata = { + src, src_len, expected, expected_len + }; + return test_texteditor_stackfilter_common(&testdata); +} + +LOCAL UNITTEST_RESULT test_texteditor_stackfilter_4() +{ + TC src[] = (TC[]){ + 0x2422, + 0xffe1, 0x0018, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0xff88, 0xff88, + 0x0021, 0x0000, + 0x2422, + 0xffe2, 0x0000, + 0x2422, + }; + W src_len = 19; + TC expected[] = (TC[]){ + 0x2422, 0x2422, + }; + W expected_len = 2; + test_texteditor_stackfilter_testdata_t testdata = { + src, src_len, expected, expected_len + }; + return test_texteditor_stackfilter_common(&testdata); +} + +EXPORT VOID test_texteditor_stackfilter_main(unittest_driver_t *driver) +{ + UNITTEST_DRIVER_REGIST(driver, test_texteditor_stackfilter_1); + UNITTEST_DRIVER_REGIST(driver, test_texteditor_stackfilter_2); + UNITTEST_DRIVER_REGIST(driver, test_texteditor_stackfilter_3); + UNITTEST_DRIVER_REGIST(driver, test_texteditor_stackfilter_4); +} diff --git a/src/control/texteditor_stackfilter.c b/src/control/texteditor_stackfilter.c new file mode 100644 index 0000000..e5d31c1 --- /dev/null +++ b/src/control/texteditor_stackfilter.c @@ -0,0 +1,109 @@ +/* + * texteditor_stackfilter.c + * + * Copyright (c) 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 + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source + * distribution. + * + */ + +#include "texteditor_stackfilter.h" + +#include + +#include +#include + +#ifdef BCHAN_CONFIG_DEBUG +# define DP(arg) printf arg +# define DP_ER(msg, err) printf("%s (%d/%x)\n", msg, err>>16, err) +#else +# define DP(arg) /**/ +# define DP_ER(msg, err) /**/ +#endif + +IMPORT W texteditor_stackfilter_setinput(texteditor_stackfilter_t *filter, tadsegment *segment) +{ + W nestlevel, err; + TADSTACK_DATATYPE type; + TADSTACK_RESULT result; + + if (filter->state == TEXTEDITOR_STACKFILTER_STATE_HAS_RESULT) { + return TEXTEDITOR_STACKFILTER_SETINPUT_RESULT_FULL; + } + + result = tadstack_inputsegment(&filter->tadstack, segment); + + nestlevel = tadstack_nestlevel(&filter->tadstack); + if (nestlevel < 0) { + return TEXTEDITOR_STACKFILTER_SETINPUT_RESULT_FORMAT_ERROR; + } + if (nestlevel > 0) { + return TEXTEDITOR_STACKFILTER_SETINPUT_RESULT_OK; + } + if (result == TADSTACK_RESULT_POP_STACK) { + return TEXTEDITOR_STACKFILTER_SETINPUT_RESULT_OK; + } + err = tadstack_currentdata(&filter->tadstack, &type); + if (err < 0) { + return TEXTEDITOR_STACKFILTER_SETINPUT_RESULT_FORMAT_ERROR; + } + if (type != TADSTACK_DATATYPE_TEXT) { + return TEXTEDITOR_STACKFILTER_SETINPUT_RESULT_OK; + } + + filter->state = TEXTEDITOR_STACKFILTER_STATE_HAS_RESULT; + filter->result_buffer.segs[0] = *segment; + filter->result_buffer.used = 1; + filter->result_buffer.consumed = 0; + + return TEXTEDITOR_STACKFILTER_SETINPUT_RESULT_OK; +} + +IMPORT Bool texteditor_stackfilter_getoutput(texteditor_stackfilter_t *filter, tadsegment **segment) +{ + if (filter->state == TEXTEDITOR_STACKFILTER_STATE_WAIT_INPUT) { + return False; + } + + *segment = filter->result_buffer.segs + filter->result_buffer.consumed; + filter->result_buffer.consumed++; + + if (filter->result_buffer.consumed >= filter->result_buffer.used) { + filter->result_buffer.used = 0; + filter->result_buffer.consumed = 0; + filter->state = TEXTEDITOR_STACKFILTER_STATE_WAIT_INPUT; + } + + return True; +} + +IMPORT VOID texteditor_stackfilter_initialize(texteditor_stackfilter_t *filter) +{ + tadstack_initialize(&filter->tadstack); + filter->state = TEXTEDITOR_STACKFILTER_STATE_WAIT_INPUT; + filter->result_buffer.used = 0; + filter->result_buffer.consumed = 0; +} + +IMPORT VOID texteditor_stackfilter_finalize(texteditor_stackfilter_t *filter) +{ + tadstack_finalize(&filter->tadstack); +} diff --git a/src/control/texteditor_stackfilter.h b/src/control/texteditor_stackfilter.h new file mode 100644 index 0000000..d9ea556 --- /dev/null +++ b/src/control/texteditor_stackfilter.h @@ -0,0 +1,59 @@ +/* + * texteditor_stackfilter.h + * + * Copyright (c) 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 + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source + * distribution. + * + */ + +#include + +#include +#include + +#ifndef __TEXTEDITOR_STACKFILTER_H__ +#define __TEXTEDITOR_STACKFILTER_H__ + +/* Functionality name: texteditor */ +/* Detail name: stackfilter */ +struct texteditor_stackfilter_t_ { + enum { + TEXTEDITOR_STACKFILTER_STATE_WAIT_INPUT, + TEXTEDITOR_STACKFILTER_STATE_HAS_RESULT, + } state; + tadstack_t tadstack; + struct { + tadsegment segs[1]; + W used; + W consumed; + } result_buffer; +}; +typedef struct texteditor_stackfilter_t_ texteditor_stackfilter_t; + +IMPORT VOID texteditor_stackfilter_initialize(texteditor_stackfilter_t *filter); +IMPORT VOID texteditor_stackfilter_finalize(texteditor_stackfilter_t *filter); +IMPORT W texteditor_stackfilter_setinput(texteditor_stackfilter_t *filter, tadsegment *segment); +#define TEXTEDITOR_STACKFILTER_SETINPUT_RESULT_OK (0) +#define TEXTEDITOR_STACKFILTER_SETINPUT_RESULT_FULL (1) +#define TEXTEDITOR_STACKFILTER_SETINPUT_RESULT_FORMAT_ERROR (-1) +IMPORT Bool texteditor_stackfilter_getoutput(texteditor_stackfilter_t *filter, tadsegment **segment); + +#endif -- 2.11.0