libutf8/src/libutf8/encode_state.c

89 lines
2.2 KiB
C

/* libutf8/src/lib/encode_state.c
*
* (c)2006, Laurence Withers. Released under the GNU GPL. See file
* COPYING for more information / terms of license.
*/
struct utf8_encode_state* utf8_encoder(struct utf8_encode_state* state)
{
char* wr = state->wr, * ret;
char* endp = wr + state->wr_size - 1;
wchar_t ch;
enum utf8_encode_error_action error_action;
bool reencoding;
if(!state || !state->rd || !state->wr || state->wr_size < 7) {
errno = EINVAL;
return 0;
}
state->written = 0;
while(state->rd_remain) {
ch = *state->rd;
if(!ch && state->rd_remain < 0) break;
reencoding = false;
reencode:
ret = utf8_encode_char(wr, endp - wr, ch);
if(!ret) {
if(errno == ENOMEM) break;
if(!state->error_callback || reencoding) {
errno = EILSEQ;
return 0;
}
error_action = state->error_callback(state, &ch);
switch(error_action) {
case utf8_encode_error_action_abort:
errno = EILSEQ;
return 0;
case utf8_encode_error_action_replace:
reencoding = true;
goto reencode;
case utf8_encode_error_action_skip:
ret = wr;
break;
}
}
if(state->rd_remain > 0) state->rd_remain--;
++state->rd;
++state->char_offset;
if(ch == 0x0A || ch == 0x2028) {
++state->line;
state->col = 0;
} else {
++state->col;
}
state->written += ret - wr;
wr = ret;
if(wr == endp) break;
}
*wr = 0;
return state;
}
enum utf8_encode_error_action utf8_encode_error_callback_replace(
const struct utf8_encode_state* state, wchar_t* newch)
{
(void)state;
*newch = 0xFFFD;
return utf8_encode_error_action_replace;
}
enum utf8_encode_error_action utf8_encode_error_callback_skip(
const struct utf8_encode_state* state, wchar_t* newch)
{
(void)state;
(void)newch;
return utf8_encode_error_action_skip;
}
/* options for text editors
kate: replace-trailing-space-save true; space-indent true; tab-width 4;
*/