From 8ac0efa85d836815cfbb5016bb387bc21ab18f37 Mon Sep 17 00:00:00 2001 From: Simon Rozman Date: Wed, 14 Feb 2024 10:42:38 +0100 Subject: [PATCH] Xcode: resolve -Wsign-compare Signed-off-by: Simon Rozman --- UnitTests/UnitTests.xcodeproj/project.pbxproj | 4 + include/stdex/base64.hpp | 10 +- include/stdex/endian.hpp | 12 +- include/stdex/idrec.hpp | 18 +-- include/stdex/parser.hpp | 30 ++--- include/stdex/sgml.hpp | 30 +++-- include/stdex/stream.hpp | 121 +++++++++++------- include/stdex/string.hpp | 34 ++--- include/stdex/wav.hpp | 8 +- 9 files changed, 154 insertions(+), 113 deletions(-) diff --git a/UnitTests/UnitTests.xcodeproj/project.pbxproj b/UnitTests/UnitTests.xcodeproj/project.pbxproj index aac53946e..ec5876e26 100644 --- a/UnitTests/UnitTests.xcodeproj/project.pbxproj +++ b/UnitTests/UnitTests.xcodeproj/project.pbxproj @@ -290,6 +290,7 @@ CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_IMPLICIT_SIGN_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; @@ -316,6 +317,7 @@ ); GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_SIGN_COMPARE = YES; GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNKNOWN_PRAGMAS = YES; @@ -350,6 +352,7 @@ CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_IMPLICIT_SIGN_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; @@ -374,6 +377,7 @@ ); GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_SIGN_COMPARE = YES; GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNKNOWN_PRAGMAS = YES; diff --git a/include/stdex/base64.hpp b/include/stdex/base64.hpp index 98717c75a..30aa902b7 100644 --- a/include/stdex/base64.hpp +++ b/include/stdex/base64.hpp @@ -1,4 +1,4 @@ -/* +/* SPDX-License-Identifier: MIT Copyright © 2016-2024 Amebis */ @@ -317,7 +317,7 @@ namespace stdex if (i >= size) break; - int x = data[i]; + size_t x = static_cast(data[i]); if ((m_buf[m_num] = x < _countof(base64_dec_lookup) ? base64_dec_lookup[x] : 255) != 255) m_num++; } @@ -435,11 +435,11 @@ namespace stdex { m_num = 0; m_temp_off = 0; - m_temp[0] = ((m_buf[0] << 2) | (m_buf[1] >> 4)) & 0xff; + m_temp[0] = static_cast(((m_buf[0] << 2) | (m_buf[1] >> 4)) & 0xff); if (m_buf[2] < 64) { - m_temp[1] = ((m_buf[1] << 4) | (m_buf[2] >> 2)) & 0xff; + m_temp[1] = static_cast(((m_buf[1] << 4) | (m_buf[2] >> 2)) & 0xff); if (m_buf[3] < 64) { - m_temp[2] = ((m_buf[2] << 6) | m_buf[3]) & 0xff; + m_temp[2] = static_cast(((m_buf[2] << 6) | m_buf[3]) & 0xff); m_temp_len = 3; } else m_temp_len = 2; diff --git a/include/stdex/endian.hpp b/include/stdex/endian.hpp index 32e7dc318..ea4fd92f1 100644 --- a/include/stdex/endian.hpp +++ b/include/stdex/endian.hpp @@ -1,4 +1,4 @@ -/* +/* SPDX-License-Identifier: MIT Copyright © 2023-2024 Amebis */ @@ -95,11 +95,11 @@ namespace stdex #endif } - inline constexpr int8_t byteswap(_In_ const char value) { return byteswap(static_cast(value)); } - inline constexpr int8_t byteswap(_In_ const int8_t value) { return byteswap(static_cast(value)); } - inline int16_t byteswap(_In_ const int16_t value) { return byteswap(static_cast(value)); } - inline int32_t byteswap(_In_ const int32_t value) { return byteswap(static_cast(value)); } - inline int64_t byteswap(_In_ const int64_t value) { return byteswap(static_cast(value)); } + inline constexpr int8_t byteswap(_In_ const char value) { return static_cast(byteswap(static_cast(value))); } + inline constexpr int8_t byteswap(_In_ const int8_t value) { return static_cast(byteswap(static_cast(value))); } + inline int16_t byteswap(_In_ const int16_t value) { return static_cast(byteswap(static_cast(value))); } + inline int32_t byteswap(_In_ const int32_t value) { return static_cast(byteswap(static_cast(value))); } + inline int64_t byteswap(_In_ const int64_t value) { return static_cast(byteswap(static_cast(value))); } inline float byteswap(_In_ const float value) { diff --git a/include/stdex/idrec.hpp b/include/stdex/idrec.hpp index 0e3dc372c..db6052037 100644 --- a/include/stdex/idrec.hpp +++ b/include/stdex/idrec.hpp @@ -1,4 +1,4 @@ -/* +/* SPDX-License-Identifier: MIT Copyright © 2016-2024 Amebis */ @@ -276,9 +276,9 @@ namespace stdex { // Update the data size. if (!stream.ok()) _Unlikely_ return stdex::stream::fpos_max; - stream.seek(start + sizeof(T_id)); + stream.seekbeg(start + sizeof(T_id)); stream << size; - stream.seek(end); + stream.seekbeg(end); return end; } @@ -344,7 +344,7 @@ namespace stdex { /// /// \returns Position of the record header start in \p stream. Save for later \c close call. /// - static stdex::stream::foff_t open(_In_ stdex::stream::basic_file& stream) + static stdex::stream::fpos_t open(_In_ stdex::stream::basic_file& stream) { return stdex::idrec::open(stream, ID); } @@ -370,7 +370,7 @@ namespace stdex { /// /// \returns Position of the record end in \p stream /// - static stdex::stream::foff_t close(_In_ stdex::stream::basic_file& stream, _In_ stdex::stream::foff_t start) + static stdex::stream::fpos_t close(_In_ stdex::stream::basic_file& stream, _In_ stdex::stream::fpos_t start) { return stdex::idrec::close(stream, start); } @@ -394,13 +394,13 @@ namespace stdex { /// Finds record data /// /// \param[in] stream Input stream - /// \param[in] end Position limit. Default is -1 (no limit). + /// \param[in] end Position limit. Default is stdex::stream::fpos_max (no limit). /// /// \returns /// - \c true when found /// - \c false otherwise /// - static bool find(_In_ stdex::stream::basic_file& stream, _In_opt_ stdex::stream::foff_t end = stdex::stream::foff_max) + static bool find(_In_ stdex::stream::basic_file& stream, _In_opt_ stdex::stream::fpos_t end = stdex::stream::fpos_max) { return stdex::idrec::find(stream, ID, end); } @@ -464,7 +464,7 @@ namespace stdex { if (!temp.ok()) _Unlikely_ return stream; temp << r.data; r.close(temp, start); - temp.seek(0); + temp.seekbeg(0); stream.write_stream(temp); return stream; @@ -524,7 +524,7 @@ namespace stdex { } size += padding(size); - stream.seek(start + size); + stream.seekbeg(start + static_cast(size)); return stream; } diff --git a/include/stdex/parser.hpp b/include/stdex/parser.hpp index 0d81da53d..a33657fb1 100644 --- a/include/stdex/parser.hpp +++ b/include/stdex/parser.hpp @@ -141,11 +141,11 @@ namespace stdex size_t n = chr_end - start - 1; if (n >= 2 && text[start + 1] == '#') { // Numerical entity - char32_t unicode; + utf32_t unicode; if (text[start + 2] == 'x' || text[start + 2] == 'X') - unicode = strtou32(text + start + 3, n - 2, nullptr, 16); + unicode = static_cast(strtou32(text + start + 3, n - 2, nullptr, 16)); else - unicode = strtou32(text + start + 2, n - 1, nullptr, 10); + unicode = static_cast(strtou32(text + start + 2, n - 1, nullptr, 10)); #ifdef _WIN32 if (unicode < 0x10000) { buf[0] = (wchar_t)unicode; @@ -4911,7 +4911,7 @@ namespace stdex } size_t digit_count = nominator == 0 ? 0 : nominator < 10 ? 1 : 2; for (; digit_count < 9 && normalized[next]; ++next, ++digit_count) - nominator = nominator * 10 + (normalized[next] - '0'); + nominator = nominator * 10 + static_cast(normalized[next] - '0'); } this->interval.start = start; @@ -5059,7 +5059,7 @@ namespace stdex } size_t digit_count = nominator == 0 ? 0 : nominator < 10 ? 1 : 2; for (; digit_count < 9 && normalized[next]; ++next, ++digit_count) - nominator = nominator * 10 + (normalized[next] - '0'); + nominator = nominator * 10 + static_cast(normalized[next] - '0'); } this->interval.start = start; @@ -5443,7 +5443,7 @@ namespace stdex _Assume_(part1 && num_part1 >= 1); uint32_t nominator = 0, ponder = 2; for (size_t i = num_part1 - 1; i--; ++ponder) - nominator += (part1[i] - '0') * ponder; + nominator += static_cast(part1[i] - '0') * ponder; uint8_t control = 11 - static_cast(nominator % 11); if (control >= 10) control = 0; @@ -5458,9 +5458,9 @@ namespace stdex _Assume_(part2 && num_part2 >= 1); uint32_t nominator = 0, ponder = 2; for (size_t i = num_part2 - 1; i--; ++ponder) - nominator += (part2[i] - '0') * ponder; + nominator += static_cast(part2[i] - '0') * ponder; for (size_t i = num_part1; i--; ++ponder) - nominator += (part1[i] - '0') * ponder; + nominator += static_cast(part1[i] - '0') * ponder; uint8_t control = 11 - static_cast(nominator % 11); if (control == 10) control = 0; @@ -5477,11 +5477,11 @@ namespace stdex _Assume_(part3 && num_part3 >= 1); uint32_t nominator = 0, ponder = 2; for (size_t i = num_part3 - 1; i--; ++ponder) - nominator += (part3[i] - '0') * ponder; + nominator += static_cast(part3[i] - '0') * ponder; for (size_t i = num_part2; i--; ++ponder) - nominator += (part2[i] - '0') * ponder; + nominator += static_cast(part2[i] - '0') * ponder; for (size_t i = num_part1; i--; ++ponder) - nominator += (part1[i] - '0') * ponder; + nominator += static_cast(part1[i] - '0') * ponder; uint8_t control = 11 - static_cast(nominator % 11); if (control == 10) control = 0; @@ -6109,8 +6109,8 @@ namespace stdex for (;;) { if (this->interval.end < end && text[this->interval.end]) { if ('0' <= text[this->interval.end] && text[this->interval.end] <= '9') { - size_t _value = (size_t)value * 10 + text[this->interval.end] - '0'; - if (_value > (uint16_t)-1) { + size_t _value = static_cast(value) * 10 + static_cast(text[this->interval.end] - '0'); + if (_value > UINT16_MAX) { value = 0; this->interval.invalidate(); return false; @@ -6491,7 +6491,7 @@ namespace stdex for (;;) { if (this->interval.end < end && text[this->interval.end]) { if ('0' <= text[this->interval.end] && text[this->interval.end] <= '9') { - celi_del = celi_del * 10 + text[this->interval.end] - '0'; + celi_del = celi_del * 10 + static_cast(text[this->interval.end] - '0'); this->interval.end++; } else if (text[this->interval.end] == '.') { @@ -6499,7 +6499,7 @@ namespace stdex for (;;) { if (this->interval.end < end && text[this->interval.end]) { if ('0' <= text[this->interval.end] && text[this->interval.end] <= '9') { - decimalni_del = decimalni_del * 10 + text[this->interval.end] - '0'; + decimalni_del = decimalni_del * 10 + static_cast(text[this->interval.end] - '0'); decimalni_del_n *= 10; this->interval.end++; } diff --git a/include/stdex/sgml.hpp b/include/stdex/sgml.hpp index 4012a205c..a6c03a396 100644 --- a/include/stdex/sgml.hpp +++ b/include/stdex/sgml.hpp @@ -1,4 +1,4 @@ -/* +/* SPDX-License-Identifier: MIT Copyright © 2023-2024 Amebis */ @@ -59,7 +59,7 @@ namespace stdex } /// \endcond - constexpr int sgml_full = 0x80000000; + constexpr int sgml_full = 0x40000000; constexpr int sgml_quot = 0x00000001; constexpr int sgml_apos = 0x00000002; constexpr int sgml_quot_apos = sgml_quot | sgml_apos; @@ -105,7 +105,7 @@ namespace stdex wchar_t chr[3]; size_t n = end - src - i - 1; if (n >= 2 && src[i + 1] == '#') { - uint32_t unicode; + utf32_t unicode; if (src[i + 2] == 'x' || src[i + 2] == 'X') unicode = strtou32(src + i + 3, n - 2, nullptr, 16); else @@ -193,13 +193,14 @@ namespace stdex if (end) { const wchar_t* entity_w; wchar_t chr[3]; - size_t n = end - src - i - 1; + _Assume_(src + i + 1 <= end); + size_t n = static_cast(end - src) - i - 1; if (n >= 2 && src[i + 1] == '#') { - uint32_t unicode; + utf32_t unicode; if (src[i + 2] == 'x' || src[i + 2] == 'X') - unicode = strtou32(src + i + 3, n - 2, nullptr, 16); + unicode = static_cast(strtou32(src + i + 3, n - 2, nullptr, 16)); else - unicode = strtou32(src + i + 2, n - 1, nullptr, 10); + unicode = static_cast(strtou32(src + i + 2, n - 1, nullptr, 10)); #ifdef _WIN32 if (unicode < 0x10000) { chr[0] = (wchar_t)unicode; @@ -234,7 +235,8 @@ namespace stdex { if (map) map->push_back(mapping(offset.from + i, offset.to + dst.size())); dst.append(entity_w); - i = end - src + 1; + _Assume_(src <= end); + i = static_cast(end - src) + 1; if (map) map->push_back(mapping(offset.from + i, offset.to + dst.size())); continue; } @@ -313,7 +315,7 @@ namespace stdex wchar_t chr[3]; size_t n = end - src - i - 1; if (n >= 2 && src[i + 1] == '#') { - uint32_t unicode; + utf32_t unicode; if (src[i + 2] == 'x' || src[i + 2] == 'X') unicode = strtou32(src + i + 3, n - 2, nullptr, 16); else @@ -599,7 +601,7 @@ namespace stdex else if (is7bit(src[i])) dst.append(1, static_cast(src[i++])); else { - uint32_t unicode; + utf32_t unicode; #ifdef _WIN32 if (i + 1 < end && is_surrogate_pair(src + i)) { unicode = surrogate_pair_to_ucs4(src + i); @@ -718,7 +720,8 @@ namespace stdex _Assume_(m >= 0); if (static_cast(m) >= count_dst) throw buffer_overrun; - memcpy(dst + j, tmp, m * sizeof(char)); j += m; + memcpy(dst + j, tmp, static_cast(m) * sizeof(char)); + j += static_cast(m); } } else { @@ -740,7 +743,7 @@ namespace stdex dst[j++] = static_cast(src[i++]); } else { - uint32_t unicode; + utf32_t unicode; #ifdef _WIN32 if (i + 1 < end && is_surrogate_pair(src + i)) { unicode = surrogate_pair_to_ucs4(src + i); @@ -756,7 +759,8 @@ namespace stdex _Assume_(m >= 0); if (static_cast(m) >= count_dst) throw buffer_overrun; - memcpy(dst + j, tmp, m * sizeof(char)); j += m; + memcpy(dst + j, tmp, static_cast(m) * sizeof(char)); + j += static_cast(m); } } } diff --git a/include/stdex/stream.hpp b/include/stdex/stream.hpp index fb45ea1d2..23fd2766e 100644 --- a/include/stdex/stream.hpp +++ b/include/stdex/stream.hpp @@ -73,8 +73,8 @@ namespace stdex constexpr size_t iterate_count = 0x10; constexpr size_t default_block_size = 0x10000; ///< Amount of space used by copy or reallocation increments - constexpr char16_t utf16_bom = u'\ufeff'; ///< Byte-order-mark written at each UTF-16 file start - constexpr char32_t utf32_bom = U'\ufeff'; ///< Byte-order-mark written at each UTF-32 file start + constexpr utf16_t utf16_bom = u'\ufeff'; ///< Byte-order-mark written at each UTF-16 file start + constexpr utf32_t utf32_bom = U'\ufeff'; ///< Byte-order-mark written at each UTF-32 file start constexpr const char utf8_bom[3] = { '\xef', '\xbb', '\xbf' }; ///> UTF-8 byte-order-mark /// @@ -841,7 +841,10 @@ namespace stdex /// /// \return Absolute file position after seek /// - fpos_t seekbeg(_In_ fpos_t offset) { return seek(offset, seek_t::beg); } + fpos_t seekbeg(_In_ fpos_t offset) + { + return seek(static_cast(offset), seek_t::beg); + } /// /// Seeks to relative from current file position @@ -859,7 +862,9 @@ namespace stdex virtual void skip(_In_ fsize_t amount) { - seek(amount, seek_t::cur); + if (amount > foff_max) + throw std::invalid_argument("file offset too big"); + seek(static_cast(amount), seek_t::cur); } /// @@ -983,15 +988,15 @@ namespace stdex { if (seek(0) != 0) _Unlikely_ throw std::system_error(sys_error(), std::system_category(), "failed to seek"); - char32_t id_utf32; - read_array(&id_utf32, sizeof(char32_t), 1); + utf32_t id_utf32; + read_array(&id_utf32, sizeof(utf32_t), 1); if (ok() && id_utf32 == utf32_bom) return charset_id::utf32; if (seek(0) != 0) _Unlikely_ throw std::system_error(sys_error(), std::system_category(), "failed to seek"); - char16_t id_utf16; - read_array(&id_utf16, sizeof(char16_t), 1); + utf16_t id_utf16; + read_array(&id_utf16, sizeof(utf16_t), 1); if (ok() && id_utf16 == utf16_bom) return charset_id::utf16; @@ -1827,7 +1832,7 @@ namespace stdex flush_cache(); if (!ok()) _Unlikely_ throw std::system_error(sys_error(), std::system_category(), "failed to flush cache"); // Data loss occured - m_source->seek(m_offset); + m_source->seekbeg(m_offset); #if SET_FILE_OP_TIMES m_source->set_atime(m_atime); m_source->set_mtime(m_mtime); @@ -1855,7 +1860,7 @@ namespace stdex flush_cache(); if (!ok()) _Unlikely_ throw std::system_error(sys_error(), std::system_category(), "failed to flush cache"); // Data loss occured - m_source->seek(m_offset); + m_source->seekbeg(m_offset); #if SET_FILE_OP_TIMES m_source->set_atime(m_atime); m_source->set_mtime(m_mtime); @@ -1896,7 +1901,7 @@ namespace stdex fpos_t end_max = m_offset + to_read; if (m_offset / m_cache.capacity < end_max / m_cache.capacity) { // Read spans multiple cache blocks. Bypass cache to the last block. - m_source->seek(m_offset); + m_source->seekbeg(m_offset); if (!m_source->ok()) _Unlikely_ { m_state = to_read < length ? state_t::ok : state_t::fail; return length - to_read; @@ -1964,7 +1969,7 @@ namespace stdex fpos_t end_max = m_offset + to_write; if (m_offset / m_cache.capacity < end_max / m_cache.capacity) { // Write spans multiple cache blocks. Bypass cache to the last block. - m_source->seek(m_offset); + m_source->seekbeg(m_offset); if (!ok()) _Unlikely_ return length - to_write; size_t num_written = m_source->write(data, to_write - static_cast(end_max % m_cache.capacity)); @@ -2007,20 +2012,25 @@ namespace stdex m_state = state_t::ok; switch (how) { case seek_t::beg: - return m_offset = offset; + break; case seek_t::cur: - return m_offset += offset; + offset = static_cast(m_offset) + offset; + break; case seek_t::end: { auto n = size(); if (n == fsize_max) _Unlikely_{ m_state = state_t::fail; return fpos_max; } - return m_offset = n + offset; + offset = static_cast(n) + offset; + break; } default: throw std::invalid_argument("unknown seek origin"); } + if (offset < 0) _Unlikely_ + throw std::invalid_argument("negative file offset"); + return m_offset = static_cast(offset); } virtual fpos_t tell() const @@ -2052,7 +2062,7 @@ namespace stdex #if SET_FILE_OP_TIMES m_atime = m_mtime = time_point::now(); #endif - m_source->seek(m_offset); + m_source->seekbeg(m_offset); if (m_cache.region.end <= m_offset) { // Truncation does not affect cache. } @@ -2144,7 +2154,7 @@ namespace stdex { _Assume_(m_cache.status != cache_t::cache_t::status_t::dirty); start -= start % m_cache.capacity; // Align to cache block size. - m_source->seek(m_cache.region.start = start); + m_source->seekbeg(m_cache.region.start = start); if (m_source->ok()) { m_cache.region.end = start + m_source->read(m_cache.data, m_cache.capacity); m_cache.status = cache_t::cache_t::status_t::loaded; @@ -2157,7 +2167,7 @@ namespace stdex void write_cache() { _Assume_(m_cache.status == cache_t::cache_t::status_t::dirty); - m_source->seek(m_cache.region.start); + m_source->seekbeg(m_cache.region.start); m_source->write(m_cache.data, static_cast(m_cache.region.size())); m_state = m_source->state(); } @@ -2235,7 +2245,7 @@ namespace stdex } if (!succeeded) _Unlikely_ #else - ssize_t num_read = ::read(m_h, data, static_cast(std::min(to_read, block_size))); + auto num_read = ::read(m_h, data, std::min(to_read, block_size)); if (num_read < 0) _Unlikely_ #endif { @@ -2246,7 +2256,7 @@ namespace stdex m_state = to_read < length || !length ? state_t::ok : state_t::eof; return length - to_read; } - to_read -= num_read; + to_read -= static_cast(num_read); if (!to_read) { m_state = state_t::ok; return length; @@ -2287,12 +2297,12 @@ namespace stdex return length - to_write; } #else - ssize_t num_written = ::write(m_h, data, static_cast(std::min(to_write, block_size))); + auto num_written = ::write(m_h, data, std::min(to_write, block_size)); if (num_written < 0) _Unlikely_ { m_state = state_t::fail; return length - to_write; } - to_write -= num_written; + to_write -= static_cast(num_written); if (!to_write) { m_state = state_t::ok; return length; @@ -2413,8 +2423,14 @@ namespace stdex _Assume_(data || !length); constexpr int block_size = 0x10000000; for (size_t to_read = length;;) { - auto num_read = recv(m_h, reinterpret_cast(data), static_cast(std::min(to_read, block_size)), 0); - if (num_read == -1) _Unlikely_ { + auto num_read = recv(m_h, reinterpret_cast(data), +#ifdef _WIN32 + static_cast(std::min(to_read, block_size)), +#else + std::min(to_read, block_size), +#endif + 0); + if (num_read < 0) _Unlikely_ { m_state = to_read < length ? state_t::ok : state_t::fail; return length - to_read; } @@ -2422,7 +2438,7 @@ namespace stdex m_state = to_read < length || !length ? state_t::ok : state_t::eof; return length - to_read; } - to_read -= num_read; + to_read -= static_cast(num_read); if (!to_read) { m_state = state_t::ok; return length; @@ -2437,12 +2453,18 @@ namespace stdex _Assume_(data || !length); constexpr int block_size = 0x10000000; for (size_t to_write = length;;) { - auto num_written = send(m_h, reinterpret_cast(data), static_cast(std::min(to_write, block_size)), 0); - if (num_written == -1) _Unlikely_ { + auto num_written = send(m_h, reinterpret_cast(data), +#ifdef _WIN32 + static_cast(std::min(to_write, block_size)), +#else + std::min(to_write, block_size), +#endif + 0); + if (num_written < 0) _Unlikely_ { m_state = state_t::fail; return length - to_write; } - to_write -= num_written; + to_write -= static_cast(num_written); if (!to_write) { m_state = state_t::ok; return length; @@ -2816,7 +2838,7 @@ namespace stdex off64_t result = lseek64(m_h, offset, static_cast(how)); if (result >= 0) { m_state = state_t::ok; - return result; + return static_cast(result); } #endif m_state = state_t::fail; @@ -2835,7 +2857,7 @@ namespace stdex #else off64_t result = lseek64(m_h, 0, SEEK_CUR); if (result >= 0) - return result; + return static_cast(result); #endif } return fpos_max; @@ -2855,7 +2877,11 @@ namespace stdex #else off64_t orig = lseek64(m_h, 0, SEEK_CUR); if (orig >= 0) { - m_state = lseek64(m_h, offset, SEEK_SET) >= 0 && lockf64(m_h, F_LOCK, length) >= 0 ? state_t::ok : state_t::fail; + if (offset > std::numeric_limits::max()) + throw std::invalid_argument("file offset too big"); + if (length > std::numeric_limits::max()) + throw std::invalid_argument("file section length too big"); + m_state = lseek64(m_h, static_cast(offset), SEEK_SET) >= 0 && lockf64(m_h, F_LOCK, static_cast(length)) >= 0 ? state_t::ok : state_t::fail; lseek64(m_h, orig, SEEK_SET); m_state = state_t::ok; return; @@ -2878,7 +2904,11 @@ namespace stdex #else off64_t orig = lseek64(m_h, 0, SEEK_CUR); if (orig >= 0) { - if (lseek64(m_h, offset, SEEK_SET) >= 0 && lockf64(m_h, F_ULOCK, length) >= 0) { + if (offset > std::numeric_limits::max()) + throw std::invalid_argument("file offset too big"); + if (length > std::numeric_limits::max()) + throw std::invalid_argument("file section length too big"); + if (lseek64(m_h, static_cast(offset), SEEK_SET) >= 0 && lockf64(m_h, F_ULOCK, static_cast(length)) >= 0) { lseek64(m_h, orig, SEEK_SET); m_state = state_t::ok; return; @@ -2898,12 +2928,14 @@ namespace stdex li.QuadPart = -1; return li.QuadPart; #else - off64_t length = -1, orig = lseek64(m_h, 0, SEEK_CUR); + off64_t orig = lseek64(m_h, 0, SEEK_CUR); if (orig >= 0) { - length = lseek64(m_h, 0, SEEK_END); + off64_t length = lseek64(m_h, 0, SEEK_END); lseek64(m_h, orig, SEEK_SET); + if (length >= 0) + return static_cast(length); } - return length; + return fsize_max; #endif } @@ -3868,19 +3900,18 @@ namespace stdex virtual fpos_t seek(_In_ foff_t offset, _In_ seek_t how = seek_t::beg) { - fpos_t target; switch (how) { - case seek_t::beg: target = offset; break; - case seek_t::cur: target = static_cast(m_offset) + offset; break; - case seek_t::end: target = static_cast(m_size) + offset; break; + case seek_t::beg: break; + case seek_t::cur: offset = static_cast(m_offset) + offset; break; + case seek_t::end: offset = static_cast(m_size) + offset; break; default: throw std::invalid_argument("unknown seek origin"); } - if (target <= SIZE_MAX) { - m_state = state_t::ok; - return m_offset = static_cast(target); - } - m_state = state_t::fail; - return fpos_max; + if (offset < 0) _Unlikely_ + throw std::invalid_argument("negative file offset"); + if (static_cast(offset) > SIZE_MAX) _Unlikely_ + throw std::invalid_argument("file offset too big"); + m_state = state_t::ok; + return m_offset = static_cast(offset); } virtual fpos_t tell() const diff --git a/include/stdex/string.hpp b/include/stdex/string.hpp index 0a6bcc9b7..e37a4308e 100644 --- a/include/stdex/string.hpp +++ b/include/stdex/string.hpp @@ -27,9 +27,11 @@ namespace stdex /// UTF-16 code unit /// #ifdef _WIN32 - typedef wchar_t utf16_t; + using utf16_t = wchar_t; + using utf32_t = char32_t; #else - typedef char16_t utf16_t; + using utf16_t = char16_t; + using utf32_t = wchar_t; #endif /// @@ -67,12 +69,12 @@ namespace stdex /// /// \param[in] str Pointer to first code unit /// - inline char32_t surrogate_pair_to_ucs4(_In_reads_(2) const utf16_t* str) + inline utf32_t surrogate_pair_to_ucs4(_In_reads_(2) const utf16_t* str) { _Assume_(is_surrogate_pair(str)); return - (static_cast(str[0] - 0xd800) << 10) + - static_cast(str[1] - 0xdc00) + + (static_cast(str[0] - 0xd800) << 10) + + static_cast(str[1] - 0xdc00) + 0x10000; } @@ -81,12 +83,12 @@ namespace stdex /// /// \param[in] str Pointer to first code unit /// - inline void ucs4_to_surrogate_pair(_Out_writes_(2) utf16_t* str, _In_ char32_t chr) + inline void ucs4_to_surrogate_pair(_Out_writes_(2) utf16_t* str, _In_ utf32_t chr) { _Assume_(chr >= 0x10000); chr -= 0x10000; - str[0] = 0xd800 + static_cast((chr >> 10) & 0x3ff); - str[1] = 0xdc00 + static_cast(chr & 0x3ff); + str[0] = 0xd800 + static_cast((chr >> 10) & 0x3ff); + str[1] = 0xdc00 + static_cast(chr & 0x3ff); } /// @@ -94,7 +96,7 @@ namespace stdex /// /// \param[in] chr Code point to test /// - inline bool iscombining(_In_ char32_t chr) + inline bool iscombining(_In_ utf32_t chr) { return (0x0300 <= chr && chr < 0x0370) || @@ -2364,10 +2366,10 @@ namespace stdex // Try with stack buffer first. int count = vsnprintf(buf, _countof(buf), format, locale, arg); - if (0 <= count && count <= _countof(buf)) { + if (0 <= count && static_cast(count) <= _countof(buf)) { // Copy from stack. - str.append(buf, count); - return count; + str.append(buf, static_cast(count)); + return static_cast(count); } #ifdef _WIN32 if (count < 0) { @@ -2393,9 +2395,9 @@ namespace stdex // Allocate on heap and retry. str.resize(offset + capacity); count = vsnprintf(&str[offset], capacity, format, locale, arg); - if (0 <= count && count <= capacity) { - str.resize(offset + count); - return count; + if (0 <= count && static_cast(count) <= capacity) { + str.resize(offset + static_cast(count)); + return static_cast(count); } break; case EINVAL: throw std::invalid_argument("invalid vsnprintf arguments"); @@ -2404,7 +2406,7 @@ namespace stdex } } #endif - return count; + return static_cast(count); } /// diff --git a/include/stdex/wav.hpp b/include/stdex/wav.hpp index aad15eb6d..9b3e44184 100644 --- a/include/stdex/wav.hpp +++ b/include/stdex/wav.hpp @@ -481,7 +481,7 @@ namespace stdex // Block was found, but sub-ID is different. end += (align - end) % align; - dat.seek(end); + dat.seekbeg(end); } return false; } @@ -540,7 +540,7 @@ namespace stdex } // Cues are loaded. Add other data. - dat.seek(start); + dat.seekbeg(start); while (dat.tell() < block_end) { stdex::stream::fpos_t found_block_end; if (find_first(dat, *(const id_t*)"adtl", block_end, &found_block_end)) { @@ -589,7 +589,7 @@ namespace stdex } } - dat.seek(start); + dat.seekbeg(start); return true; } @@ -646,7 +646,7 @@ namespace stdex if (end != output.tell()) stdex::idrec::close(output, start); else - output.seek(start); + output.seekbeg(start); } }