OSDN Git Service

implement filtering for TAD segments nesting.
authorornse01 <ornse01@users.sourceforge.jp>
Tue, 23 Sep 2014 16:50:00 +0000 (16:50 +0000)
committerornse01 <ornse01@users.sourceforge.jp>
Tue, 23 Sep 2014 16:50:00 +0000 (16:50 +0000)
git-svn-id: http://svn.sourceforge.jp/svnroot/bchan/bchanf/trunk@630 20a0b8eb-f62a-4a12-8fe1-b598822500fb

src/control/test_texteditor_stackfilter.c [new file with mode: 0644]
src/control/texteditor_stackfilter.c [new file with mode: 0644]
src/control/texteditor_stackfilter.h [new file with mode: 0644]

diff --git a/src/control/test_texteditor_stackfilter.c b/src/control/test_texteditor_stackfilter.c
new file mode 100644 (file)
index 0000000..e994c3a
--- /dev/null
@@ -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       <basic.h>
+#include       <bstdio.h>
+#include       <bstdlib.h>
+#include       <bstring.h>
+#include       <tstring.h>
+#include       <tcode.h>
+
+#include    <tad/taddecoder.h>
+#include    <tad/tadfragment.h>
+
+#include    <unittest_driver.h>
+
+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 (file)
index 0000000..e5d31c1
--- /dev/null
@@ -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       <bstdio.h>
+
+#include       <tad/tadsegment.h>
+#include       <tad/tadlangcode.h>
+
+#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 (file)
index 0000000..d9ea556
--- /dev/null
@@ -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    <basic.h>
+
+#include       <tad/tadsegment.h>
+#include       <tad/tadstack.h>
+
+#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