Xcode: resolve -Wsign-compare

Signed-off-by: Simon Rozman <simon@rozman.si>
This commit is contained in:
Simon Rozman 2024-02-14 10:42:38 +01:00
parent 681a6955d8
commit 8ac0efa85d
9 changed files with 154 additions and 113 deletions

View File

@ -290,6 +290,7 @@
CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_IMPLICIT_SIGN_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
@ -316,6 +317,7 @@
); );
GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_SIGN_COMPARE = YES;
GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNKNOWN_PRAGMAS = YES; GCC_WARN_UNKNOWN_PRAGMAS = YES;
@ -350,6 +352,7 @@
CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_IMPLICIT_SIGN_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
@ -374,6 +377,7 @@
); );
GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_SIGN_COMPARE = YES;
GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNKNOWN_PRAGMAS = YES; GCC_WARN_UNKNOWN_PRAGMAS = YES;

View File

@ -1,4 +1,4 @@
/* /*
SPDX-License-Identifier: MIT SPDX-License-Identifier: MIT
Copyright © 2016-2024 Amebis Copyright © 2016-2024 Amebis
*/ */
@ -317,7 +317,7 @@ namespace stdex
if (i >= size) if (i >= size)
break; break;
int x = data[i]; size_t x = static_cast<size_t>(data[i]);
if ((m_buf[m_num] = x < _countof(base64_dec_lookup) ? base64_dec_lookup[x] : 255) != 255) if ((m_buf[m_num] = x < _countof(base64_dec_lookup) ? base64_dec_lookup[x] : 255) != 255)
m_num++; m_num++;
} }
@ -435,11 +435,11 @@ namespace stdex
{ {
m_num = 0; m_num = 0;
m_temp_off = 0; m_temp_off = 0;
m_temp[0] = ((m_buf[0] << 2) | (m_buf[1] >> 4)) & 0xff; m_temp[0] = static_cast<char>(((m_buf[0] << 2) | (m_buf[1] >> 4)) & 0xff);
if (m_buf[2] < 64) { if (m_buf[2] < 64) {
m_temp[1] = ((m_buf[1] << 4) | (m_buf[2] >> 2)) & 0xff; m_temp[1] = static_cast<char>(((m_buf[1] << 4) | (m_buf[2] >> 2)) & 0xff);
if (m_buf[3] < 64) { if (m_buf[3] < 64) {
m_temp[2] = ((m_buf[2] << 6) | m_buf[3]) & 0xff; m_temp[2] = static_cast<char>(((m_buf[2] << 6) | m_buf[3]) & 0xff);
m_temp_len = 3; m_temp_len = 3;
} else } else
m_temp_len = 2; m_temp_len = 2;

View File

@ -1,4 +1,4 @@
/* /*
SPDX-License-Identifier: MIT SPDX-License-Identifier: MIT
Copyright © 2023-2024 Amebis Copyright © 2023-2024 Amebis
*/ */
@ -95,11 +95,11 @@ namespace stdex
#endif #endif
} }
inline constexpr int8_t byteswap(_In_ const char value) { return byteswap(static_cast<uint8_t>(value)); } inline constexpr int8_t byteswap(_In_ const char value) { return static_cast<int8_t>(byteswap(static_cast<uint8_t>(value))); }
inline constexpr int8_t byteswap(_In_ const int8_t value) { return byteswap(static_cast<uint8_t>(value)); } inline constexpr int8_t byteswap(_In_ const int8_t value) { return static_cast<int8_t>(byteswap(static_cast<uint8_t>(value))); }
inline int16_t byteswap(_In_ const int16_t value) { return byteswap(static_cast<uint16_t>(value)); } inline int16_t byteswap(_In_ const int16_t value) { return static_cast<int16_t>(byteswap(static_cast<uint16_t>(value))); }
inline int32_t byteswap(_In_ const int32_t value) { return byteswap(static_cast<uint32_t>(value)); } inline int32_t byteswap(_In_ const int32_t value) { return static_cast<int32_t>(byteswap(static_cast<uint32_t>(value))); }
inline int64_t byteswap(_In_ const int64_t value) { return byteswap(static_cast<uint64_t>(value)); } inline int64_t byteswap(_In_ const int64_t value) { return static_cast<int64_t>(byteswap(static_cast<uint64_t>(value))); }
inline float byteswap(_In_ const float value) inline float byteswap(_In_ const float value)
{ {

View File

@ -1,4 +1,4 @@
/* /*
SPDX-License-Identifier: MIT SPDX-License-Identifier: MIT
Copyright © 2016-2024 Amebis Copyright © 2016-2024 Amebis
*/ */
@ -276,9 +276,9 @@ namespace stdex {
// Update the data size. // Update the data size.
if (!stream.ok()) _Unlikely_ return stdex::stream::fpos_max; if (!stream.ok()) _Unlikely_ return stdex::stream::fpos_max;
stream.seek(start + sizeof(T_id)); stream.seekbeg(start + sizeof(T_id));
stream << size; stream << size;
stream.seek(end); stream.seekbeg(end);
return 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. /// \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<T_id, T_size>(stream, ID); return stdex::idrec::open<T_id, T_size>(stream, ID);
} }
@ -370,7 +370,7 @@ namespace stdex {
/// ///
/// \returns Position of the record end in \p stream /// \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<T_id, T_size, N_align>(stream, start); return stdex::idrec::close<T_id, T_size, N_align>(stream, start);
} }
@ -394,13 +394,13 @@ namespace stdex {
/// Finds record data /// Finds record data
/// ///
/// \param[in] stream Input stream /// \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 /// \returns
/// - \c true when found /// - \c true when found
/// - \c false otherwise /// - \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<T_id, T_size, N_align>(stream, ID, end); return stdex::idrec::find<T_id, T_size, N_align>(stream, ID, end);
} }
@ -464,7 +464,7 @@ namespace stdex {
if (!temp.ok()) _Unlikely_ return stream; if (!temp.ok()) _Unlikely_ return stream;
temp << r.data; temp << r.data;
r.close(temp, start); r.close(temp, start);
temp.seek(0); temp.seekbeg(0);
stream.write_stream(temp); stream.write_stream(temp);
return stream; return stream;
@ -524,7 +524,7 @@ namespace stdex {
} }
size += padding<T_size, N_align>(size); size += padding<T_size, N_align>(size);
stream.seek(start + size); stream.seekbeg(start + static_cast<stdex::stream::fpos_t>(size));
return stream; return stream;
} }

View File

@ -141,11 +141,11 @@ namespace stdex
size_t n = chr_end - start - 1; size_t n = chr_end - start - 1;
if (n >= 2 && text[start + 1] == '#') { if (n >= 2 && text[start + 1] == '#') {
// Numerical entity // Numerical entity
char32_t unicode; utf32_t unicode;
if (text[start + 2] == 'x' || text[start + 2] == 'X') if (text[start + 2] == 'x' || text[start + 2] == 'X')
unicode = strtou32(text + start + 3, n - 2, nullptr, 16); unicode = static_cast<utf32_t>(strtou32(text + start + 3, n - 2, nullptr, 16));
else else
unicode = strtou32(text + start + 2, n - 1, nullptr, 10); unicode = static_cast<utf32_t>(strtou32(text + start + 2, n - 1, nullptr, 10));
#ifdef _WIN32 #ifdef _WIN32
if (unicode < 0x10000) { if (unicode < 0x10000) {
buf[0] = (wchar_t)unicode; buf[0] = (wchar_t)unicode;
@ -4911,7 +4911,7 @@ namespace stdex
} }
size_t digit_count = nominator == 0 ? 0 : nominator < 10 ? 1 : 2; size_t digit_count = nominator == 0 ? 0 : nominator < 10 ? 1 : 2;
for (; digit_count < 9 && normalized[next]; ++next, ++digit_count) for (; digit_count < 9 && normalized[next]; ++next, ++digit_count)
nominator = nominator * 10 + (normalized[next] - '0'); nominator = nominator * 10 + static_cast<uint32_t>(normalized[next] - '0');
} }
this->interval.start = start; this->interval.start = start;
@ -5059,7 +5059,7 @@ namespace stdex
} }
size_t digit_count = nominator == 0 ? 0 : nominator < 10 ? 1 : 2; size_t digit_count = nominator == 0 ? 0 : nominator < 10 ? 1 : 2;
for (; digit_count < 9 && normalized[next]; ++next, ++digit_count) for (; digit_count < 9 && normalized[next]; ++next, ++digit_count)
nominator = nominator * 10 + (normalized[next] - '0'); nominator = nominator * 10 + static_cast<uint32_t>(normalized[next] - '0');
} }
this->interval.start = start; this->interval.start = start;
@ -5443,7 +5443,7 @@ namespace stdex
_Assume_(part1 && num_part1 >= 1); _Assume_(part1 && num_part1 >= 1);
uint32_t nominator = 0, ponder = 2; uint32_t nominator = 0, ponder = 2;
for (size_t i = num_part1 - 1; i--; ++ponder) for (size_t i = num_part1 - 1; i--; ++ponder)
nominator += (part1[i] - '0') * ponder; nominator += static_cast<uint32_t>(part1[i] - '0') * ponder;
uint8_t control = 11 - static_cast<uint8_t>(nominator % 11); uint8_t control = 11 - static_cast<uint8_t>(nominator % 11);
if (control >= 10) if (control >= 10)
control = 0; control = 0;
@ -5458,9 +5458,9 @@ namespace stdex
_Assume_(part2 && num_part2 >= 1); _Assume_(part2 && num_part2 >= 1);
uint32_t nominator = 0, ponder = 2; uint32_t nominator = 0, ponder = 2;
for (size_t i = num_part2 - 1; i--; ++ponder) for (size_t i = num_part2 - 1; i--; ++ponder)
nominator += (part2[i] - '0') * ponder; nominator += static_cast<uint32_t>(part2[i] - '0') * ponder;
for (size_t i = num_part1; i--; ++ponder) for (size_t i = num_part1; i--; ++ponder)
nominator += (part1[i] - '0') * ponder; nominator += static_cast<uint32_t>(part1[i] - '0') * ponder;
uint8_t control = 11 - static_cast<uint8_t>(nominator % 11); uint8_t control = 11 - static_cast<uint8_t>(nominator % 11);
if (control == 10) if (control == 10)
control = 0; control = 0;
@ -5477,11 +5477,11 @@ namespace stdex
_Assume_(part3 && num_part3 >= 1); _Assume_(part3 && num_part3 >= 1);
uint32_t nominator = 0, ponder = 2; uint32_t nominator = 0, ponder = 2;
for (size_t i = num_part3 - 1; i--; ++ponder) for (size_t i = num_part3 - 1; i--; ++ponder)
nominator += (part3[i] - '0') * ponder; nominator += static_cast<uint32_t>(part3[i] - '0') * ponder;
for (size_t i = num_part2; i--; ++ponder) for (size_t i = num_part2; i--; ++ponder)
nominator += (part2[i] - '0') * ponder; nominator += static_cast<uint32_t>(part2[i] - '0') * ponder;
for (size_t i = num_part1; i--; ++ponder) for (size_t i = num_part1; i--; ++ponder)
nominator += (part1[i] - '0') * ponder; nominator += static_cast<uint32_t>(part1[i] - '0') * ponder;
uint8_t control = 11 - static_cast<uint8_t>(nominator % 11); uint8_t control = 11 - static_cast<uint8_t>(nominator % 11);
if (control == 10) if (control == 10)
control = 0; control = 0;
@ -6109,8 +6109,8 @@ namespace stdex
for (;;) { for (;;) {
if (this->interval.end < end && text[this->interval.end]) { if (this->interval.end < end && text[this->interval.end]) {
if ('0' <= text[this->interval.end] && text[this->interval.end] <= '9') { if ('0' <= text[this->interval.end] && text[this->interval.end] <= '9') {
size_t _value = (size_t)value * 10 + text[this->interval.end] - '0'; size_t _value = static_cast<size_t>(value) * 10 + static_cast<size_t>(text[this->interval.end] - '0');
if (_value > (uint16_t)-1) { if (_value > UINT16_MAX) {
value = 0; value = 0;
this->interval.invalidate(); this->interval.invalidate();
return false; return false;
@ -6491,7 +6491,7 @@ namespace stdex
for (;;) { for (;;) {
if (this->interval.end < end && text[this->interval.end]) { if (this->interval.end < end && text[this->interval.end]) {
if ('0' <= text[this->interval.end] && text[this->interval.end] <= '9') { 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<size_t>(text[this->interval.end] - '0');
this->interval.end++; this->interval.end++;
} }
else if (text[this->interval.end] == '.') { else if (text[this->interval.end] == '.') {
@ -6499,7 +6499,7 @@ namespace stdex
for (;;) { for (;;) {
if (this->interval.end < end && text[this->interval.end]) { if (this->interval.end < end && text[this->interval.end]) {
if ('0' <= text[this->interval.end] && text[this->interval.end] <= '9') { 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<size_t>(text[this->interval.end] - '0');
decimalni_del_n *= 10; decimalni_del_n *= 10;
this->interval.end++; this->interval.end++;
} }

View File

@ -1,4 +1,4 @@
/* /*
SPDX-License-Identifier: MIT SPDX-License-Identifier: MIT
Copyright © 2023-2024 Amebis Copyright © 2023-2024 Amebis
*/ */
@ -59,7 +59,7 @@ namespace stdex
} }
/// \endcond /// \endcond
constexpr int sgml_full = 0x80000000; constexpr int sgml_full = 0x40000000;
constexpr int sgml_quot = 0x00000001; constexpr int sgml_quot = 0x00000001;
constexpr int sgml_apos = 0x00000002; constexpr int sgml_apos = 0x00000002;
constexpr int sgml_quot_apos = sgml_quot | sgml_apos; constexpr int sgml_quot_apos = sgml_quot | sgml_apos;
@ -105,7 +105,7 @@ namespace stdex
wchar_t chr[3]; wchar_t chr[3];
size_t n = end - src - i - 1; size_t n = end - src - i - 1;
if (n >= 2 && src[i + 1] == '#') { if (n >= 2 && src[i + 1] == '#') {
uint32_t unicode; utf32_t unicode;
if (src[i + 2] == 'x' || src[i + 2] == 'X') if (src[i + 2] == 'x' || src[i + 2] == 'X')
unicode = strtou32(src + i + 3, n - 2, nullptr, 16); unicode = strtou32(src + i + 3, n - 2, nullptr, 16);
else else
@ -193,13 +193,14 @@ namespace stdex
if (end) { if (end) {
const wchar_t* entity_w; const wchar_t* entity_w;
wchar_t chr[3]; wchar_t chr[3];
size_t n = end - src - i - 1; _Assume_(src + i + 1 <= end);
size_t n = static_cast<size_t>(end - src) - i - 1;
if (n >= 2 && src[i + 1] == '#') { if (n >= 2 && src[i + 1] == '#') {
uint32_t unicode; utf32_t unicode;
if (src[i + 2] == 'x' || src[i + 2] == 'X') if (src[i + 2] == 'x' || src[i + 2] == 'X')
unicode = strtou32(src + i + 3, n - 2, nullptr, 16); unicode = static_cast<utf32_t>(strtou32(src + i + 3, n - 2, nullptr, 16));
else else
unicode = strtou32(src + i + 2, n - 1, nullptr, 10); unicode = static_cast<utf32_t>(strtou32(src + i + 2, n - 1, nullptr, 10));
#ifdef _WIN32 #ifdef _WIN32
if (unicode < 0x10000) { if (unicode < 0x10000) {
chr[0] = (wchar_t)unicode; chr[0] = (wchar_t)unicode;
@ -234,7 +235,8 @@ namespace stdex
{ {
if (map) map->push_back(mapping<size_t>(offset.from + i, offset.to + dst.size())); if (map) map->push_back(mapping<size_t>(offset.from + i, offset.to + dst.size()));
dst.append(entity_w); dst.append(entity_w);
i = end - src + 1; _Assume_(src <= end);
i = static_cast<size_t>(end - src) + 1;
if (map) map->push_back(mapping<size_t>(offset.from + i, offset.to + dst.size())); if (map) map->push_back(mapping<size_t>(offset.from + i, offset.to + dst.size()));
continue; continue;
} }
@ -313,7 +315,7 @@ namespace stdex
wchar_t chr[3]; wchar_t chr[3];
size_t n = end - src - i - 1; size_t n = end - src - i - 1;
if (n >= 2 && src[i + 1] == '#') { if (n >= 2 && src[i + 1] == '#') {
uint32_t unicode; utf32_t unicode;
if (src[i + 2] == 'x' || src[i + 2] == 'X') if (src[i + 2] == 'x' || src[i + 2] == 'X')
unicode = strtou32(src + i + 3, n - 2, nullptr, 16); unicode = strtou32(src + i + 3, n - 2, nullptr, 16);
else else
@ -599,7 +601,7 @@ namespace stdex
else if (is7bit(src[i])) else if (is7bit(src[i]))
dst.append(1, static_cast<char>(src[i++])); dst.append(1, static_cast<char>(src[i++]));
else { else {
uint32_t unicode; utf32_t unicode;
#ifdef _WIN32 #ifdef _WIN32
if (i + 1 < end && is_surrogate_pair(src + i)) { if (i + 1 < end && is_surrogate_pair(src + i)) {
unicode = surrogate_pair_to_ucs4(src + i); unicode = surrogate_pair_to_ucs4(src + i);
@ -718,7 +720,8 @@ namespace stdex
_Assume_(m >= 0); _Assume_(m >= 0);
if (static_cast<size_t>(m) >= count_dst) if (static_cast<size_t>(m) >= count_dst)
throw buffer_overrun; throw buffer_overrun;
memcpy(dst + j, tmp, m * sizeof(char)); j += m; memcpy(dst + j, tmp, static_cast<size_t>(m) * sizeof(char));
j += static_cast<size_t>(m);
} }
} }
else { else {
@ -740,7 +743,7 @@ namespace stdex
dst[j++] = static_cast<char>(src[i++]); dst[j++] = static_cast<char>(src[i++]);
} }
else { else {
uint32_t unicode; utf32_t unicode;
#ifdef _WIN32 #ifdef _WIN32
if (i + 1 < end && is_surrogate_pair(src + i)) { if (i + 1 < end && is_surrogate_pair(src + i)) {
unicode = surrogate_pair_to_ucs4(src + i); unicode = surrogate_pair_to_ucs4(src + i);
@ -756,7 +759,8 @@ namespace stdex
_Assume_(m >= 0); _Assume_(m >= 0);
if (static_cast<size_t>(m) >= count_dst) if (static_cast<size_t>(m) >= count_dst)
throw buffer_overrun; throw buffer_overrun;
memcpy(dst + j, tmp, m * sizeof(char)); j += m; memcpy(dst + j, tmp, static_cast<size_t>(m) * sizeof(char));
j += static_cast<size_t>(m);
} }
} }
} }

View File

@ -73,8 +73,8 @@ namespace stdex
constexpr size_t iterate_count = 0x10; constexpr size_t iterate_count = 0x10;
constexpr size_t default_block_size = 0x10000; ///< Amount of space used by copy or reallocation increments 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 utf16_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 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 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 /// \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<foff_t>(offset), seek_t::beg);
}
/// ///
/// Seeks to relative from current file position /// Seeks to relative from current file position
@ -859,7 +862,9 @@ namespace stdex
virtual void skip(_In_ fsize_t amount) 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<foff_t>(amount), seek_t::cur);
} }
/// ///
@ -983,15 +988,15 @@ namespace stdex
{ {
if (seek(0) != 0) _Unlikely_ if (seek(0) != 0) _Unlikely_
throw std::system_error(sys_error(), std::system_category(), "failed to seek"); throw std::system_error(sys_error(), std::system_category(), "failed to seek");
char32_t id_utf32; utf32_t id_utf32;
read_array(&id_utf32, sizeof(char32_t), 1); read_array(&id_utf32, sizeof(utf32_t), 1);
if (ok() && id_utf32 == utf32_bom) if (ok() && id_utf32 == utf32_bom)
return charset_id::utf32; return charset_id::utf32;
if (seek(0) != 0) _Unlikely_ if (seek(0) != 0) _Unlikely_
throw std::system_error(sys_error(), std::system_category(), "failed to seek"); throw std::system_error(sys_error(), std::system_category(), "failed to seek");
char16_t id_utf16; utf16_t id_utf16;
read_array(&id_utf16, sizeof(char16_t), 1); read_array(&id_utf16, sizeof(utf16_t), 1);
if (ok() && id_utf16 == utf16_bom) if (ok() && id_utf16 == utf16_bom)
return charset_id::utf16; return charset_id::utf16;
@ -1827,7 +1832,7 @@ namespace stdex
flush_cache(); flush_cache();
if (!ok()) _Unlikely_ if (!ok()) _Unlikely_
throw std::system_error(sys_error(), std::system_category(), "failed to flush cache"); // Data loss occured 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 #if SET_FILE_OP_TIMES
m_source->set_atime(m_atime); m_source->set_atime(m_atime);
m_source->set_mtime(m_mtime); m_source->set_mtime(m_mtime);
@ -1855,7 +1860,7 @@ namespace stdex
flush_cache(); flush_cache();
if (!ok()) _Unlikely_ if (!ok()) _Unlikely_
throw std::system_error(sys_error(), std::system_category(), "failed to flush cache"); // Data loss occured 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 #if SET_FILE_OP_TIMES
m_source->set_atime(m_atime); m_source->set_atime(m_atime);
m_source->set_mtime(m_mtime); m_source->set_mtime(m_mtime);
@ -1896,7 +1901,7 @@ namespace stdex
fpos_t end_max = m_offset + to_read; fpos_t end_max = m_offset + to_read;
if (m_offset / m_cache.capacity < end_max / m_cache.capacity) { if (m_offset / m_cache.capacity < end_max / m_cache.capacity) {
// Read spans multiple cache blocks. Bypass cache to the last block. // 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_ { if (!m_source->ok()) _Unlikely_ {
m_state = to_read < length ? state_t::ok : state_t::fail; m_state = to_read < length ? state_t::ok : state_t::fail;
return length - to_read; return length - to_read;
@ -1964,7 +1969,7 @@ namespace stdex
fpos_t end_max = m_offset + to_write; fpos_t end_max = m_offset + to_write;
if (m_offset / m_cache.capacity < end_max / m_cache.capacity) { if (m_offset / m_cache.capacity < end_max / m_cache.capacity) {
// Write spans multiple cache blocks. Bypass cache to the last block. // Write spans multiple cache blocks. Bypass cache to the last block.
m_source->seek(m_offset); m_source->seekbeg(m_offset);
if (!ok()) _Unlikely_ if (!ok()) _Unlikely_
return length - to_write; return length - to_write;
size_t num_written = m_source->write(data, to_write - static_cast<size_t>(end_max % m_cache.capacity)); size_t num_written = m_source->write(data, to_write - static_cast<size_t>(end_max % m_cache.capacity));
@ -2007,20 +2012,25 @@ namespace stdex
m_state = state_t::ok; m_state = state_t::ok;
switch (how) { switch (how) {
case seek_t::beg: case seek_t::beg:
return m_offset = offset; break;
case seek_t::cur: case seek_t::cur:
return m_offset += offset; offset = static_cast<foff_t>(m_offset) + offset;
break;
case seek_t::end: { case seek_t::end: {
auto n = size(); auto n = size();
if (n == fsize_max) _Unlikely_{ if (n == fsize_max) _Unlikely_{
m_state = state_t::fail; m_state = state_t::fail;
return fpos_max; return fpos_max;
} }
return m_offset = n + offset; offset = static_cast<foff_t>(n) + offset;
break;
} }
default: default:
throw std::invalid_argument("unknown seek origin"); throw std::invalid_argument("unknown seek origin");
} }
if (offset < 0) _Unlikely_
throw std::invalid_argument("negative file offset");
return m_offset = static_cast<fpos_t>(offset);
} }
virtual fpos_t tell() const virtual fpos_t tell() const
@ -2052,7 +2062,7 @@ namespace stdex
#if SET_FILE_OP_TIMES #if SET_FILE_OP_TIMES
m_atime = m_mtime = time_point::now(); m_atime = m_mtime = time_point::now();
#endif #endif
m_source->seek(m_offset); m_source->seekbeg(m_offset);
if (m_cache.region.end <= m_offset) { if (m_cache.region.end <= m_offset) {
// Truncation does not affect cache. // Truncation does not affect cache.
} }
@ -2144,7 +2154,7 @@ namespace stdex
{ {
_Assume_(m_cache.status != cache_t::cache_t::status_t::dirty); _Assume_(m_cache.status != cache_t::cache_t::status_t::dirty);
start -= start % m_cache.capacity; // Align to cache block size. 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()) { if (m_source->ok()) {
m_cache.region.end = start + m_source->read(m_cache.data, m_cache.capacity); m_cache.region.end = start + m_source->read(m_cache.data, m_cache.capacity);
m_cache.status = cache_t::cache_t::status_t::loaded; m_cache.status = cache_t::cache_t::status_t::loaded;
@ -2157,7 +2167,7 @@ namespace stdex
void write_cache() void write_cache()
{ {
_Assume_(m_cache.status == cache_t::cache_t::status_t::dirty); _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<size_t>(m_cache.region.size())); m_source->write(m_cache.data, static_cast<size_t>(m_cache.region.size()));
m_state = m_source->state(); m_state = m_source->state();
} }
@ -2235,7 +2245,7 @@ namespace stdex
} }
if (!succeeded) _Unlikely_ if (!succeeded) _Unlikely_
#else #else
ssize_t num_read = ::read(m_h, data, static_cast<ssize_t>(std::min<size_t>(to_read, block_size))); auto num_read = ::read(m_h, data, std::min<size_t>(to_read, block_size));
if (num_read < 0) _Unlikely_ if (num_read < 0) _Unlikely_
#endif #endif
{ {
@ -2246,7 +2256,7 @@ namespace stdex
m_state = to_read < length || !length ? state_t::ok : state_t::eof; m_state = to_read < length || !length ? state_t::ok : state_t::eof;
return length - to_read; return length - to_read;
} }
to_read -= num_read; to_read -= static_cast<size_t>(num_read);
if (!to_read) { if (!to_read) {
m_state = state_t::ok; m_state = state_t::ok;
return length; return length;
@ -2287,12 +2297,12 @@ namespace stdex
return length - to_write; return length - to_write;
} }
#else #else
ssize_t num_written = ::write(m_h, data, static_cast<ssize_t>(std::min<size_t>(to_write, block_size))); auto num_written = ::write(m_h, data, std::min<size_t>(to_write, block_size));
if (num_written < 0) _Unlikely_ { if (num_written < 0) _Unlikely_ {
m_state = state_t::fail; m_state = state_t::fail;
return length - to_write; return length - to_write;
} }
to_write -= num_written; to_write -= static_cast<size_t>(num_written);
if (!to_write) { if (!to_write) {
m_state = state_t::ok; m_state = state_t::ok;
return length; return length;
@ -2413,8 +2423,14 @@ namespace stdex
_Assume_(data || !length); _Assume_(data || !length);
constexpr int block_size = 0x10000000; constexpr int block_size = 0x10000000;
for (size_t to_read = length;;) { for (size_t to_read = length;;) {
auto num_read = recv(m_h, reinterpret_cast<char*>(data), static_cast<int>(std::min<size_t>(to_read, block_size)), 0); auto num_read = recv(m_h, reinterpret_cast<char*>(data),
if (num_read == -1) _Unlikely_ { #ifdef _WIN32
static_cast<int>(std::min<size_t>(to_read, block_size)),
#else
std::min<size_t>(to_read, block_size),
#endif
0);
if (num_read < 0) _Unlikely_ {
m_state = to_read < length ? state_t::ok : state_t::fail; m_state = to_read < length ? state_t::ok : state_t::fail;
return length - to_read; return length - to_read;
} }
@ -2422,7 +2438,7 @@ namespace stdex
m_state = to_read < length || !length ? state_t::ok : state_t::eof; m_state = to_read < length || !length ? state_t::ok : state_t::eof;
return length - to_read; return length - to_read;
} }
to_read -= num_read; to_read -= static_cast<size_t>(num_read);
if (!to_read) { if (!to_read) {
m_state = state_t::ok; m_state = state_t::ok;
return length; return length;
@ -2437,12 +2453,18 @@ namespace stdex
_Assume_(data || !length); _Assume_(data || !length);
constexpr int block_size = 0x10000000; constexpr int block_size = 0x10000000;
for (size_t to_write = length;;) { for (size_t to_write = length;;) {
auto num_written = send(m_h, reinterpret_cast<const char*>(data), static_cast<int>(std::min<size_t>(to_write, block_size)), 0); auto num_written = send(m_h, reinterpret_cast<const char*>(data),
if (num_written == -1) _Unlikely_ { #ifdef _WIN32
static_cast<int>(std::min<size_t>(to_write, block_size)),
#else
std::min<size_t>(to_write, block_size),
#endif
0);
if (num_written < 0) _Unlikely_ {
m_state = state_t::fail; m_state = state_t::fail;
return length - to_write; return length - to_write;
} }
to_write -= num_written; to_write -= static_cast<size_t>(num_written);
if (!to_write) { if (!to_write) {
m_state = state_t::ok; m_state = state_t::ok;
return length; return length;
@ -2816,7 +2838,7 @@ namespace stdex
off64_t result = lseek64(m_h, offset, static_cast<int>(how)); off64_t result = lseek64(m_h, offset, static_cast<int>(how));
if (result >= 0) { if (result >= 0) {
m_state = state_t::ok; m_state = state_t::ok;
return result; return static_cast<fpos_t>(result);
} }
#endif #endif
m_state = state_t::fail; m_state = state_t::fail;
@ -2835,7 +2857,7 @@ namespace stdex
#else #else
off64_t result = lseek64(m_h, 0, SEEK_CUR); off64_t result = lseek64(m_h, 0, SEEK_CUR);
if (result >= 0) if (result >= 0)
return result; return static_cast<fpos_t>(result);
#endif #endif
} }
return fpos_max; return fpos_max;
@ -2855,7 +2877,11 @@ namespace stdex
#else #else
off64_t orig = lseek64(m_h, 0, SEEK_CUR); off64_t orig = lseek64(m_h, 0, SEEK_CUR);
if (orig >= 0) { 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<off64_t>::max())
throw std::invalid_argument("file offset too big");
if (length > std::numeric_limits<off64_t>::max())
throw std::invalid_argument("file section length too big");
m_state = lseek64(m_h, static_cast<off64_t>(offset), SEEK_SET) >= 0 && lockf64(m_h, F_LOCK, static_cast<off64_t>(length)) >= 0 ? state_t::ok : state_t::fail;
lseek64(m_h, orig, SEEK_SET); lseek64(m_h, orig, SEEK_SET);
m_state = state_t::ok; m_state = state_t::ok;
return; return;
@ -2878,7 +2904,11 @@ namespace stdex
#else #else
off64_t orig = lseek64(m_h, 0, SEEK_CUR); off64_t orig = lseek64(m_h, 0, SEEK_CUR);
if (orig >= 0) { if (orig >= 0) {
if (lseek64(m_h, offset, SEEK_SET) >= 0 && lockf64(m_h, F_ULOCK, length) >= 0) { if (offset > std::numeric_limits<off64_t>::max())
throw std::invalid_argument("file offset too big");
if (length > std::numeric_limits<off64_t>::max())
throw std::invalid_argument("file section length too big");
if (lseek64(m_h, static_cast<off64_t>(offset), SEEK_SET) >= 0 && lockf64(m_h, F_ULOCK, static_cast<off64_t>(length)) >= 0) {
lseek64(m_h, orig, SEEK_SET); lseek64(m_h, orig, SEEK_SET);
m_state = state_t::ok; m_state = state_t::ok;
return; return;
@ -2898,12 +2928,14 @@ namespace stdex
li.QuadPart = -1; li.QuadPart = -1;
return li.QuadPart; return li.QuadPart;
#else #else
off64_t length = -1, orig = lseek64(m_h, 0, SEEK_CUR); off64_t orig = lseek64(m_h, 0, SEEK_CUR);
if (orig >= 0) { 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); lseek64(m_h, orig, SEEK_SET);
if (length >= 0)
return static_cast<fsize_t>(length);
} }
return length; return fsize_max;
#endif #endif
} }
@ -3868,19 +3900,18 @@ namespace stdex
virtual fpos_t seek(_In_ foff_t offset, _In_ seek_t how = seek_t::beg) virtual fpos_t seek(_In_ foff_t offset, _In_ seek_t how = seek_t::beg)
{ {
fpos_t target;
switch (how) { switch (how) {
case seek_t::beg: target = offset; break; case seek_t::beg: break;
case seek_t::cur: target = static_cast<fpos_t>(m_offset) + offset; break; case seek_t::cur: offset = static_cast<foff_t>(m_offset) + offset; break;
case seek_t::end: target = static_cast<fpos_t>(m_size) + offset; break; case seek_t::end: offset = static_cast<foff_t>(m_size) + offset; break;
default: throw std::invalid_argument("unknown seek origin"); default: throw std::invalid_argument("unknown seek origin");
} }
if (target <= SIZE_MAX) { if (offset < 0) _Unlikely_
m_state = state_t::ok; throw std::invalid_argument("negative file offset");
return m_offset = static_cast<size_t>(target); if (static_cast<fpos_t>(offset) > SIZE_MAX) _Unlikely_
} throw std::invalid_argument("file offset too big");
m_state = state_t::fail; m_state = state_t::ok;
return fpos_max; return m_offset = static_cast<size_t>(offset);
} }
virtual fpos_t tell() const virtual fpos_t tell() const

View File

@ -27,9 +27,11 @@ namespace stdex
/// UTF-16 code unit /// UTF-16 code unit
/// ///
#ifdef _WIN32 #ifdef _WIN32
typedef wchar_t utf16_t; using utf16_t = wchar_t;
using utf32_t = char32_t;
#else #else
typedef char16_t utf16_t; using utf16_t = char16_t;
using utf32_t = wchar_t;
#endif #endif
/// ///
@ -67,12 +69,12 @@ namespace stdex
/// ///
/// \param[in] str Pointer to first code unit /// \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)); _Assume_(is_surrogate_pair(str));
return return
(static_cast<char32_t>(str[0] - 0xd800) << 10) + (static_cast<utf32_t>(str[0] - 0xd800) << 10) +
static_cast<char32_t>(str[1] - 0xdc00) + static_cast<utf32_t>(str[1] - 0xdc00) +
0x10000; 0x10000;
} }
@ -81,12 +83,12 @@ namespace stdex
/// ///
/// \param[in] str Pointer to first code unit /// \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); _Assume_(chr >= 0x10000);
chr -= 0x10000; chr -= 0x10000;
str[0] = 0xd800 + static_cast<char32_t>((chr >> 10) & 0x3ff); str[0] = 0xd800 + static_cast<utf32_t>((chr >> 10) & 0x3ff);
str[1] = 0xdc00 + static_cast<char32_t>(chr & 0x3ff); str[1] = 0xdc00 + static_cast<utf32_t>(chr & 0x3ff);
} }
/// ///
@ -94,7 +96,7 @@ namespace stdex
/// ///
/// \param[in] chr Code point to test /// \param[in] chr Code point to test
/// ///
inline bool iscombining(_In_ char32_t chr) inline bool iscombining(_In_ utf32_t chr)
{ {
return return
(0x0300 <= chr && chr < 0x0370) || (0x0300 <= chr && chr < 0x0370) ||
@ -2364,10 +2366,10 @@ namespace stdex
// Try with stack buffer first. // Try with stack buffer first.
int count = vsnprintf(buf, _countof(buf), format, locale, arg); int count = vsnprintf(buf, _countof(buf), format, locale, arg);
if (0 <= count && count <= _countof(buf)) { if (0 <= count && static_cast<size_t>(count) <= _countof(buf)) {
// Copy from stack. // Copy from stack.
str.append(buf, count); str.append(buf, static_cast<size_t>(count));
return count; return static_cast<size_t>(count);
} }
#ifdef _WIN32 #ifdef _WIN32
if (count < 0) { if (count < 0) {
@ -2393,9 +2395,9 @@ namespace stdex
// Allocate on heap and retry. // Allocate on heap and retry.
str.resize(offset + capacity); str.resize(offset + capacity);
count = vsnprintf(&str[offset], capacity, format, locale, arg); count = vsnprintf(&str[offset], capacity, format, locale, arg);
if (0 <= count && count <= capacity) { if (0 <= count && static_cast<size_t>(count) <= capacity) {
str.resize(offset + count); str.resize(offset + static_cast<size_t>(count));
return count; return static_cast<size_t>(count);
} }
break; break;
case EINVAL: throw std::invalid_argument("invalid vsnprintf arguments"); case EINVAL: throw std::invalid_argument("invalid vsnprintf arguments");
@ -2404,7 +2406,7 @@ namespace stdex
} }
} }
#endif #endif
return count; return static_cast<size_t>(count);
} }
/// ///

View File

@ -481,7 +481,7 @@ namespace stdex
// Block was found, but sub-ID is different. // Block was found, but sub-ID is different.
end += (align - end) % align; end += (align - end) % align;
dat.seek(end); dat.seekbeg(end);
} }
return false; return false;
} }
@ -540,7 +540,7 @@ namespace stdex
} }
// Cues are loaded. Add other data. // Cues are loaded. Add other data.
dat.seek(start); dat.seekbeg(start);
while (dat.tell() < block_end) { while (dat.tell() < block_end) {
stdex::stream::fpos_t found_block_end; stdex::stream::fpos_t found_block_end;
if (find_first<list>(dat, *(const id_t*)"adtl", block_end, &found_block_end)) { if (find_first<list>(dat, *(const id_t*)"adtl", block_end, &found_block_end)) {
@ -589,7 +589,7 @@ namespace stdex
} }
} }
dat.seek(start); dat.seekbeg(start);
return true; return true;
} }
@ -646,7 +646,7 @@ namespace stdex
if (end != output.tell()) if (end != output.tell())
stdex::idrec::close<id_t, length_t, align>(output, start); stdex::idrec::close<id_t, length_t, align>(output, start);
else else
output.seek(start); output.seekbeg(start);
} }
} }