diff options
Diffstat (limited to 'wcsmbs/btowc.c')
-rw-r--r-- | wcsmbs/btowc.c | 69 |
1 files changed, 41 insertions, 28 deletions
diff --git a/wcsmbs/btowc.c b/wcsmbs/btowc.c index ca75e28..1ba0221 100644 --- a/wcsmbs/btowc.c +++ b/wcsmbs/btowc.c @@ -30,12 +30,6 @@ wint_t __btowc (c) int c; { - wchar_t result; - struct __gconv_step_data data; - unsigned char inbuf[1]; - const unsigned char *inptr = inbuf; - size_t dummy; - int status; const struct gconv_fcts *fcts; /* If the parameter does not fit into one byte or it is the EOF value @@ -43,32 +37,51 @@ __btowc (c) if (c < SCHAR_MIN || c > UCHAR_MAX || c == EOF) return WEOF; - /* Tell where we want the result. */ - data.__outbuf = (unsigned char *) &result; - data.__outbufend = data.__outbuf + sizeof (wchar_t); - data.__invocation_counter = 0; - data.__internal_use = 1; - data.__flags = __GCONV_IS_LAST; - data.__statep = &data.__state; - data.__trans = NULL; - - /* Make sure we start in the initial state. */ - memset (&data.__state, '\0', sizeof (mbstate_t)); - /* Get the conversion functions. */ fcts = get_gconv_fcts (_NL_CURRENT_DATA (LC_CTYPE)); - /* Create the input string. */ - inbuf[0] = c; + if (__builtin_expect (fcts->towc_nsteps == 1, 1) + && __builtin_expect (fcts->towc->__btowc_fct != NULL, 1)) + { + /* Use the shortcut function. */ + return DL_CALL_FCT (fcts->towc->__btowc_fct, + (fcts->towc, (unsigned char) c)); + } + else + { + /* Fall back to the slow but generic method. */ + wchar_t result; + struct __gconv_step_data data; + unsigned char inbuf[1]; + const unsigned char *inptr = inbuf; + size_t dummy; + int status; + + /* Tell where we want the result. */ + data.__outbuf = (unsigned char *) &result; + data.__outbufend = data.__outbuf + sizeof (wchar_t); + data.__invocation_counter = 0; + data.__internal_use = 1; + data.__flags = __GCONV_IS_LAST; + data.__statep = &data.__state; + data.__trans = NULL; + + /* Make sure we start in the initial state. */ + memset (&data.__state, '\0', sizeof (mbstate_t)); + + /* Create the input string. */ + inbuf[0] = c; + + status = DL_CALL_FCT (fcts->towc->__fct, + (fcts->towc, &data, &inptr, inptr + 1, + NULL, &dummy, 0, 1)); - status = DL_CALL_FCT (fcts->towc->__fct, - (fcts->towc, &data, &inptr, inptr + 1, - NULL, &dummy, 0, 1)); - /* The conversion failed. */ - if (status != __GCONV_OK && status != __GCONV_FULL_OUTPUT - && status != __GCONV_EMPTY_INPUT) - result = WEOF; + if (status != __GCONV_OK && status != __GCONV_FULL_OUTPUT + && status != __GCONV_EMPTY_INPUT) + /* The conversion failed. */ + result = WEOF; - return result; + return result; + } } weak_alias (__btowc, btowc) |