diff --git a/vtparse.c b/vtparse.c index 7627bb1..5b9007f 100644 --- a/vtparse.c +++ b/vtparse.c @@ -15,9 +15,11 @@ void vtparse_init(vtparse_t *parser, vtparse_callback_t cb) parser->num_params = 0; parser->ignore_flagged = 0; parser->cb = cb; + parser->characterBytes = 1; + parser->utf8Character = 0; } -static void do_action(vtparse_t *parser, vtparse_action_t action, char ch) +static void do_action(vtparse_t *parser, vtparse_action_t action, unsigned int ch) { /* Some actions we handle internally (like parsing parameters), others * we hand to our client for processing */ @@ -46,7 +48,7 @@ static void do_action(vtparse_t *parser, vtparse_action_t action, char ch) if(parser->num_intermediate_chars + 1 > MAX_INTERMEDIATE_CHARS) parser->ignore_flagged = 1; else - parser->intermediate_chars[parser->num_intermediate_chars++] = ch; + parser->intermediate_chars[parser->num_intermediate_chars++] = (unsigned char)ch; break; } @@ -72,7 +74,7 @@ static void do_action(vtparse_t *parser, vtparse_action_t action, char ch) current_param = parser->num_params - 1; parser->params[current_param] *= 10; - parser->params[current_param] += (ch - '0'); + parser->params[current_param] += ch - '0'; } break; @@ -89,7 +91,7 @@ static void do_action(vtparse_t *parser, vtparse_action_t action, char ch) } } -static void do_state_change(vtparse_t *parser, state_change_t change, char ch) +static void do_state_change(vtparse_t *parser, state_change_t change, unsigned int ch) { /* A state change is an action and/or a new state to transition to. */ @@ -125,14 +127,61 @@ static void do_state_change(vtparse_t *parser, state_change_t change, char ch) } } -void vtparse(vtparse_t *parser, unsigned char *data, int len) +void vtparse(vtparse_t *parser, unsigned char *data, unsigned int len) { int i; for(i = 0; i < len; i++) { unsigned char ch = data[i]; - state_change_t change = STATE_TABLE[parser->state-1][ch]; - do_state_change(parser, change, ch); + if(parser->characterBytes != 1) + { + parser->utf8Character = (parser->utf8Character << 6) | (ch & 0x3F); + parser->characterBytes--; + + if(parser->characterBytes == 1) + { + state_change_t change = VTPARSE_ACTION_PRINT; + do_state_change(parser, change, parser->utf8Character); + } + } + else if((ch&(1<<7)) != 0) + { + int bit = 6; + do + { + if((ch&(1< 1); + + parser->utf8Character = 0; + parser->characterBytes = 7-bit; + switch(parser->characterBytes) + { + case 2: + parser->utf8Character = ch & (1 | (1<<1) | (1<<2) | (1<<3) | (1<<4)); + break; + case 3: + parser->utf8Character = ch & (1 | (1<<1) | (1<<2) | (1<<3)); + break; + case 4: + parser->utf8Character = ch & (1 | (1<<1) | (1<<2)); + break; + case 5: + parser->utf8Character = ch & (1 | (1<<1)); + break; + case 6: + parser->utf8Character = ch & 1; + break; + } + } + else + { + state_change_t change = STATE_TABLE[parser->state-1][ch]; + do_state_change(parser, change, (unsigned int)ch); + } } } diff --git a/vtparse.h b/vtparse.h index 6bd139c..8b044fd 100644 --- a/vtparse.h +++ b/vtparse.h @@ -21,7 +21,7 @@ extern "C" { struct vtparse; -typedef void (*vtparse_callback_t)(struct vtparse*, vtparse_action_t, unsigned char); +typedef void (*vtparse_callback_t)(struct vtparse*, vtparse_action_t, unsigned int); typedef struct vtparse { vtparse_state_t state; @@ -32,10 +32,12 @@ typedef struct vtparse { int params[16]; int num_params; void* user_data; + int characterBytes; + unsigned int utf8Character; } vtparse_t; void vtparse_init(vtparse_t *parser, vtparse_callback_t cb); -void vtparse(vtparse_t *parser, unsigned char *data, int len); +void vtparse(vtparse_t *parser, unsigned char *data, unsigned int len); #ifdef __cplusplus } diff --git a/vtparse_check_tables.rb b/vtparse_check_tables.rb index 6c529ef..9c8f071 100644 --- a/vtparse_check_tables.rb +++ b/vtparse_check_tables.rb @@ -1,5 +1,5 @@ -require 'vtparse_tables' +require './vtparse_tables.rb' # # check that for every state, there is a transition defined diff --git a/vtparse_gen_c_tables.rb b/vtparse_gen_c_tables.rb index 811706b..aca18c9 100644 --- a/vtparse_gen_c_tables.rb +++ b/vtparse_gen_c_tables.rb @@ -1,5 +1,5 @@ -require 'vtparse_tables' +require './vtparse_tables.rb' class String def pad(len) diff --git a/vtparse_test.c b/vtparse_test.c index 5019c81..85c1dba 100644 --- a/vtparse_test.c +++ b/vtparse_test.c @@ -10,7 +10,7 @@ #include #include "vtparse.h" -void parser_callback(vtparse_t *parser, vtparse_action_t action, unsigned char ch) +void parser_callback(vtparse_t *parser, vtparse_action_t action, unsigned int ch) { int i;