mirror of
https://github.com/curl/curl.git
synced 2026-01-18 17:21:26 +01:00
tool_cb_wrt: stop alloc/free for every chunk windows console output
Instead realloc to the largest buffer and keep that for reuse during the entire lifetime. Co-authored-by: Jay Satiro <raysatiro@yahoo.com> Closes #18233
This commit is contained in:
@@ -115,8 +115,7 @@ static size_t win_console(intptr_t fhnd, struct OutStruct *outs,
|
||||
char *buffer, size_t bytes,
|
||||
size_t *retp)
|
||||
{
|
||||
wchar_t *wc_buf;
|
||||
DWORD wc_len, chars_written;
|
||||
DWORD chars_written;
|
||||
unsigned char *rbuf = (unsigned char *)buffer;
|
||||
DWORD rlen = (DWORD)bytes;
|
||||
|
||||
@@ -206,27 +205,30 @@ static size_t win_console(intptr_t fhnd, struct OutStruct *outs,
|
||||
|
||||
if(rlen) {
|
||||
/* calculate buffer size for wide characters */
|
||||
wc_len = (DWORD)MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)rbuf, (int)rlen,
|
||||
NULL, 0);
|
||||
if(!wc_len)
|
||||
DWORD len = (DWORD)MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)rbuf,
|
||||
(int)rlen, NULL, 0);
|
||||
if(!len)
|
||||
return CURL_WRITEFUNC_ERROR;
|
||||
|
||||
wc_buf = (wchar_t*) malloc(wc_len * sizeof(wchar_t));
|
||||
if(!wc_buf)
|
||||
return CURL_WRITEFUNC_ERROR;
|
||||
|
||||
wc_len = (DWORD)MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)rbuf, (int)rlen,
|
||||
wc_buf, (int)wc_len);
|
||||
if(!wc_len) {
|
||||
free(wc_buf);
|
||||
return CURL_WRITEFUNC_ERROR;
|
||||
/* grow the buffer if needed */
|
||||
if(len > global->term.len) {
|
||||
wchar_t *buf = (wchar_t *) realloc(global->term.buf,
|
||||
len * sizeof(wchar_t));
|
||||
if(!buf)
|
||||
return CURL_WRITEFUNC_ERROR;
|
||||
global->term.len = len;
|
||||
global->term.buf = buf;
|
||||
}
|
||||
|
||||
if(!WriteConsoleW((HANDLE) fhnd, wc_buf, wc_len, &chars_written, NULL)) {
|
||||
free(wc_buf);
|
||||
len = (DWORD)MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)rbuf, (int)rlen,
|
||||
global->term.buf,
|
||||
(int)len);
|
||||
if(!len)
|
||||
return CURL_WRITEFUNC_ERROR;
|
||||
|
||||
if(!WriteConsoleW((HANDLE) fhnd, global->term.buf,
|
||||
len, &chars_written, NULL))
|
||||
return CURL_WRITEFUNC_ERROR;
|
||||
}
|
||||
free(wc_buf);
|
||||
}
|
||||
|
||||
*retp = bytes;
|
||||
|
||||
@@ -263,6 +263,9 @@ static void free_globalconfig(void)
|
||||
global->trace_stream = NULL;
|
||||
|
||||
tool_safefree(global->libcurl);
|
||||
#if defined(_WIN32) && !defined(UNDER_CE)
|
||||
free(global->term.buf);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -339,6 +339,13 @@ struct OperationConfig {
|
||||
BIT(skip_existing);
|
||||
};
|
||||
|
||||
#if defined(_WIN32) && !defined(UNDER_CE)
|
||||
struct termout {
|
||||
wchar_t *buf;
|
||||
DWORD len;
|
||||
};
|
||||
#endif
|
||||
|
||||
struct GlobalConfig {
|
||||
struct State state; /* for create_transfer() */
|
||||
char *trace_dump; /* file to dump the network trace to */
|
||||
@@ -351,6 +358,9 @@ struct GlobalConfig {
|
||||
struct OperationConfig *first;
|
||||
struct OperationConfig *current;
|
||||
struct OperationConfig *last;
|
||||
#if defined(_WIN32) && !defined(UNDER_CE)
|
||||
struct termout term;
|
||||
#endif
|
||||
timediff_t ms_per_transfer; /* start next transfer after (at least) this
|
||||
many milliseconds */
|
||||
trace tracetype;
|
||||
|
||||
Reference in New Issue
Block a user