OSDN Git Service

implement iterator for traydata handling.
authorornse01 <ornse01@users.sourceforge.jp>
Sun, 10 Jun 2012 10:29:20 +0000 (10:29 +0000)
committerornse01 <ornse01@users.sourceforge.jp>
Sun, 10 Jun 2012 10:29:20 +0000 (10:29 +0000)
git-svn-id: http://svn.sourceforge.jp/svnroot/bchan/bchanf/trunk@487 20a0b8eb-f62a-4a12-8fe1-b598822500fb

src/tad/test_traydata_iterator.c [new file with mode: 0644]
src/tad/traydata_iterator.c [new file with mode: 0644]
src/tad/traydata_iterator.h [new file with mode: 0644]

diff --git a/src/tad/test_traydata_iterator.c b/src/tad/test_traydata_iterator.c
new file mode 100644 (file)
index 0000000..1571dc1
--- /dev/null
@@ -0,0 +1,276 @@
+/*
+ * test_tadlexer_le.c
+ *
+ * Copyright (c) 2012 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_tad.h"
+
+#include "traydata_iterator.h"
+
+#include       <basic.h>
+#include       <bstdio.h>
+#include       <bstdlib.h>
+#include       <bstring.h>
+
+#include    <unittest_driver.h>
+
+LOCAL UB test_traydata_testdata01[] = {
+       0xe0, 0xff, 0x06, 0x00, 0x00, 0x00, 0x02, 0x00,
+       0x22, 0x01, 0xe1, 0xff, 0x18, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0xff,
+       0x88, 0xff, 0x21, 0x00, 0x00, 0x00, 0xa0, 0xff,
+       0x0e, 0x00, 0x00, 0x00, 0x7b, 0x05, 0xe0, 0x03,
+       0x5e, 0x00, 0x46, 0x00, 0x6c, 0x00, 0x55, 0x00,
+       0xa0, 0xff, 0x0a, 0x00, 0x00, 0x01, 0x5e, 0x00,
+       0x76, 0x00, 0x6c, 0x00, 0x55, 0x00, 0xa0, 0xff,
+       0x22, 0x00, 0x00, 0x03, 0xa0, 0xff, 0x02, 0x00,
+       0x00, 0x08, 0xa1, 0xff, 0x04, 0x00, 0x00, 0x00,
+       0x00, 0x80, 0xa1, 0xff, 0x02, 0x00, 0x01, 0x01,
+       0x5d, 0x21, 0xad, 0xff, 0x04, 0x00, 0x00, 0x00,
+       0xc8, 0x00, 0x5d, 0x21, 0xa0, 0xff, 0x04, 0x00,
+       0x00, 0x04, 0x00, 0x80, 0xa4, 0xff, 0x24, 0x00,
+       0x11, 0x08, 0x22, 0x21, 0x23, 0x21, 0x24, 0x21,
+       0x25, 0x21, 0x2b, 0x21, 0x2c, 0x21, 0x47, 0x21,
+       0x49, 0x21, 0x4b, 0x21, 0x4d, 0x21, 0x4f, 0x21,
+       0x51, 0x21, 0x53, 0x21, 0x55, 0x21, 0x57, 0x21,
+       0x59, 0x21, 0x5b, 0x21, 0xa4, 0xff, 0x18, 0x00,
+       0x11, 0x09, 0x46, 0x21, 0x48, 0x21, 0x4a, 0x21,
+       0x4c, 0x21, 0x4e, 0x21, 0x50, 0x21, 0x52, 0x21,
+       0x54, 0x21, 0x56, 0x21, 0x58, 0x21, 0x5a, 0x21,
+       0xa1, 0xff, 0x24, 0x00, 0x00, 0x02, 0x04, 0x01,
+       0x04, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x0b, 0x00, 0x48, 0x00, 0x90, 0x00, 0xd8, 0x00,
+       0x20, 0x01, 0x68, 0x01, 0xb0, 0x01, 0xf8, 0x01,
+       0x40, 0x02, 0x88, 0x02, 0xd0, 0x02, 0x18, 0x03,
+       0xa1, 0xff, 0x04, 0x00, 0x01, 0x00, 0x04, 0x01,
+       0x46, 0x23, 0x52, 0x23, 0x4f, 0x23, 0x4d, 0x23,
+       0x27, 0x21, 0x21, 0x21, 0x6e, 0x23, 0x61, 0x23,
+       0x6d, 0x23, 0x65, 0x23, 0x0a, 0x00, 0x6d, 0x23,
+       0x61, 0x23, 0x69, 0x23, 0x6c, 0x23, 0x27, 0x21,
+       0x21, 0x21, 0x6d, 0x23, 0x61, 0x23, 0x69, 0x23,
+       0x6c, 0x23, 0x0a, 0x00, 0x0a, 0x00, 0x62, 0x23,
+       0x6f, 0x23, 0x64, 0x23, 0x79, 0x23, 0xe2, 0xff,
+       0x00, 0x00,
+};
+
+typedef struct {
+       enum {
+               TEST_TRAYDATA_ITERATOR_CH,
+               TEST_TRAYDATA_ITERATOR_SEGMENT,
+               TEST_TRAYDATA_ITERATOR_VOBJ
+       } type;
+       TC ch;
+       UB segid;
+       W len;
+} test_traydata_iterator_expected_t;
+
+LOCAL test_traydata_iterator_expected_t test_traydata_expected01[] = {
+       {TEST_TRAYDATA_ITERATOR_SEGMENT, 0, 0xe0, 6},
+       {TEST_TRAYDATA_ITERATOR_SEGMENT, 0, 0xe1, 24},
+       {TEST_TRAYDATA_ITERATOR_SEGMENT, 0, 0xa0, 14},
+       {TEST_TRAYDATA_ITERATOR_SEGMENT, 0, 0xa0, 10},
+       {TEST_TRAYDATA_ITERATOR_SEGMENT, 0, 0xa0, 34},
+       {TEST_TRAYDATA_ITERATOR_SEGMENT, 0, 0xa0, 4},
+       {TEST_TRAYDATA_ITERATOR_SEGMENT, 0, 0xa4, 36},
+       {TEST_TRAYDATA_ITERATOR_SEGMENT, 0, 0xa4, 24},
+       {TEST_TRAYDATA_ITERATOR_SEGMENT, 0, 0xa1, 36},
+       {TEST_TRAYDATA_ITERATOR_SEGMENT, 0, 0xa1, 4},
+       {TEST_TRAYDATA_ITERATOR_CH, 0x2346, 0, 0},
+       {TEST_TRAYDATA_ITERATOR_CH, 0x2352, 0, 0},
+       {TEST_TRAYDATA_ITERATOR_CH, 0x234f, 0, 0},
+       {TEST_TRAYDATA_ITERATOR_CH, 0x234d, 0, 0},
+       {TEST_TRAYDATA_ITERATOR_CH, 0x2127, 0, 0},
+       {TEST_TRAYDATA_ITERATOR_CH, 0x2121, 0, 0},
+       {TEST_TRAYDATA_ITERATOR_CH, 0x236e, 0, 0},
+       {TEST_TRAYDATA_ITERATOR_CH, 0x2361, 0, 0},
+       {TEST_TRAYDATA_ITERATOR_CH, 0x236d, 0, 0},
+       {TEST_TRAYDATA_ITERATOR_CH, 0x2365, 0, 0},
+       {TEST_TRAYDATA_ITERATOR_CH, 0x000a, 0, 0},
+       {TEST_TRAYDATA_ITERATOR_CH, 0x236d, 0, 0},
+       {TEST_TRAYDATA_ITERATOR_CH, 0x2361, 0, 0},
+       {TEST_TRAYDATA_ITERATOR_CH, 0x2369, 0, 0},
+       {TEST_TRAYDATA_ITERATOR_CH, 0x236c, 0, 0},
+       {TEST_TRAYDATA_ITERATOR_CH, 0x2127, 0, 0},
+       {TEST_TRAYDATA_ITERATOR_CH, 0x2121, 0, 0},
+       {TEST_TRAYDATA_ITERATOR_CH, 0x236d, 0, 0},
+       {TEST_TRAYDATA_ITERATOR_CH, 0x2361, 0, 0},
+       {TEST_TRAYDATA_ITERATOR_CH, 0x2369, 0, 0},
+       {TEST_TRAYDATA_ITERATOR_CH, 0x236c, 0, 0},
+       {TEST_TRAYDATA_ITERATOR_CH, 0x000a, 0, 0},
+       {TEST_TRAYDATA_ITERATOR_CH, 0x000a, 0, 0},
+       {TEST_TRAYDATA_ITERATOR_CH, 0x2362, 0, 0},
+       {TEST_TRAYDATA_ITERATOR_CH, 0x236f, 0, 0},
+       {TEST_TRAYDATA_ITERATOR_CH, 0x2364, 0, 0},
+       {TEST_TRAYDATA_ITERATOR_CH, 0x2379, 0, 0},
+       {TEST_TRAYDATA_ITERATOR_SEGMENT, 0, 0xe2, 0},
+};
+
+LOCAL UNITTEST_RESULT test_traydata_iterator_common(TRAYREC *rec, W len, test_traydata_iterator_expected_t *expected, W expected_len)
+{
+       traydata_iterator_t iter;
+       traydata_iterator_result result;
+       Bool cont;
+       UNITTEST_RESULT ret = UNITTEST_RESULT_PASS;
+       W j, sz = 0;
+
+       traydata_iterator_initialize(&iter, rec, len);
+
+       j = 0;
+       for (;;) {
+               cont = traydata_iterator_next(&iter, &result);
+               if (cont == False) {
+                       break;
+               }
+               if (result.type == TRAYDATA_ITERATOR_RESULTTYPE_FIXED_SEGMENT) {
+                       if (j < expected_len) {
+                               if (expected[j].type == TEST_TRAYDATA_ITERATOR_CH) {
+                                       if (expected[j].ch != result.val.ch) {
+                                               printf("character is not expected: expected %04x, result %04x\n", expected[j].ch, result.val.ch);
+                                               ret = UNITTEST_RESULT_FAIL;
+                                       }
+                               } else {
+                                       printf("segment type is not expected: expected ch\n");
+                                       ret = UNITTEST_RESULT_FAIL;
+                               }
+                       } else {
+                               ret = UNITTEST_RESULT_FAIL;
+                       }
+                       j++;
+               } else if (result.type == TRAYDATA_ITERATOR_RESULTTYPE_VARIABLE_SEGMENT_CONT) {
+                       if (j < expected_len) {
+                               if (expected[j].type == TEST_TRAYDATA_ITERATOR_SEGMENT) {
+                                       if (expected[j].segid != result.val.seg.id) {
+                                               printf("devided segment id is not expected: expected = %02x, result = %02x\n", expected[j].segid, result.val.seg.id);
+                                               ret = UNITTEST_RESULT_FAIL;
+                                       }
+                               } else {
+                                       printf("segment type is not expected: expected segment\n");
+                                       ret = UNITTEST_RESULT_FAIL;
+                               }
+                       } else {
+                               ret = UNITTEST_RESULT_FAIL;
+                       }
+                       sz += result.val.seg.chunk_data_len;
+               } else if (result.type == TRAYDATA_ITERATOR_RESULTTYPE_VARIABLE_SEGMENT) {
+                       sz += result.val.seg.chunk_data_len;
+                       if (j < expected_len) {
+                               if (expected[j].type == TEST_TRAYDATA_ITERATOR_SEGMENT) {
+                                       if (expected[j].segid != result.val.seg.id) {
+                                               printf("segment id is not expected: expected = %02x, result = %02x\n", expected[j].segid, result.val.seg.id);
+                                               ret = UNITTEST_RESULT_FAIL;
+                                       }
+                                       if (expected[j].len != sz) {
+                                               printf("segment size is not expected: expected = %d, result = %d(%d)\n", expected[j].len, result.val.seg.seglen, sz);
+                                               ret = UNITTEST_RESULT_FAIL;
+                                       }
+                               } else {
+                                       printf("segment type is not expected: expected segment\n");
+                                       ret = UNITTEST_RESULT_FAIL;
+                               }
+                       } else {
+                               ret = UNITTEST_RESULT_FAIL;
+                       }
+                       j++;
+                       sz = 0;
+               } else if (result.type == TRAYDATA_ITERATOR_RESULTTYPE_VOBJREC) {
+                       if (j < expected_len) {
+                               if (expected[j].type == TEST_TRAYDATA_ITERATOR_VOBJ) {
+                               } else {
+                                       printf("segment type is not expected: expected vobj\n");
+                                       ret = UNITTEST_RESULT_FAIL;
+                               }
+                       } else {
+                               ret = UNITTEST_RESULT_FAIL;
+                       }
+                       j++;
+               } else if (result.type == TRAYDATA_ITERATOR_RESULTTYPE_END) {
+                       break;
+               }
+       }
+
+       traydata_iterator_finalize(&iter);
+
+       if (j != expected_len) {
+               printf("segument number is not expected: len = %d, expected = %d\n", j, expected_len);
+               ret = UNITTEST_RESULT_FAIL;
+       }
+
+       return ret;
+}
+
+LOCAL UNITTEST_RESULT test_traydata_1()
+{
+       TRAYREC rec[] = {
+               {TS_INFO, 6, test_traydata_testdata01+4},
+               {TR_TEXT, sizeof(test_traydata_testdata01) - 10, test_traydata_testdata01+10},
+       };
+       W len = sizeof(rec)/sizeof(TRAYREC);
+       test_traydata_iterator_expected_t *expected = test_traydata_expected01;
+       W expected_len = sizeof(test_traydata_expected01)/sizeof(test_traydata_iterator_expected_t);
+       return test_traydata_iterator_common(rec, len, expected, expected_len);
+}
+
+LOCAL UNITTEST_RESULT test_traydata_2()
+{
+       TRAYREC rec[] = {
+               {TS_INFO, 6, test_traydata_testdata01+4},
+               {TR_TEXT|TR_CONT, 100, test_traydata_testdata01+10},
+               {TR_TEXT, sizeof(test_traydata_testdata01) - 10 - 100, test_traydata_testdata01+10 + 100},
+       };
+       W len = sizeof(rec)/sizeof(TRAYREC);
+       test_traydata_iterator_expected_t *expected = test_traydata_expected01;
+       W expected_len = sizeof(test_traydata_expected01)/sizeof(test_traydata_iterator_expected_t);
+       return test_traydata_iterator_common(rec, len, expected, expected_len);
+}
+
+LOCAL UNITTEST_RESULT test_traydata_3()
+{
+       TRAYREC rec[] = {
+               {TS_INFO, 6, test_traydata_testdata01+4},
+               {TR_TEXT|TR_CONT, 100, test_traydata_testdata01+10},
+               {TR_TEXT|TR_CONT, 1, test_traydata_testdata01+10+100},
+               {TR_TEXT|TR_CONT, 1, test_traydata_testdata01+10+100+1},
+               {TR_TEXT|TR_CONT, 1, test_traydata_testdata01+10+100+2},
+               {TR_TEXT|TR_CONT, 1, test_traydata_testdata01+10+100+3},
+               {TR_TEXT|TR_CONT, 1, test_traydata_testdata01+10+100+4},
+               {TR_TEXT|TR_CONT, 1, test_traydata_testdata01+10+100+5},
+               {TR_TEXT|TR_CONT, 1, test_traydata_testdata01+10+100+6},
+               {TR_TEXT|TR_CONT, 1, test_traydata_testdata01+10+100+7},
+               {TR_TEXT|TR_CONT, 1, test_traydata_testdata01+10+100+8},
+               {TR_TEXT|TR_CONT, 1, test_traydata_testdata01+10+100+9},
+               {TR_TEXT, sizeof(test_traydata_testdata01) - 10 - 100 - 10, test_traydata_testdata01+10 + 100 + 10},
+       };
+       W len = sizeof(rec)/sizeof(TRAYREC);
+       test_traydata_iterator_expected_t *expected = test_traydata_expected01;
+       W expected_len = sizeof(test_traydata_expected01)/sizeof(test_traydata_iterator_expected_t);
+       return test_traydata_iterator_common(rec, len, expected, expected_len);
+}
+
+EXPORT VOID test_traydata_iterator_main(unittest_driver_t *driver)
+{
+       UNITTEST_DRIVER_REGIST(driver, test_traydata_1);
+       UNITTEST_DRIVER_REGIST(driver, test_traydata_2);
+       UNITTEST_DRIVER_REGIST(driver, test_traydata_3);
+}
diff --git a/src/tad/traydata_iterator.c b/src/tad/traydata_iterator.c
new file mode 100644 (file)
index 0000000..54e0ff7
--- /dev/null
@@ -0,0 +1,270 @@
+/*
+ * traydata_iterator.c
+ *
+ * Copyright (c) 2012 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 "traydata_iterator.h"
+
+#include       <basic.h>
+#include       <stdio.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
+
+#if 0
+# define DP_STATE(state) printf("%s\n", state)
+#else
+# define DP_STATE(state) /**/
+#endif
+
+/* return; -1:error, 0:continue, 1:break, 2:break increment */
+LOCAL W traydata_iterator_inputTRAYREC(traydata_iterator_t *iterator, TRAYREC *rec, traydata_iterator_result *result)
+{
+       W i, lex_result_len, ret = -1;
+       tadlexer_le_result *lex_result;
+       UB ch;
+       Bool ok, vseg, segend, fixed, segdata;
+
+       switch (iterator->state) {
+       case TRAYDATA_ITERATOR_STATE_REC_START:
+               DP_STATE("TRAYDATA_ITERATOR_STATE_REC_START");
+               if ((rec->id == TR_TEXT)||(rec->id == TR_FIG)||(rec->id == (TR_TEXT|TR_CONT))||(rec->id == (TR_FIG|TR_CONT))) {
+                       iterator->state = TRAYDATA_ITERATOR_STATE_REC_UNITE;
+                       iterator->status.unite.id = rec->id & 0xFF;
+                       tadlexer_le_initialize(&iterator->status.unite.lexer);
+                       iterator->status.unite.rec_read_len = 0;
+               } else if (rec->id == TR_VOBJ) {
+                       if (rec->len != sizeof(TR_VOBJREC)) {
+                               break;
+                       }
+                       memcpy(&result->val.vobjrec, rec->dt, sizeof(TR_VOBJREC));
+                       ret = 2;
+                       break;
+               } else if (rec->id == (TR_VOBJ|TR_CONT)) {
+                       memcpy((UB*)&result->val.vobjrec, rec->dt, rec->len);
+                       iterator->status.devide_vobj.read_len = rec->len;
+                       ret = 0;
+                       iterator->state = TRAYDATA_ITERATOR_STATE_REC_VOBJ_DEVIDE;
+                       break;
+               } else if ((rec->id & TR_CONT) != 0) {
+                       iterator->state = TRAYDATA_ITERATOR_STATE_REC_DEVIDE;
+                       result->type = TRAYDATA_ITERATOR_RESULTTYPE_VARIABLE_SEGMENT_CONT;
+                       result->val.seg.id = rec->id;
+                       result->val.seg.seglen = rec->len;
+                       result->val.seg.chunk_data = rec->dt;
+                       result->val.seg.chunk_data_len = rec->len;
+                       ret = 2;
+                       break;
+               } else {
+                       result->type = TRAYDATA_ITERATOR_RESULTTYPE_VARIABLE_SEGMENT;
+                       result->val.seg.id = rec->id;
+                       result->val.seg.seglen = rec->len;
+                       result->val.seg.chunk_data = rec->dt;
+                       result->val.seg.chunk_data_len = rec->len;
+                       ret = 2;
+                       break;
+               }
+               /* intentional */
+       case TRAYDATA_ITERATOR_STATE_REC_UNITE:
+               DP_STATE("TRAYDATA_ITERATOR_STATE_REC_UNITE");
+               i = iterator->status.unite.rec_read_len;
+               vseg = False;
+               fixed = False;
+               for (;i < rec->len;) {
+                       ch = rec->dt[i];
+                       i++;
+                       tadlexer_le_inputbyte(&iterator->status.unite.lexer, ch, &lex_result, &lex_result_len);
+                       ok = tadlexer_le_result_is_fixedsegment(lex_result);
+                       if (ok != False) {
+                               fixed = True;
+                               break;
+                       }
+                       ok = tadlexer_le_result_is_variablesegment(lex_result);
+                       if (ok != False) {
+                               vseg = True;
+                               break;
+                       }
+               }
+               iterator->status.unite.rec_read_len = i;
+               if (vseg != False) {
+                       iterator->state = TRAYDATA_ITERATOR_STATE_REC_UNITE_VSEG_INFO;
+               } else if (fixed != False) {
+                       result->type = TRAYDATA_ITERATOR_RESULTTYPE_FIXED_SEGMENT;
+                       result->val.ch = lex_result->val.ch;
+                       ret = 1;
+                       break;
+               } else if (i == rec->len) {
+                       iterator->status.unite.rec_read_len = 0;
+                       if (iterator->status.unite.id == rec->id) {
+                               iterator->state = TRAYDATA_ITERATOR_STATE_REC_START;
+                               tadlexer_le_finalize(&iterator->status.unite.lexer);
+                       }
+                       ret = 0;
+                       break;
+               } else {
+                       DP(("error condition\n"));
+               }
+               /* intentional */
+       case TRAYDATA_ITERATOR_STATE_REC_UNITE_VSEG_INFO:
+               DP_STATE("TRAYDATA_ITERATOR_STATE_REC_UNITE_VSEG_INFO");
+               i = iterator->status.unite.rec_read_len;
+               segend = False;
+               segdata = False;
+               for (;i < rec->len;) {
+                       ch = rec->dt[i];
+                       i++;
+                       tadlexer_le_inputbyte(&iterator->status.unite.lexer, ch, &lex_result, &lex_result_len);
+                       if (lex_result->type == TADLEXER_LE_RESULTTYPE_SEGMENT_END) {
+                               segend = True;
+                               break;
+                       }
+                       ok = tadlexer_le_result_is_lengthdetermined(lex_result);
+                       if (ok != False) {
+                               segdata = True;
+                               break;
+                       }
+               }
+               iterator->status.unite.rec_read_len = i;
+               if (segend != False) {
+                       iterator->state = TRAYDATA_ITERATOR_STATE_REC_UNITE;
+                       result->type = TRAYDATA_ITERATOR_RESULTTYPE_VARIABLE_SEGMENT;
+                       result->val.seg.id = lex_result->val.seg.id;
+                       result->val.seg.seglen = lex_result->val.seg.len;
+                       result->val.seg.chunk_data = NULL;
+                       result->val.seg.chunk_data_len = 0;
+                       ret = 1;
+                       break;
+               } else if (segdata != False) {
+                       iterator->state = TRAYDATA_ITERATOR_STATE_REC_UNITE_VSEG_DATA;
+               } else if (i == rec->len) {
+                       if (iterator->status.unite.id == rec->id) {
+                               iterator->state = TRAYDATA_ITERATOR_STATE_REC_START;
+                               tadlexer_le_finalize(&iterator->status.unite.lexer);
+                       }
+                       iterator->status.unite.rec_read_len = 0;
+                       ret = 0;
+                       break;
+               } else {
+                       DP(("error condition\n"));
+               }
+               /* intentional */
+       case TRAYDATA_ITERATOR_STATE_REC_UNITE_VSEG_DATA:
+               DP_STATE("TRAYDATA_ITERATOR_STATE_REC_UNITE_VSEG_DATA");
+               i = iterator->status.unite.rec_read_len;
+               result->val.seg.chunk_data = rec->dt + i;
+               for (;i < rec->len;) {
+                       ch = rec->dt[i];
+                       i++;
+                       tadlexer_le_inputbyte(&iterator->status.unite.lexer, ch, &lex_result, &lex_result_len);
+                       if (lex_result->type == TADLEXER_LE_RESULTTYPE_SEGMENT_END) {
+                               break;
+                       }
+               }
+               if (lex_result->type == TADLEXER_LE_RESULTTYPE_SEGMENT_END) {
+                       if (rec->len == i) {
+                               iterator->state = TRAYDATA_ITERATOR_STATE_REC_START;
+                       } else {
+                               iterator->state = TRAYDATA_ITERATOR_STATE_REC_UNITE;
+                       }
+                       result->type = TRAYDATA_ITERATOR_RESULTTYPE_VARIABLE_SEGMENT;
+               } else {
+                       result->type = TRAYDATA_ITERATOR_RESULTTYPE_VARIABLE_SEGMENT_CONT;
+               }
+               result->val.seg.id = lex_result->val.seg.id;
+               result->val.seg.seglen = lex_result->val.seg.len;
+               result->val.seg.chunk_data_len = i - iterator->status.unite.rec_read_len;
+               if (rec->len == i) {
+                       iterator->status.unite.rec_read_len = 0;
+                       ret = 2;
+               } else {
+                       iterator->status.unite.rec_read_len = i;
+                       ret = 1;
+               }
+               break;
+       case TRAYDATA_ITERATOR_STATE_REC_VOBJ_DEVIDE:
+               DP_STATE("TRAYDATA_ITERATOR_STATE_REC_VOBJ_DEVIDE");
+               if (iterator->status.devide_vobj.read_len + rec->len <= sizeof(TR_VOBJREC)) {
+                       memcpy(((UB*)&result->val.vobjrec) + iterator->status.devide_vobj.read_len, rec->dt, rec->len);
+                       ret = 0;
+               } else {
+                       ret = -1;
+               }
+               iterator->status.devide_vobj.read_len = rec->len;
+               iterator->state = TRAYDATA_ITERATOR_STATE_REC_VOBJ_DEVIDE;
+               break;
+       case TRAYDATA_ITERATOR_STATE_REC_DEVIDE:
+               DP_STATE("TRAYDATA_ITERATOR_STATE_REC_DEVIDE");
+               if (rec->id == iterator->status.devide.id) {
+                       result->type = TRAYDATA_ITERATOR_RESULTTYPE_VARIABLE_SEGMENT;
+               } else {
+                       result->type = TRAYDATA_ITERATOR_RESULTTYPE_VARIABLE_SEGMENT_CONT;
+               }
+               result->val.seg.id = iterator->status.devide.id;
+               result->val.seg.seglen = -1; /* TODO */
+               result->val.seg.chunk_data = rec->dt;
+               result->val.seg.chunk_data_len = rec->len;
+               ret = 1;
+               break;
+       }
+
+       return ret;
+}
+
+EXPORT Bool traydata_iterator_next(traydata_iterator_t *iterator, traydata_iterator_result *result)
+{
+       TRAYREC *rec;
+       W ret;
+
+       for (; iterator->i_rec < iterator->recnum; iterator->i_rec++) {
+               rec = iterator->rec + iterator->i_rec;
+               ret = traydata_iterator_inputTRAYREC(iterator, rec, result);
+               if (ret < 0) {
+                       return False; /* TODO: error*/
+               } else if (ret == 1) {
+                       return True;
+               } else if (ret == 2) {
+                       iterator->i_rec++;
+                       return True;
+               }
+       }
+
+       return False;
+}
+
+EXPORT VOID traydata_iterator_initialize(traydata_iterator_t *iterator, TRAYREC *rec, W recnum)
+{
+       iterator->state = TRAYDATA_ITERATOR_STATE_REC_START;
+       iterator->rec = rec;
+       iterator->recnum = recnum;
+       iterator->i_rec = 0;
+}
+
+EXPORT VOID traydata_iterator_finalize(traydata_iterator_t *iterator)
+{
+}
diff --git a/src/tad/traydata_iterator.h b/src/tad/traydata_iterator.h
new file mode 100644 (file)
index 0000000..cd1be30
--- /dev/null
@@ -0,0 +1,99 @@
+/*
+ * traydata_iterator.h
+ *
+ * Copyright (c) 2012 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.
+ *
+ */
+
+/* Vendor name: */
+/* Functionality name: traydata */
+/* Detail name: iterator */
+
+#include    <basic.h>
+#include    <btron/hmi.h>
+
+#include    "tadlexer_le.h"
+
+#ifndef __TRAYDATA_ITERATOR_H__
+#define __TRAYDATA_ITERATOR_H__
+
+/* Functionality name: traydata */
+/* Detail name: iterator */
+struct traydata_iterator_t_ {
+       enum {
+               TRAYDATA_ITERATOR_STATE_REC_START,
+               TRAYDATA_ITERATOR_STATE_REC_UNITE,
+               TRAYDATA_ITERATOR_STATE_REC_UNITE_VSEG_INFO,
+               TRAYDATA_ITERATOR_STATE_REC_UNITE_VSEG_DATA,
+               TRAYDATA_ITERATOR_STATE_REC_VOBJ_DEVIDE,
+               TRAYDATA_ITERATOR_STATE_REC_DEVIDE,
+       } state;
+       TRAYREC *rec;
+       W recnum;
+       W i_rec;
+       union {
+               struct {
+                       W id;
+                       tadlexer_le_t lexer;
+                       W rec_read_len;
+               } unite;
+               struct {
+                       W read_len;
+                       UW whole_len;
+               } devide_vobj;
+               struct {
+                       W id;
+                       UW whole_len;
+               } devide;
+       } status;
+};
+typedef struct traydata_iterator_t_ traydata_iterator_t;
+
+/* Functionality name: traydata */
+/* Detail name: iterator */
+/* Data structure identifier: result */
+struct traydata_iterator_result_ {
+       enum {
+               TRAYDATA_ITERATOR_RESULTTYPE_FIXED_SEGMENT,
+               TRAYDATA_ITERATOR_RESULTTYPE_VARIABLE_SEGMENT_CONT,
+               TRAYDATA_ITERATOR_RESULTTYPE_VARIABLE_SEGMENT,
+               TRAYDATA_ITERATOR_RESULTTYPE_VOBJREC,
+               TRAYDATA_ITERATOR_RESULTTYPE_END,
+       } type;
+       union {
+               TC ch;
+               struct {
+                       UB id;
+                       UW seglen;
+                       UB *chunk_data;
+                       UW chunk_data_len;
+               } seg;
+               TR_VOBJREC vobjrec;
+       } val;
+};
+typedef struct traydata_iterator_result_ traydata_iterator_result;
+
+IMPORT VOID traydata_iterator_initialize(traydata_iterator_t *iterator, TRAYREC *rec, W recnum);
+IMPORT VOID traydata_iterator_finalize(traydata_iterator_t *iterator);
+IMPORT Bool traydata_iterator_next(traydata_iterator_t *iterator, traydata_iterator_result *result);
+
+#endif