Ignore:
Timestamp:
Jan 29, 2022, 3:39:47 AM (3 years ago)
Author:
bird
Message:

lib: Changed the console-optimization wrappers to use the get_crt_codepage() function as that's more appropriate than GetConsoleCP() for use with _cputws(). Also made them avoid the heap for smaller writes that could fit into a reasonable (2KiB) stack buffer.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/lib/maybe_con_fwrite.c

    r3188 r3547  
    5757#ifdef KBUILD_OS_WINDOWS
    5858    /*
    59      * If it's a TTY, do our own conversion to wide char and
    60      * call WriteConsoleW directly.
     59     * If it's a TTY, do our own conversion to wide char and call _cputws.
    6160     */
    6261    if (   cbUnit > 0
    6362        && cUnits > 0
     63        && cbUnit < (unsigned)INT_MAX / 4
     64        && cUnits < (unsigned)INT_MAX / 4
    6465        && (pFile == stdout || pFile == stderr))
    6566    {
     
    7374                if (is_console_handle((intptr_t)hCon))
    7475                {
    75                     size_t   cbToWrite = cbUnit * cUnits;
    76                     size_t   cwcTmp    = cbToWrite * 2 + 16;
    77                     wchar_t *pawcTmp   = (wchar_t *)malloc(cwcTmp * sizeof(wchar_t));
    78                     if (pawcTmp)
     76                    /* Use a stack buffer if we can, falling back on the heap for larger writes: */
     77                    wchar_t  awcBuf[1024];
     78                    wchar_t *pawcBuf;
     79                    wchar_t *pawcBufFree = NULL;
     80                    size_t   cbToWrite   = cbUnit * cUnits;
     81                    size_t   cwcBuf      = cbToWrite * 2 + 16;
     82                    if (cwcBuf < sizeof(awcBuf) / sizeof(awcBuf[0]))
    7983                    {
    80                         int           cwcToWrite;
    81                         static UINT s_uConsoleCp = 0;
    82                         if (s_uConsoleCp == 0)
    83                             s_uConsoleCp = GetConsoleCP();
    84 
    85                         cwcToWrite = MultiByteToWideChar(s_uConsoleCp, 0 /*dwFlags*/, pvBuf, (int)cbToWrite,
    86                                                          pawcTmp, (int)(cwcTmp - 1));
     84                        pawcBuf = awcBuf;
     85                        cwcBuf  = sizeof(awcBuf) / sizeof(awcBuf[0]);
     86                    }
     87                    else
     88                        pawcBufFree = pawcBuf = (wchar_t *)malloc(cwcBuf * sizeof(wchar_t));
     89                    if (pawcBuf)
     90                    {
     91                        int cwcToWrite = MultiByteToWideChar(get_crt_codepage(), 0 /*dwFlags*/,
     92                                                             pvBuf, (int)cbToWrite,
     93                                                             pawcBuf, (int)(cwcBuf - 1));
    8794                        if (cwcToWrite > 0)
    8895                        {
    8996                            int rc;
    90                             pawcTmp[cwcToWrite] = '\0';
     97                            pawcBuf[cwcToWrite] = '\0';
    9198
    9299                            /* Let the CRT do the rest.  At least the Visual C++ 2010 CRT
    93100                               sources indicates _cputws will do the right thing.  */
    94101                            fflush(pFile);
    95                             rc = _cputws(pawcTmp);
    96                             free(pawcTmp);
     102                            rc = _cputws(pawcBuf);
     103                            if (pawcBufFree)
     104                                free(pawcBufFree);
    97105                            if (rc >= 0)
    98106                                return cUnits;
    99107                            return 0;
    100108                        }
    101                         free(pawcTmp);
     109                        free(pawcBufFree);
    102110                    }
    103111                }
Note: See TracChangeset for help on using the changeset viewer.