#include "texteditor_insertfilter.h"
#include <bstdio.h>
+#include <bassert.h>
#include <tad/taditerator.h>
#include <tad/tadstack.h>
+#include "texteditor_stackfilter.h"
+
#ifdef BCHAN_CONFIG_DEBUG
# define DP(arg) printf arg
# define DP_ER(msg, err) printf("%s (%d/%x)\n", msg, err>>16, err)
#define DP_STATE(s) /**/
#endif
-LOCAL Bool texteditor_insertfilter_stackfilter(texteditor_insertfilter_t *filter, taditerator_result *result)
-{
- W nestlevel, err;
- TADSTACK_DATATYPE type;
-
- for (;;) {
- taditerator_next2(&filter->iterator, result);
- if (result->type == TADITERATOR_RESULTTYPE_END) {
- break;
- }
-
- if (result->type == TADITERATOR_RESULTTYPE_CHARCTOR) {
- tadstack_inputcharactor(&filter->tadstack, result->segment);
- } else if (result->type == TADITERATOR_RESULTTYPE_SEGMENT) {
- tadstack_inputvsegment(&filter->tadstack, result->segment, result->data, result->segsize);
- }
-
- nestlevel = tadstack_nestlevel(&filter->tadstack);
- if (nestlevel != 0) {
- continue;
- }
- err = tadstack_currentdata(&filter->tadstack, &type);
- if (type != TADSTACK_DATATYPE_TEXT) {
- continue;
- }
-
- return True;
- }
-
- return False;
-}
-
-struct texteditor_insertfilter_innerresult_ {
- enum {
- INNERRESULT_VARIABLE,
- INNERRESULT_STRING,
- INNERRESULT_LANGCODE,
- } type;
- UB *data;
- W len;
- struct {
- UB segid;
- UW len;
- UB *data;
- } variable;
-};
-typedef struct texteditor_insertfilter_innerresult_ texteditor_insertfilter_innerresult;
-
-LOCAL Bool texteditor_insertfilter_langcode(texteditor_insertfilter_t *filter, texteditor_insertfilter_innerresult *result)
-{
- taditerator_result iter_result;
- Bool reading_lang = False, cont;
- TC *lang_start = NULL;
-
- for (;;) {
- cont = texteditor_insertfilter_stackfilter(filter, &iter_result);
- if (cont == False) {
- break;
- }
-
- if (reading_lang != False) {
- if (iter_result.type != TADITERATOR_RESULTTYPE_CHARCTOR) {
- /* format error */
- break;
- }
- if (lang_start == NULL) {
- break;
- }
- if (iter_result.segment == 0xFEFE) {
- continue;
- }
- result->type = INNERRESULT_LANGCODE;
- result->data = (UB*)lang_start;
- result->len = (iter_result.pos - lang_start + 1) * sizeof(TC);
- TCtotadlangcode((TC*)result->data, result->len / sizeof(TC), &filter->current.lang);
- reading_lang = False;
- lang_start = NULL;
- }
-
- if (iter_result.type == TADITERATOR_RESULTTYPE_CHARCTOR) {
- if ((iter_result.segment & 0xFF00) == 0xFE00) {
- if (iter_result.segment == 0xFEFE) {
- reading_lang = True;
- lang_start = iter_result.pos;
- } else {
- result->type = INNERRESULT_LANGCODE;
- result->data = (UB*)iter_result.pos;
- result->len = sizeof(TC);
- TCtotadlangcode((TC*)result->data, result->len / sizeof(TC), &filter->current.lang);
- return True;
- }
- } else {
- result->type = INNERRESULT_STRING;
- result->data = (UB*)iter_result.pos;
- result->len = sizeof(TC);
- return True;
- }
- } else if (iter_result.type == TADITERATOR_RESULTTYPE_SEGMENT) {
- result->type = INNERRESULT_VARIABLE;
- result->data = (UB*)iter_result.pos;
- if (iter_result.vseg.l->len == 0xFFFF) {
- result->len = 2 + 2 + 4 + iter_result.vseg.l->llen;
- } else {
- result->len = 2 + 2 + iter_result.vseg.l->len;
- }
- result->variable.segid = iter_result.segment & 0xFF;
- result->variable.len = iter_result.segsize;
- result->variable.data = iter_result.data;
- return True;
- }
- }
-
- return False;
-}
-
-LOCAL Bool texteditor_insertfilter_chratio(texteditor_insertfilter_t *filter, texteditor_insertfilter_innerresult *result)
-{
- Bool cont;
- UB subid;
-
- for (;;) {
- cont = texteditor_insertfilter_langcode(filter, result);
- if (cont == False) {
- break;
- }
-
- if (result->type != INNERRESULT_VARIABLE) {
- return True;
- }
-
- if (result->variable.segid != TS_TFONT) {
- continue;
- }
- if (result->variable.len < 6) {
- continue;
- }
- subid = *(UH*)result->variable.data >> 8;
- if (subid != 3) {
- continue;
- }
-
- filter->current.w_ratio = *((UH*)result->variable.data + 5);
-
- return True;
- }
-
- return False;
-}
-
/* */
LOCAL Bool texteditor_insertfilter_w_ratio_isZenkaku(RATIO w_ratio)
/* */
-LOCAL TC texteditor_insertfilter_systemlangcode[] = { 0xFE21 };
-#define TEXTEDITOR_INSERTFILTER_SYSTEMLANGCODE_LENGTH 1
-
LOCAL TC textediter_insertfilter_zenkakufusen[] = { 0xFFA2, 0x0006, 0x0300, 0x0101, 0x0101 };
LOCAL TC textediter_insertfilter_hankakufusen[] = { 0xFFA2, 0x0006, 0x0300, 0x0101, 0x0102 };
#define TEXTEDITOR_INSERTFILTER_FUSEN_LENGTH 5
-LOCAL VOID texteditor_insertfilter_setresult_systemlangcode(texteditor_insertfilter_result *result)
+LOCAL VOID texteditor_insertfilter_pushback_segment(texteditor_insertfilter_t *filter, tadsegment *segment)
{
- result->data = (UB*)texteditor_insertfilter_systemlangcode;
- result->len = TEXTEDITOR_INSERTFILTER_SYSTEMLANGCODE_LENGTH * sizeof(TC);
+ assert(filter->result_buffer.used < TEXTEDITOR_INSERTFILTER_RESULT_BUFFER_LEN);
+ filter->result_buffer.segs[filter->result_buffer.used] = *segment;
+ filter->result_buffer.used++;
}
-LOCAL VOID texteditor_insertfilter_setresult_firstlangcode(texteditor_insertfilter_t *filter, texteditor_insertfilter_result *result)
+LOCAL VOID texteditor_insertfilter_pushback_zenkakufusen(texteditor_insertfilter_t *filter)
{
- result->len = tadlangcodetoTC(&filter->first.lang, filter->buffer, TEXTEDITOR_INSERTFILTER_TEXTBUFFER_SIZE) * sizeof(TC);
- result->data = (UB*)filter->buffer;
+ tadsegment segment;
+ segment.type = TADSEGMENT_TYPE_VARIABLE;
+ segment.value.variable.raw = (UB*)textediter_insertfilter_zenkakufusen;
+ segment.value.variable.rawlen = TEXTEDITOR_INSERTFILTER_FUSEN_LENGTH * sizeof(TC);
+ texteditor_insertfilter_pushback_segment(filter, &segment);
}
-LOCAL VOID texteditor_insertfilter_setresult_zenkakufusen(texteditor_insertfilter_result *result)
+LOCAL VOID texteditor_insertfilter_pushback_hankakufusen(texteditor_insertfilter_t *filter)
{
- result->data = (UB*)textediter_insertfilter_zenkakufusen;
- result->len = TEXTEDITOR_INSERTFILTER_FUSEN_LENGTH * sizeof(TC);
+ tadsegment segment;
+ segment.type = TADSEGMENT_TYPE_VARIABLE;
+ segment.value.variable.raw = (UB*)textediter_insertfilter_hankakufusen;
+ segment.value.variable.rawlen = TEXTEDITOR_INSERTFILTER_FUSEN_LENGTH * sizeof(TC);
+ texteditor_insertfilter_pushback_segment(filter, &segment);
}
-LOCAL VOID texteditor_insertfilter_setresult_hankakufusen(texteditor_insertfilter_result *result)
+LOCAL VOID texteditor_insertfilter_pushback_systemlangcode(texteditor_insertfilter_t *filter)
{
- result->data = (UB*)textediter_insertfilter_hankakufusen;
- result->len = TEXTEDITOR_INSERTFILTER_FUSEN_LENGTH * sizeof(TC);
+ tadsegment segment;
+ segment.type = TADSEGMENT_TYPE_LANGCODE;
+ segment.value.lang = (tadlangcode){0, 0x21};
+ texteditor_insertfilter_pushback_segment(filter, &segment);
}
-/* */
+LOCAL VOID texteditor_insertfilter_pushback_firstlangcode(texteditor_insertfilter_t *filter)
+{
+ tadsegment segment;
+ segment.type = TADSEGMENT_TYPE_LANGCODE;
+ segment.value.lang = filter->first.lang;
+ texteditor_insertfilter_pushback_segment(filter, &segment);
+}
-LOCAL Bool texteditor_insertfilter_next_terminate(texteditor_insertfilter_t *filter, texteditor_insertfilter_result *result)
+LOCAL W texteditor_insertfilter_put_filtering(texteditor_insertfilter_t *filter, tadsegment *segment)
{
- Bool ok, zen;
+ W ret;
+ Bool cont;
+ tadsegment *result;
+ UB segid, subid, *segdata;
+ UW seglen;
- if (filter->first.w_ratio != filter->current.w_ratio) {
- filter->state = TEXTEDITOR_INSTERTFILTER_STATE_LAST_LANGCODE;
- zen = texteditor_insertfilter_w_ratio_isZenkaku(filter->first.w_ratio);
- if (zen == False) {
- texteditor_insertfilter_setresult_hankakufusen(result);
- } else {
- texteditor_insertfilter_setresult_zenkakufusen(result);
- }
- return True;
+ ret = texteditor_stackfilter_setinput(&filter->stack, segment);
+ if (ret == TEXTEDITOR_STACKFILTER_SETINPUT_RESULT_FORMAT_ERROR) {
+ return TEXTEDITOR_INSERTFILTER_PUT_RESULT_FORMAT_ERROR;
}
- ok = tadlangcodecmp(&filter->first.lang, &filter->current.lang);
- if (ok == False) {
- filter->state = TEXTEDITOR_INSTERTFILTER_STATE_LAST;
- texteditor_insertfilter_setresult_firstlangcode(filter, result);
- return True;
+ for(;;) {
+ cont = texteditor_stackfilter_getoutput(&filter->stack, &result);
+ if (cont == False) {
+ break;
+ }
+
+ if (result->type == TADSEGMENT_TYPE_VARIABLE) {
+ tadsegment_getvariable(result, &segid, &seglen, &segdata);
+ if (segid != TS_TFONT) {
+ continue;
+ }
+ if (seglen < 6) {
+ continue;
+ }
+ subid = *(UH*)segdata >> 8;
+ if (subid != 3) {
+ continue;
+ }
+
+ filter->current.w_ratio = *((UH*)segdata + 5);
+ } else if (result->type == TADSEGMENT_TYPE_LANGCODE) {
+ filter->current.lang = result->value.lang;
+ }
+
+ texteditor_insertfilter_pushback_segment(filter, result);
}
- return False;
+ return TEXTEDITOR_INSERTFILTER_PUT_RESULT_OK;
}
-LOCAL Bool texteditor_insertfilter_next_state_start(texteditor_insertfilter_t *filter, texteditor_insertfilter_result *result)
+LOCAL W texteditor_insertfilter_put_state_start(texteditor_insertfilter_t *filter, tadsegment *segment, texteditor_insertfilterresult_t **result)
{
- texteditor_insertfilter_innerresult inner_result;
- Bool cont, ok;
+ Bool ok;
ok = texteditor_insertfilter_w_ratio_isZenkaku(filter->first.w_ratio);
if (ok == False) {
- filter->state = TEXTEDITOR_INSTERTFILTER_STATE_FIRST_LANGCODE;
- texteditor_insertfilter_setresult_zenkakufusen(result);
- return True;
+ texteditor_insertfilter_pushback_zenkakufusen(filter);
}
ok = texteditor_insertfilter_w_ratio_isSystemScript(&filter->first.lang);
if (ok == False) {
- filter->state = TEXTEDITOR_INSTERTFILTER_STATE_RUNNING;
- texteditor_insertfilter_setresult_systemlangcode(result);
- return True;
+ texteditor_insertfilter_pushback_systemlangcode(filter);
}
- cont = texteditor_insertfilter_chratio(filter, &inner_result);
- if (cont == False) {
- return texteditor_insertfilter_next_terminate(filter, result);
- }
+ *result = &filter->result;
- filter->state = TEXTEDITOR_INSTERTFILTER_STATE_RUNNING;
- result->data = inner_result.data;
- result->len = inner_result.len;
+ filter->state = TEXTEDITOR_INSERTFILTER_STATE_RUNNING;
- return True;
+ return texteditor_insertfilter_put_filtering(filter, segment);
}
-LOCAL Bool texteditor_insertfilter_next_state_langcode(texteditor_insertfilter_t *filter, texteditor_insertfilter_result *result)
+LOCAL W texteditor_insertfilter_put_state_running(texteditor_insertfilter_t *filter, tadsegment *segment, texteditor_insertfilterresult_t **result)
{
- texteditor_insertfilter_innerresult inner_result;
- Bool cont, ok;
-
- ok = texteditor_insertfilter_w_ratio_isSystemScript(&filter->first.lang);
- if (ok == False) {
- filter->state = TEXTEDITOR_INSTERTFILTER_STATE_RUNNING;
- texteditor_insertfilter_setresult_systemlangcode(result);
- return True;
- }
+ filter->result_buffer.used = 0;
+ filter->result_buffer.consumed = 0;
- cont = texteditor_insertfilter_chratio(filter, &inner_result);
- if (cont == False) {
- return texteditor_insertfilter_next_terminate(filter, result);
- }
-
- filter->state = TEXTEDITOR_INSTERTFILTER_STATE_RUNNING;
- result->data = inner_result.data;
- result->len = inner_result.len;
+ *result = &filter->result;
- return True;
+ return texteditor_insertfilter_put_filtering(filter, segment);
}
-LOCAL Bool texteditor_insertfilter_next_state_running(texteditor_insertfilter_t *filter, texteditor_insertfilter_result *result)
+EXPORT W texteditor_insertfilter_put(texteditor_insertfilter_t *filter, tadsegment *segment, texteditor_insertfilterresult_t **result)
{
- texteditor_insertfilter_innerresult inner_result;
- Bool cont;
-
- cont = texteditor_insertfilter_chratio(filter, &inner_result);
- if (cont == False) {
- return texteditor_insertfilter_next_terminate(filter, result);
+ switch (filter->state) {
+ case TEXTEDITOR_INSERTFILTER_STATE_START:
+ DP_STATE("put:STATE_START");
+ return texteditor_insertfilter_put_state_start(filter, segment, result);
+ case TEXTEDITOR_INSERTFILTER_STATE_RUNNING:
+ DP_STATE("put:STATE_RUNNING");
+ return texteditor_insertfilter_put_state_running(filter, segment, result);
+ case TEXTEDITOR_INSERTFILTER_STATE_END:
+ DP_STATE("put:STATE_END");
+ return TEXTEDITOR_INSERTFILTER_PUT_RESULT_FORMAT_ERROR;
}
-
- filter->state = TEXTEDITOR_INSTERTFILTER_STATE_RUNNING;
- result->data = inner_result.data;
- result->len = inner_result.len;
-
- return True;
+ return TEXTEDITOR_INSERTFILTER_PUT_RESULT_FORMAT_ERROR;
}
-LOCAL Bool texteditor_insertfilter_next_state_last_langcode(texteditor_insertfilter_t *filter, texteditor_insertfilter_result *result)
+EXPORT VOID texteditor_insertfilter_endinput(texteditor_insertfilter_t *filter, texteditor_insertfilterresult_t **result)
{
- Bool ok;
+ Bool ok, zen;
- ok = tadlangcodecmp(&filter->first.lang, &filter->current.lang);
- if (ok == False) {
- filter->state = TEXTEDITOR_INSTERTFILTER_STATE_LAST;
- texteditor_insertfilter_setresult_firstlangcode(filter, result);
- return True;
- }
+ filter->result_buffer.used = 0;
+ filter->result_buffer.consumed = 0;
+ *result = &filter->result;
- return False;
+ switch (filter->state) {
+ case TEXTEDITOR_INSERTFILTER_STATE_START:
+ DP_STATE("end:STATE_START");
+ break;
+ case TEXTEDITOR_INSERTFILTER_STATE_RUNNING:
+ DP_STATE("end:STATE_RUNNING");
+ if (filter->first.w_ratio != filter->current.w_ratio) {
+ zen = texteditor_insertfilter_w_ratio_isZenkaku(filter->first.w_ratio);
+ if (zen == False) {
+ texteditor_insertfilter_pushback_hankakufusen(filter);
+ } else {
+ texteditor_insertfilter_pushback_zenkakufusen(filter);
+ }
+ }
+ ok = tadlangcodecmp(&filter->first.lang, &filter->current.lang);
+ if (ok == False) {
+ texteditor_insertfilter_pushback_firstlangcode(filter);
+ }
+ break;
+ case TEXTEDITOR_INSERTFILTER_STATE_END:
+ DP_STATE("end:STATE_END");
+ break;
+ }
}
-LOCAL Bool texteditor_insertfilter_next_state_last(texteditor_insertfilter_t *filter, texteditor_insertfilter_result *result)
+EXPORT Bool texteditor_insertfilterresult_next(texteditor_insertfilterresult_t *result, tadsegment **segment)
{
- return False;
-}
+ texteditor_insertfilter_t *filter = result->filter;
-EXPORT Bool texteditor_insertfilter_next(texteditor_insertfilter_t *filter, texteditor_insertfilter_result *result)
-{
- Bool cont = False;
+ if (filter->result_buffer.consumed >= filter->result_buffer.used) {
+ return False;
+ }
- switch (filter->state) {
- case TEXTEDITOR_INSTERTFILTER_STATE_START:
- DP_STATE("STATE_START");
- cont = texteditor_insertfilter_next_state_start(filter, result);
- break;
- case TEXTEDITOR_INSTERTFILTER_STATE_FIRST_LANGCODE:
- DP_STATE("STATE_FIRST_LANGCODE");
- cont = texteditor_insertfilter_next_state_langcode(filter, result);
- break;
- case TEXTEDITOR_INSTERTFILTER_STATE_RUNNING:
- DP_STATE("STATE_RUNNING");
- cont = texteditor_insertfilter_next_state_running(filter, result);
- break;
- case TEXTEDITOR_INSTERTFILTER_STATE_LAST_LANGCODE:
- DP_STATE("STATE_LAST_LANGCODE");
- cont = texteditor_insertfilter_next_state_last_langcode(filter, result);
- break;
- case TEXTEDITOR_INSTERTFILTER_STATE_LAST:
- DP_STATE("STATE_LAST");
- cont = texteditor_insertfilter_next_state_last(filter, result);
- break;
+ *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;
}
- return cont;
+ return True;
}
-EXPORT VOID texteditor_insertfilter_initialize(texteditor_insertfilter_t *filter, tadlangcode *lang, RATIO w_ratio, UB *data, W len)
+EXPORT VOID texteditor_insertfilter_initialize(texteditor_insertfilter_t *filter, tadlangcode *lang, RATIO w_ratio)
{
- filter->state = TEXTEDITOR_INSTERTFILTER_STATE_START;
+ texteditor_stackfilter_initialize(&filter->stack);
+ filter->state = TEXTEDITOR_INSERTFILTER_STATE_START;
filter->first.lang = *lang;
filter->first.w_ratio = w_ratio;
filter->current.lang = (tadlangcode){0, 0x21};
filter->current.w_ratio = 0x0101;
- tadstack_initialize(&filter->tadstack);
- taditerator_initialize(&filter->iterator, (TC*)data, len / sizeof(TC));
+ filter->result_buffer.used = 0;
+ filter->result_buffer.consumed = 0;
+ filter->result.filter = filter;
}
EXPORT VOID texteditor_insertfilter_finalize(texteditor_insertfilter_t *filter)
{
- taditerator_finalize(&filter->iterator);
- tadstack_finalize(&filter->tadstack);
+ texteditor_stackfilter_finalize(&filter->stack);
}