diff --git a/src/core/iomgr/tcp_windows.c b/src/core/iomgr/tcp_windows.c index 5ff78231bd7..db8e7f56fe9 100644 --- a/src/core/iomgr/tcp_windows.c +++ b/src/core/iomgr/tcp_windows.c @@ -197,7 +197,7 @@ static void win_read(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep, tcp->read_slice = gpr_slice_malloc(8192); - buffer.len = GPR_SLICE_LENGTH(tcp->read_slice); + buffer.len = (ULONG)GPR_SLICE_LENGTH(tcp->read_slice); // we know slice size fits in 32bit. buffer.buf = (char *)GPR_SLICE_START_PTR(tcp->read_slice); TCP_REF(tcp, "read"); @@ -282,18 +282,20 @@ static void win_write(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep, tcp->write_cb = cb; tcp->write_slices = slices; + GPR_ASSERT((tcp->write_slices->count >> 32) == 0); if (tcp->write_slices->count > GPR_ARRAY_SIZE(local_buffers)) { buffers = (WSABUF *)gpr_malloc(sizeof(WSABUF) * tcp->write_slices->count); allocated = buffers; } for (i = 0; i < tcp->write_slices->count; i++) { - buffers[i].len = GPR_SLICE_LENGTH(tcp->write_slices->slices[i]); + GPR_ASSERT((GPR_SLICE_LENGTH(tcp->write_slices->slices[i]) >> 32) == 0); + buffers[i].len = (ULONG) GPR_SLICE_LENGTH(tcp->write_slices->slices[i]); buffers[i].buf = (char *)GPR_SLICE_START_PTR(tcp->write_slices->slices[i]); } /* First, let's try a synchronous, non-blocking write. */ - status = WSASend(socket->socket, buffers, tcp->write_slices->count, + status = WSASend(socket->socket, buffers, (DWORD)tcp->write_slices->count, &bytes_sent, 0, NULL, NULL); info->wsa_error = status == 0 ? 0 : WSAGetLastError(); @@ -322,7 +324,7 @@ static void win_write(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep, /* If we got a WSAEWOULDBLOCK earlier, then we need to re-do the same operation, this time asynchronously. */ memset(&socket->write_info.overlapped, 0, sizeof(OVERLAPPED)); - status = WSASend(socket->socket, buffers, tcp->write_slices->count, + status = WSASend(socket->socket, buffers, (DWORD)tcp->write_slices->count, &bytes_sent, 0, &socket->write_info.overlapped, NULL); if (allocated) gpr_free(allocated); diff --git a/src/core/support/string.c b/src/core/support/string.c index e0ffeb8a4af..fad0b4008bd 100644 --- a/src/core/support/string.c +++ b/src/core/support/string.c @@ -173,6 +173,27 @@ int gpr_ltoa(long value, char *string) { return i; } +int gpr_int64toa(gpr_int64 value, char *string) { + int i = 0; + int neg = value < 0; + + if (value == 0) { + string[0] = '0'; + string[1] = 0; + return 1; + } + + if (neg) value = -value; + while (value) { + string[i++] = (char)('0' + value % 10); + value /= 10; + } + if (neg) string[i++] = '-'; + gpr_reverse_bytes(string, i); + string[i] = 0; + return i; +} + char *gpr_strjoin(const char **strs, size_t nstrs, size_t *final_length) { return gpr_strjoin_sep(strs, nstrs, "", final_length); } diff --git a/src/core/support/string.h b/src/core/support/string.h index a28e00fd3ec..9b604ac5bf5 100644 --- a/src/core/support/string.h +++ b/src/core/support/string.h @@ -70,6 +70,16 @@ int gpr_parse_bytes_to_uint32(const char *data, size_t length, output must be at least GPR_LTOA_MIN_BUFSIZE bytes long. */ int gpr_ltoa(long value, char *output); +/* Minimum buffer size for calling int64toa */ +#define GPR_INT64TOA_MIN_BUFSIZE (3 * sizeof(gpr_int64)) + +/* Convert an int64 to a string in base 10; returns the length of the +output string (or 0 on failure). +output must be at least GPR_INT64TOA_MIN_BUFSIZE bytes long. +NOTE: This function ensures sufficient bit width even on Win x64, +where long is 32bit is size.*/ +int gpr_int64toa(gpr_int64 value, char *output); + /* Reverse a run of bytes */ void gpr_reverse_bytes(char *str, int len); diff --git a/src/core/transport/chttp2/timeout_encoding.c b/src/core/transport/chttp2/timeout_encoding.c index 8a9b290ecb9..cf81c18a20b 100644 --- a/src/core/transport/chttp2/timeout_encoding.c +++ b/src/core/transport/chttp2/timeout_encoding.c @@ -36,6 +36,7 @@ #include #include +#include #include "src/core/support/string.h" static int round_up(int x, int divisor) { @@ -57,13 +58,13 @@ static int round_up_to_three_sig_figs(int x) { /* encode our minimum viable timeout value */ static void enc_tiny(char *buffer) { memcpy(buffer, "1n", 3); } -static void enc_ext(char *buffer, long value, char ext) { - int n = gpr_ltoa(value, buffer); +static void enc_ext(char *buffer, gpr_int64 value, char ext) { + int n = gpr_int64toa(value, buffer); buffer[n] = ext; buffer[n + 1] = 0; } -static void enc_seconds(char *buffer, long sec) { +static void enc_seconds(char *buffer, gpr_int64 sec) { if (sec % 3600 == 0) { enc_ext(buffer, sec / 3600, 'H'); } else if (sec % 60 == 0) {