Changeset View
Changeset View
Standalone View
Standalone View
lib/libiconv_modules/iconv_std/citrus_iconv_std.c
Show First 20 Lines • Show All 466 Lines • ▼ Show 20 Lines | _citrus_iconv_std_iconv_convert(struct _citrus_iconv * __restrict cv, | ||||
char * __restrict * __restrict out, size_t * __restrict outbytes, | char * __restrict * __restrict out, size_t * __restrict outbytes, | ||||
uint32_t flags, size_t * __restrict invalids) | uint32_t flags, size_t * __restrict invalids) | ||||
{ | { | ||||
const struct _citrus_iconv_std_shared *is = cv->cv_shared->ci_closure; | const struct _citrus_iconv_std_shared *is = cv->cv_shared->ci_closure; | ||||
struct _citrus_iconv_std_context *sc = cv->cv_closure; | struct _citrus_iconv_std_context *sc = cv->cv_closure; | ||||
_csid_t csid; | _csid_t csid; | ||||
_index_t idx; | _index_t idx; | ||||
char *tmpin; | char *tmpin; | ||||
size_t inval, szrin, szrout; | size_t inval, in_mb_cur_min, szrin, szrout; | ||||
int ret, state = 0; | int ret, state = 0; | ||||
inval = 0; | inval = 0; | ||||
if (in == NULL || *in == NULL) { | if (in == NULL || *in == NULL) { | ||||
/* special cases */ | /* special cases */ | ||||
if (out != NULL && *out != NULL) { | if (out != NULL && *out != NULL) { | ||||
/* init output state and store the shift sequence */ | /* init output state and store the shift sequence */ | ||||
save_encoding_state(&sc->sc_src_encoding); | save_encoding_state(&sc->sc_src_encoding); | ||||
Show All 15 Lines | if (in == NULL || *in == NULL) { | ||||
} else | } else | ||||
/* otherwise, discard the shift sequence */ | /* otherwise, discard the shift sequence */ | ||||
init_encoding_state(&sc->sc_dst_encoding); | init_encoding_state(&sc->sc_dst_encoding); | ||||
init_encoding_state(&sc->sc_src_encoding); | init_encoding_state(&sc->sc_src_encoding); | ||||
*invalids = 0; | *invalids = 0; | ||||
return (0); | return (0); | ||||
} | } | ||||
in_mb_cur_min = _stdenc_get_mb_cur_min(is->is_src_encoding); | |||||
/* normal case */ | /* normal case */ | ||||
for (;;) { | for (;;) { | ||||
if (*inbytes == 0) { | if (*inbytes == 0) { | ||||
ret = get_state_desc_gen(&sc->sc_src_encoding, &state); | ret = get_state_desc_gen(&sc->sc_src_encoding, &state); | ||||
if (state == _STDENC_SDGEN_INITIAL || | if (state == _STDENC_SDGEN_INITIAL || | ||||
state == _STDENC_SDGEN_STABLE) | state == _STDENC_SDGEN_STABLE) | ||||
break; | break; | ||||
} | } | ||||
/* save the encoding states for the error recovery */ | /* save the encoding states for the error recovery */ | ||||
save_encoding_state(&sc->sc_src_encoding); | save_encoding_state(&sc->sc_src_encoding); | ||||
save_encoding_state(&sc->sc_dst_encoding); | save_encoding_state(&sc->sc_dst_encoding); | ||||
/* mb -> csid/index */ | /* mb -> csid/index */ | ||||
tmpin = *in; | tmpin = *in; | ||||
szrin = szrout = 0; | szrin = szrout = 0; | ||||
ret = mbtocsx(&sc->sc_src_encoding, &csid, &idx, &tmpin, | ret = mbtocsx(&sc->sc_src_encoding, &csid, &idx, &tmpin, | ||||
*inbytes, &szrin, cv->cv_shared->ci_hooks); | *inbytes, &szrin, cv->cv_shared->ci_hooks); | ||||
if (ret) | if (ret != 0 && (ret != EILSEQ || | ||||
!cv->cv_shared->ci_discard_ilseq)) { | |||||
goto err; | goto err; | ||||
} else if (ret == EILSEQ) { | |||||
/* | |||||
* If //IGNORE was specified, we'll just keep crunching | |||||
* through invalid characters. | |||||
*/ | |||||
*in += in_mb_cur_min; | |||||
*inbytes -= in_mb_cur_min; | |||||
restore_encoding_state(&sc->sc_src_encoding); | |||||
restore_encoding_state(&sc->sc_dst_encoding); | |||||
continue; | |||||
} | |||||
if (szrin == (size_t)-2) { | if (szrin == (size_t)-2) { | ||||
/* incompleted character */ | /* incompleted character */ | ||||
ret = get_state_desc_gen(&sc->sc_src_encoding, &state); | ret = get_state_desc_gen(&sc->sc_src_encoding, &state); | ||||
if (ret) { | if (ret) { | ||||
ret = EINVAL; | ret = EINVAL; | ||||
goto err; | goto err; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 61 Lines • Show Last 20 Lines |