Ejemplo n.º 1
0
static size_t __cdecl common_mbstrlen_l(
    char const* const string,
    size_t      const max_size,
    _locale_t   const locale
    )
{
    _LocaleUpdate locale_update(locale);

    _ASSERTE(
        locale_update.GetLocaleT()->locinfo->_public._locale_mb_cur_max == 1 ||
        locale_update.GetLocaleT()->locinfo->_public._locale_mb_cur_max == 2);

    // Handle single byte character sets:
    if (locale_update.GetLocaleT()->locinfo->_public._locale_mb_cur_max == 1)
    {
        return strnlen(string, max_size);
    }

    // Verify that all of the multibyte characters are valid:
    if (MultiByteToWideChar(
            locale_update.GetLocaleT()->locinfo->_public._locale_lc_codepage,
            MB_PRECOMPOSED | MB_ERR_INVALID_CHARS,
            string,
            static_cast<int>(max_size),
            nullptr,
            0
        ) == 0)
    {
        // There was a bad multibyte character:
        errno = EILSEQ;
        return static_cast<size_t>(-1);
    }

    // Count multibyte characters:
    size_t n    = 0; // Number of multibyte characters read
    size_t size = 0; // Number of bytes read
    for (char const* it = string; size < max_size && *it; ++n, ++it, ++size)
    {
        if (_isleadbyte_l(static_cast<unsigned char>(*it), locale_update.GetLocaleT()))
        {
            ++size;
            if (size >= max_size)
                break;

            ++it;
            if (*it == '\0')
                break;
        }
    }

    return size >= max_size ? max_size : n;
}
Ejemplo n.º 2
0
extern "C" size_t __cdecl _mbstowcs_l_helper (
        wchar_t  *pwcs,
        const char *s,
        size_t n,
        _locale_t plocinfo
        )
{
    size_t count = 0;

    if (pwcs && n == 0)
        /* dest string exists, but 0 bytes converted */
        return (size_t) 0;

    if (pwcs && n > 0)
    {
        *pwcs = '\0';
    }

    /* validation section */
    _VALIDATE_RETURN(s != NULL, EINVAL, (size_t)-1);
    /* n must fit into an int for MultiByteToWideChar */
    _VALIDATE_RETURN(n <= INT_MAX, EINVAL, (size_t)-1);


    _LocaleUpdate _loc_update(plocinfo);
    /* if destination string exists, fill it in */
    if (pwcs)
    {
        if (_loc_update.GetLocaleT()->locinfo->lc_handle[LC_CTYPE] == _CLOCALEHANDLE)
        {
            /* C locale: easy and fast */
            while (count < n)
            {
                *pwcs = (wchar_t) ((unsigned char)s[count]);
                if (!s[count])
                    return count;
                count++;
                pwcs++;
            }
            return count;

        } else {
            int bytecnt, charcnt;
            unsigned char *p;

            /* Assume that the buffer is large enough */
            if ( (count = MultiByteToWideChar( _loc_update.GetLocaleT()->locinfo->lc_codepage,
                                               MB_PRECOMPOSED |
                                                MB_ERR_INVALID_CHARS,
                                               s,
                                               -1,
                                               pwcs,
                                               (int)n )) != 0 )
                return count - 1; /* don't count NUL */

            if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
            {
                errno = EILSEQ;
                *pwcs = '\0';
                return (size_t)-1;
            }

            /* User-supplied buffer not large enough. */

            /* How many bytes are in n characters of the string? */
            charcnt = (int)n;
            for (p = (unsigned char *)s; (charcnt-- && *p); p++)
            {
                if (
                    _isleadbyte_l(*p, _loc_update.GetLocaleT())
                    )
                {
                    if(p[1]=='\0')
                    {
                        /*  this is a leadbyte followed by EOS -- a dud MBCS string
                            We choose not to assert here because this
                            function is defined to deal with dud strings on
                            input and return a known value
                        */
                        errno = EILSEQ;
                        *pwcs = '\0';
                        return (size_t)-1;
                    }
                    else
                    {
                        p++;
                    }
                }
            }
            bytecnt = ((int) ((char *)p - (char *)s));

            if ( (count = MultiByteToWideChar( _loc_update.GetLocaleT()->locinfo->lc_codepage,
                                               MB_PRECOMPOSED,
                                               s,
                                               bytecnt,
                                               pwcs,
                                               (int)n )) == 0 )
            {
                errno = EILSEQ;
                *pwcs = '\0';
                return (size_t)-1;
            }

            return count; /* no NUL in string */
        }
    }
    else { /* pwcs == NULL, get size only, s must be NUL-terminated */
        if (_loc_update.GetLocaleT()->locinfo->lc_handle[LC_CTYPE] == _CLOCALEHANDLE) {
            return strlen(s);
        } else if ( (count = MultiByteToWideChar( _loc_update.GetLocaleT()->locinfo->lc_codepage,
                                                  MB_PRECOMPOSED | MB_ERR_INVALID_CHARS,
                                                  s,
                                                  -1,
                                                  NULL,
                                                  0 )) == 0 ) {
            errno = EILSEQ;
            return (size_t)-1;
        } else {
            return count - 1;
        }
    }

}
Ejemplo n.º 3
0
extern "C" int __cdecl _mbtowc_l(
    wchar_t*  pwc,
    const char* s,
    size_t n,
    _locale_t plocinfo
) {
    if (!s || n == 0)
        /* indicate do not have state-dependent encodings,
           handle zero length string */
    {
        return 0;
    }

    if (!*s) {
        /* handle NULL char */
        if (pwc) {
            *pwc = 0;
        }

        return 0;
    }

    _LocaleUpdate _loc_update(plocinfo);
    _ASSERTE(_loc_update.GetLocaleT()->locinfo->mb_cur_max == 1 || _loc_update.GetLocaleT()->locinfo->mb_cur_max == 2);

    if (_loc_update.GetLocaleT()->locinfo->lc_handle[LC_CTYPE] == _CLOCALEHANDLE) {
        if (pwc) {
            *pwc = (wchar_t)(unsigned char) * s;
        }

        return sizeof(char);
    }

    if (_isleadbyte_l((unsigned char)*s, _loc_update.GetLocaleT())) {
        /* multi-byte char */
        if ((_loc_update.GetLocaleT()->locinfo->mb_cur_max <= 1) || ((int)n < _loc_update.GetLocaleT()->locinfo->mb_cur_max) ||
                (MultiByteToWideChar(_loc_update.GetLocaleT()->locinfo->lc_codepage,
                                     MB_PRECOMPOSED | MB_ERR_INVALID_CHARS,
                                     s,
                                     _loc_update.GetLocaleT()->locinfo->mb_cur_max,
                                     pwc,
                                     (pwc) ? 1 : 0) == 0)) {
            /* validate high byte of mbcs char */
            if ((n < (size_t)_loc_update.GetLocaleT()->locinfo->mb_cur_max) || (!*(s + 1))) {
                errno = EILSEQ;
                return -1;
            }
        }

        return _loc_update.GetLocaleT()->locinfo->mb_cur_max;
    } else {
        /* single byte char */
        if (MultiByteToWideChar(_loc_update.GetLocaleT()->locinfo->lc_codepage,
                                MB_PRECOMPOSED | MB_ERR_INVALID_CHARS,
                                s,
                                1,
                                pwc,
                                (pwc) ? 1 : 0) == 0) {
            errno = EILSEQ;
            return -1;
        }

        return sizeof(char);
    }
}