コード例 #1
0
ファイル: wcstombs.c プロジェクト: mysticTot/learn_c
extern "C" size_t __cdecl _wcstombs_l_helper(
    char* s,
    const wchar_t* pwcs,
    size_t n,
    _locale_t plocinfo
) {
    size_t count = 0;
    int i, retval;
    char buffer[MB_LEN_MAX];
    BOOL defused = 0;

    if (s && n == 0)
        /* dest string exists, but 0 bytes converted */
    {
        return 0;
    }

    /* validation section */
    _VALIDATE_RETURN(pwcs != NULL, EINVAL, (size_t) - 1);
    _VALIDATE_RETURN(n <= INT_MAX, EINVAL, (size_t) - 1);
    /* if destination string exists, fill it in */
    _LocaleUpdate _loc_update(plocinfo);

    if (s) {
        if (_loc_update.GetLocaleT()->locinfo->lc_handle[LC_CTYPE] == _CLOCALEHANDLE) {
            /* C locale: easy and fast */
            /* Actually, there are such wchar_t characters which are > 255,
             * but they can be transformed to a valid single byte char
             * (i.e. a char in the C locale case). Like, for example,
             * alternative digits in unicode like Arabic-Indic U+0660..U+0669.
             * The problem is that WideCharToMultiByte() does not translate those
             * wchar_t unless we pass the correct codepage (1256, Arabic).
             * See bug VSW:192653.
             */
            while (count < n) {
                if (*pwcs > 255) { /* validate high byte */
                    errno = EILSEQ;
                    return (size_t) - 1; /* error */
                }

                s[count] = (char) * pwcs;

                if (*pwcs++ == L'\0') {
                    return count;
                }

                count++;
            }

            return count;
        } else {
            if (1 == _loc_update.GetLocaleT()->locinfo->mb_cur_max) {
                /* If SBCS, one wchar_t maps to one char */

                /* WideCharToMultiByte will compare past NULL - reset n */
                if (n > 0) {
                    n = wcsncnt(pwcs, n);
                }

                if (((count = WideCharToMultiByte(_loc_update.GetLocaleT()->locinfo->lc_codepage,
                                                  0,
                                                  pwcs,
                                                  (int)n,
                                                  s,
                                                  (int)n,
                                                  NULL,
                                                  &defused)) != 0) &&
                        (!defused)) {
                    if (*(s + count - 1) == '\0') {
                        count--;    /* don't count NUL */
                    }

                    return count;
                }

                errno = EILSEQ;
                return (size_t) - 1;
            } else {
                /* If MBCS, wchar_t to char mapping unknown */

                /* Assume that usually the buffer is large enough */
                if (((count = WideCharToMultiByte(_loc_update.GetLocaleT()->locinfo->lc_codepage,
                                                  0,
                                                  pwcs,
                                                  -1,
                                                  s,
                                                  (int)n,
                                                  NULL,
                                                  &defused)) != 0) &&
                        (!defused)) {
                    return count - 1; /* don't count NUL */
                }

                if (defused || GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
                    errno = EILSEQ;
                    return (size_t) - 1;
                }

                /* buffer not large enough, must do char by char */
                while (count < n) {
                    if (((retval = WideCharToMultiByte(_loc_update.GetLocaleT()->locinfo->lc_codepage,
                                                       0,
                                                       pwcs,
                                                       1,
                                                       buffer,
                                                       _loc_update.GetLocaleT()->locinfo->mb_cur_max,
                                                       NULL,
                                                       &defused)) == 0)
                            || defused) {
                        errno = EILSEQ;
                        return (size_t) - 1;
                    }

                    /* enforce this for prefast */
                    if (retval < 0 ||
                            retval > _countof(buffer)) {
                        errno = EILSEQ;
                        return (size_t) - 1;
                    }

                    if (count + retval > n) {
                        return count;
                    }

                    for (i = 0; i < retval; i++, count++) /* store character */
                        if ((s[count] = buffer[i]) == '\0') {
                            return count;
                        }

                    pwcs++;
                }

                return count;
            }
        }
    } else { /* s == NULL, get size only, pwcs must be NUL-terminated */
        if (_loc_update.GetLocaleT()->locinfo->lc_handle[LC_CTYPE] == _CLOCALEHANDLE) {
            return wcslen(pwcs);
        } else {
            if (((count = WideCharToMultiByte(_loc_update.GetLocaleT()->locinfo->lc_codepage,
                                              0,
                                              pwcs,
                                              -1,
                                              NULL,
                                              0,
                                              NULL,
                                              &defused)) == 0) ||
                    (defused)) {
                errno = EILSEQ;
                return (size_t) - 1;
            }

            return count - 1;
        }
    }
}
コード例 #2
0
ファイル: w_map.c プロジェクト: mysticTot/learn_c
static int __cdecl __crtLCMapStringW_stat(
    _locale_t plocinfo,
    LCID     Locale,
    DWORD    dwMapFlags,
    LPCWSTR  lpSrcStr,
    int      cchSrc,
    LPWSTR   lpDestStr,
    int      cchDest,
    int      code_page
) {
    static int f_use = 0;

    /*
     * Look for unstubbed 'preferred' flavor. Otherwise use available flavor.
     * Must actually call the function to ensure it's not a stub.
     */

    if (0 == f_use) {
        if (0 != LCMapStringW(0, LCMAP_LOWERCASE, L"\0", 1, NULL, 0)) {
            f_use = USE_W;
        } else if (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) {
            f_use = USE_A;
        }
    }

    /*
     * LCMapString will map past NULL. Must find NULL if in string
     * before cchSrc wide characters.
     */
    if (cchSrc > 0) {
        cchSrc = wcsncnt(lpSrcStr, cchSrc);
    }

    /* Use "W" version */

    if (USE_W == f_use) {
        return LCMapStringW(Locale, dwMapFlags, lpSrcStr, cchSrc,
                            lpDestStr, cchDest);
    }

    /* Use "A" version */

    if (USE_A == f_use || f_use == 0) {
        int retval = 0;
        int inbuff_size;
        int outbuff_size;
        unsigned char* inbuffer = NULL;
        unsigned char* outbuffer = NULL;
        int AnsiCP = 0;

        /*
         * Convert string and return the requested information. Note that
         * we are converting to a multibyte string so there is not a
         * one-to-one correspondence between number of wide chars in the
         * input string and the number of *bytes* in the buffer. However,
         * there had *better be* a one-to-one correspondence between the
         * number of wide characters and the number of multibyte characters
         * (enforced by WC_SEPCHARS) in the buffer or the resulting mapped
         * string will be worthless to the user.
         *
         */

        /*
         * Use __lc_codepage for conversion if code_page not specified
         */

        if (0 == Locale) {
            Locale = plocinfo->locinfo->lc_handle[LC_CTYPE];
        }

        if (0 == code_page) {
            code_page = plocinfo->locinfo->lc_codepage;
        }

        /*
         * Always use Ansi codepage with Ansi WinAPI because they use
         * Ansi codepage
         */
        if (code_page != (AnsiCP = __ansicp(Locale))) {
            if (AnsiCP != -1) {
                code_page = AnsiCP;
            }
        }

        /* find out how big a buffer we need (includes NULL if any) */
        if (0 == (inbuff_size = WideCharToMultiByte(code_page,
                                0,
                                lpSrcStr,
                                cchSrc,
                                NULL,
                                0,
                                NULL,
                                NULL))) {
            return 0;
        }

        /* allocate enough space for chars */
        inbuffer = (unsigned char*)_calloca(inbuff_size, sizeof(char));

        if (inbuffer == NULL) {
            return 0;
        }

        /* do the conversion */
        if (0 ==  WideCharToMultiByte(code_page,
                                      0,
                                      lpSrcStr,
                                      cchSrc,
                                      (char*)inbuffer,
                                      inbuff_size,
                                      NULL,
                                      NULL)) {
            goto error_cleanup;
        }

        /* get size required for string mapping */
        if (0 == (outbuff_size = LCMapStringA(Locale,
                                              dwMapFlags,
                                              (const char*)inbuffer,
                                              inbuff_size,
                                              NULL,
                                              0))) {
            goto error_cleanup;
        }

        /* allocate enough space for chars and NULL */
        outbuffer = (unsigned char*)_calloca(outbuff_size, sizeof(char));

        if (outbuffer == NULL) {
            goto error_cleanup;
        }

        /* do string mapping */
        if (0 == LCMapStringA(Locale,
                              dwMapFlags,
                              (const char*)inbuffer,
                              inbuff_size,
                              (char*)outbuffer,
                              outbuff_size)) {
            goto error_cleanup;
        }

        if (dwMapFlags & LCMAP_SORTKEY) {
            /* outbuff_size > cchDest is allowed */
            retval = outbuff_size;

            if (0 != cchDest)
                /* SORTKEY returns BYTES, just copy */
                _ERRCHECK(strncpy_s((char*)lpDestStr,
                                    cchDest,
                                    (char*)outbuffer,
                                    cchDest <= outbuff_size ? cchDest - 1 : outbuff_size));
        } else {
            if (0 == cchDest) {
                /* get size required */
                if (0 == (retval = MultiByteToWideChar(code_page,
                                                       MB_PRECOMPOSED,
                                                       (const char*)outbuffer,
                                                       outbuff_size,
                                                       NULL,
                                                       0))) {
                    goto error_cleanup;
                }
            } else {
                /* convert mapping */
                if (0 == (retval = MultiByteToWideChar(code_page,
                                                       MB_PRECOMPOSED,
                                                       (const char*)outbuffer,
                                                       outbuff_size,
                                                       lpDestStr,
                                                       cchDest))) {
                    goto error_cleanup;
                }
            }
        }

    error_cleanup:

        if (outbuffer != NULL) {
            _freea(outbuffer);
        }

        _freea(inbuffer);
        return retval;
    } else { /* f_use is neither USE_A nor USE_W */
        return 0;
    }
}
コード例 #3
0
int __cdecl __crtLCMapStringW(
        LCID     Locale,
        DWORD    dwMapFlags,
        LPCWSTR  lpSrcStr,
        int      cchSrc,
        LPWSTR   lpDestStr,
        int      cchDest,
        int      code_page
        )
{
        static int f_use = 0;

        /*
         * Look for unstubbed 'preferred' flavor. Otherwise use available flavor.
         * Must actually call the function to ensure it's not a stub.
         */

        if (0 == f_use) {
            if (0 != LCMapStringW(0, LCMAP_LOWERCASE, L"\0", 1, NULL, 0))
                f_use = USE_W;
            else if (0 != LCMapStringA(0, LCMAP_LOWERCASE, "\0", 1, NULL, 0))
                f_use = USE_A;
            else
                return 0;
        }

        /*
         * LCMapString will map past NULL. Must find NULL if in string
         * before cchSrc wide characters.
         */
        if (cchSrc > 0)
            cchSrc = wcsncnt(lpSrcStr, cchSrc);

        /* Use "W" version */

        if (USE_W == f_use) {
            return LCMapStringW( Locale, dwMapFlags, lpSrcStr, cchSrc,
                                 lpDestStr, cchDest );
        }

        /* Use "A" version */

        if (USE_A == f_use) {

            int retval;
            int inbuff_size;
            int outbuff_size;
            unsigned char *inbuffer;
            unsigned char *outbuffer;

            /*
             * Convert string and return the requested information. Note that
             * we are converting to a multibyte string so there is not a
             * one-to-one correspondence between number of wide chars in the
             * input string and the number of *bytes* in the buffer. However,
             * there had *better be* a one-to-one correspondence between the
             * number of wide characters and the number of multibyte characters
             * (enforced by WC_SEPCHARS) in the buffer or the resulting mapped
             * string will be worthless to the user.
             *
             */

            /*
             * Use __lc_codepage for conversion if code_page not specified
             */

            if (0 == code_page)
                code_page = __lc_codepage;

            /* find out how big a buffer we need (includes NULL if any) */
            if ( 0 == (inbuff_size = WideCharToMultiByte( code_page,
                                                          WC_COMPOSITECHECK |
                                                            WC_SEPCHARS,
                                                          lpSrcStr,
                                                          cchSrc,
                                                          NULL,
                                                          0,
                                                          NULL,
                                                          NULL )) )
                return 0;

            /* allocate enough space for chars */
            __try {
                inbuffer = (unsigned char *)_alloca( inbuff_size * sizeof(char) );
            }
            __except(EXCEPTION_EXECUTE_HANDLER) {
                inbuffer = NULL;
            }

            if ( inbuffer == NULL )
                return 0;

            /* do the conversion */
            if ( 0 ==  WideCharToMultiByte( code_page,
                                            WC_COMPOSITECHECK | WC_SEPCHARS,
                                            lpSrcStr,
                                            cchSrc,
                                            inbuffer,
                                            inbuff_size,
                                            NULL,
                                            NULL ) )
                return 0;

            /* get size required for string mapping */
            if ( 0 == (outbuff_size = LCMapStringA( Locale,
                                                    dwMapFlags,
                                                    inbuffer,
                                                    inbuff_size,
                                                    NULL,
                                                    0 )) )
                return 0;

            /* allocate enough space for chars and NULL */
            __try {
                outbuffer = (unsigned char *)_alloca( outbuff_size * sizeof(char) );
            }
            __except(EXCEPTION_EXECUTE_HANDLER) {
                outbuffer = NULL;
            }

            if ( outbuffer == NULL )
                return 0;

            /* do string mapping */
            if ( 0 == LCMapStringA( Locale,
                                    dwMapFlags,
                                    inbuffer,
                                    inbuff_size,
                                    outbuffer,
                                    outbuff_size ) )
                return 0;

            if (dwMapFlags & LCMAP_SORTKEY) {

                /* outbuff_size > cchDest is allowed */
                retval = outbuff_size;

                if (0 != cchDest)
                    /* SORTKEY returns BYTES, just copy */
                    strncpy( (char *)lpDestStr,
                             (char *)outbuffer,
                             cchDest < outbuff_size ? cchDest : outbuff_size );
            }
            else {
                if (0 == cchDest) {
                    /* get size required */
                    if ( 0 == (retval = MultiByteToWideChar( code_page,
                                                             MB_PRECOMPOSED,
                                                             outbuffer,
                                                             outbuff_size,
                                                             NULL,
                                                             0 )) )
                        return 0;
                }
                else {
                    /* convert mapping */
                    if ( 0 == (retval = MultiByteToWideChar( code_page,
                                                             MB_PRECOMPOSED,
                                                             outbuffer,
                                                             outbuff_size,
                                                             lpDestStr,
                                                             cchDest )) )
                        return 0;
                }
            }

            return retval;
        }
コード例 #4
0
int __cdecl __crtCompareStringW(
        LCID     Locale,
        DWORD    dwCmpFlags,
        LPCWSTR  lpString1,
        int      cchCount1,
        LPCWSTR  lpString2,
        int      cchCount2,
        int      code_page
        )
{
        static int f_use = 0;

        /*
         * Look for unstubbed 'preferred' flavor. Otherwise use available flavor.
         * Must actually call the function to ensure it's not a stub.
         */

        if (0 == f_use)
        {
            if (0 != CompareStringW(0, 0, L"\0", 1, L"\0", 1))
                f_use = USE_W;

            else if (0 != CompareStringA(0, 0, "\0", 1, "\0", 1))
                f_use = USE_A;

            else
                return 0;
        }

        /*
         * CompareString will compare past NULL. Must find NULL if in string
         * before cchCountn wide characters.
         */

        if (cchCount1 > 0)
            cchCount1= wcsncnt(lpString1, cchCount1);
        if (cchCount2 > 0)
            cchCount2= wcsncnt(lpString2, cchCount2);

        if (!cchCount1 || !cchCount2)
            return (cchCount1 - cchCount2 == 0) ? 2 :
                   (cchCount1 - cchCount2 < 0) ? 1 : 3;

        /* Use "W" version */

        if (USE_W == f_use)
        {
            return CompareStringW( Locale,
                                   dwCmpFlags,
                                   lpString1,
                                   cchCount1,
                                   lpString2,
                                   cchCount2 );
        }

        /* Use "A" version */

        if (USE_A == f_use)
        {
            int buff_size1;
            int buff_size2;
            unsigned char *buffer1;
            unsigned char *buffer2;

            /*
             * Use __lc_codepage for conversion if code_page not specified
             */

            if (0 == code_page)
                code_page = __lc_codepage;

            /*
             * Convert strings and return the requested information.
             */

            /* find out how big a buffer we need (includes NULL if any) */
            if ( 0 == (buff_size1 = WideCharToMultiByte( code_page,
                                                         WC_COMPOSITECHECK |
                                                            WC_SEPCHARS,
                                                         lpString1,
                                                         cchCount1,
                                                         NULL,
                                                         0,
                                                         NULL,
                                                         NULL )) )
                return 0;

            /* allocate enough space for chars */
            __try {
                buffer1 = (unsigned char *)_alloca( buff_size1 * sizeof(char) );
            }
            __except( EXCEPTION_EXECUTE_HANDLER ) {
                buffer1 = NULL;
            }

            if ( buffer1 == NULL )
                return 0;

            /* do the conversion */
            if ( 0 == WideCharToMultiByte( code_page,
                                           WC_COMPOSITECHECK | WC_SEPCHARS,
                                           lpString1,
                                           cchCount1,
                                           buffer1,
                                           buff_size1,
                                           NULL,
                                           NULL ) )
                return 0;

            /* find out how big a buffer we need (includes NULL if any) */
            if ( 0 == (buff_size2 = WideCharToMultiByte( code_page,
                                                         WC_COMPOSITECHECK |
                                                            WC_SEPCHARS,
                                                         lpString2,
                                                         cchCount2,
                                                         NULL,
                                                         0,
                                                         NULL,
                                                         NULL )) )
                return 0;

            /* allocate enough space for chars */
            __try {
                buffer2 = (unsigned char *)_alloca( buff_size2 * sizeof(char) );
            }
            __except( EXCEPTION_EXECUTE_HANDLER ) {
                buffer2 = NULL;
            }

            if ( buffer2 == NULL )
                return 0;

            /* do the conversion */
            if ( 0 == WideCharToMultiByte( code_page,
                                           WC_COMPOSITECHECK | WC_SEPCHARS,
                                           lpString2,
                                           cchCount2,
                                           buffer2,
                                           buff_size2,
                                           NULL,
                                           NULL ) )
                return 0;

            return CompareStringA( Locale,
                                   dwCmpFlags,
                                   buffer1,
                                   buff_size1,
                                   buffer2,
                                   buff_size2 );
        }
コード例 #5
0
ファイル: wcstombs.c プロジェクト: chunhualiu/OpenNT
size_t __cdecl _wcstombs_lk
#else
size_t __cdecl wcstombs
#endif
        (
        char * s,
        const wchar_t * pwcs,
        size_t n
        )
{
        size_t count = 0;
#ifdef _WIN32
        int i, retval;
        char buffer[MB_LEN_MAX];
        BOOL defused = 0;
#endif
        if (s && n == 0)
            /* dest string exists, but 0 bytes converted */
            return (size_t) 0;

        _ASSERTE(pwcs != NULL);

#ifdef _WIN32
#if !defined( _NTSUBSET_ ) && !defined(_POSIX_)

        /* if destination string exists, fill it in */
        if (s)
        {
            if (__lc_handle[LC_CTYPE] == _CLOCALEHANDLE)
            {
                /* C locale: easy and fast */
                while(count < n)
                {
                    if (*pwcs > 255)  /* validate high byte */
                    {
                        errno = EILSEQ;
                        return (size_t)-1;  /* error */
                    }
                    s[count] = (char) *pwcs;
                    if (*pwcs++ == L'\0')
                        return count;
                    count++;
                }
                return count;
            } else {

                if (1 == MB_CUR_MAX)
                {
                    /* If SBCS, one wchar_t maps to one char */

                    /* WideCharToMultiByte will compare past NULL - reset n */
                    if (n > 0)
                        n = wcsncnt(pwcs, n);

                    if (((count=WideCharToMultiByte(__lc_codepage,
                        WC_COMPOSITECHECK | WC_SEPCHARS,
                        pwcs, n, s, n, NULL, &defused)) != 0) && (!defused))
                    {
                        if (*(s+count-1) == '\0')
                            count--; /* don't count NUL */

                        return count;
                    }

                    errno = EILSEQ;
                    return (size_t)-1;
                }
                else {

                    /* If MBCS, wchar_t to char mapping unknown */

                    /* Assume that usually the buffer is large enough */
                    if (((count=WideCharToMultiByte(__lc_codepage,
                        WC_COMPOSITECHECK | WC_SEPCHARS,
                        pwcs, -1, s, n, NULL, &defused)) != 0) && (!defused))
                    {
                        return count - 1; /* don't count NUL */
                    }

                    if (defused || GetLastError() != ERROR_INSUFFICIENT_BUFFER)
                    {
                        errno = EILSEQ;
                        return (size_t)-1;
                    }

                    /* buffer not large enough, must do char by char */
                    while (count < n)
                    {
                        if (((retval = WideCharToMultiByte (__lc_codepage, 0,
                        pwcs, 1, buffer, MB_CUR_MAX, NULL, &defused)) == 0) || defused)
                        {
                            errno = EILSEQ;
                            return (size_t)-1;
                        }

                        if (count + retval > n)
                            return count;

                        for (i = 0; i < retval; i++, count++) /* store character */
                            if((s[count] = buffer[i])=='\0')
                                return count;

                        pwcs++;
                    }

                    return count;
                }
            }
        }
        else { /* s == NULL, get size only, pwcs must be NUL-terminated */

            if (__lc_handle[LC_CTYPE] == _CLOCALEHANDLE)
                return wcslen(pwcs);
            else {
                if (((count=WideCharToMultiByte(__lc_codepage,
                WC_COMPOSITECHECK | WC_SEPCHARS,
                pwcs, -1, NULL, 0, NULL, &defused)) == 0) || (defused))
                {
                    errno = EILSEQ;
                    return (size_t)-1;
                }

                return count - 1;
            }
        }

#else /* _NTSUBSET_/_POSIX_ */

        /* if destination string exists, fill it in */
        if (s)
        {
            NTSTATUS Status;

            Status = RtlUnicodeToMultiByteN(s, n, (PULONG)&count, (wchar_t *)pwcs, (wcslen(pwcs)+1)*sizeof(WCHAR));

            if (NT_SUCCESS(Status))
            {
                return count - 1; /* don't count NUL */
            } else {
                errno = EILSEQ;
                count = (size_t)-1;
            }
        } else { /* s == NULL, get size only, pwcs must be NUL-terminated */
            NTSTATUS Status;

            Status = RtlUnicodeToMultiByteSize((PULONG)&count, (wchar_t *)pwcs, (wcslen(pwcs)+1)*sizeof(WCHAR));

            if (NT_SUCCESS(Status))
            {
                return count - 1; /* don't count NUL */
            } else {
                errno = EILSEQ;
                count = (size_t)-1;
            }
        }

#endif  /* _NTSUBSET_/_POSIX_ */
#else /* _WIN32 */

        /* if destination string exists, fill it in */
        if (s)
        {
            /* C locale: easy and fast */
            while(count < n)
            {
                if (*pwcs > 255)  /* validate high byte */
                {
                    errno = EILSEQ;
                    return (size_t)-1;  /* error */
                }
                s[count] = (char) *pwcs;
                if (*pwcs++ == L'\0')
                    return count;
                count++;
            }
            return count;

        } else { /* s == NULL, get size only, pwcs must be NUL-terminated */
	    const wchar_t *eos = pwcs;

	    while( *eos++ ) ;

	    return( (size_t)(eos - pwcs - 1) );
        }

#endif /* _WIN32 */
}