@@ -34,6 +34,14 @@ namespace Assert
 | 
			
		||||
			throw std::runtime_error("not equal");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	template <class T, size_t N>
 | 
			
		||||
	inline void AreEqual(const T (&a)[N], const T (&b)[N])
 | 
			
		||||
	{
 | 
			
		||||
		for (size_t i = 0; i < N; ++i)
 | 
			
		||||
			if (!(a[i] == b[i]))
 | 
			
		||||
				throw std::runtime_error("not equal");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	inline void AreEqual(const char* a, const char* b)
 | 
			
		||||
	{
 | 
			
		||||
		if (strcmp(a, b) != 0)
 | 
			
		||||
 
 | 
			
		||||
@@ -187,8 +187,9 @@ namespace UnitTests
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			{
 | 
			
		||||
				wspace_cu space;
 | 
			
		||||
				wiban p(make_shared_no_delete(&space));
 | 
			
		||||
				std::locale locale_slSI("sl_SI");
 | 
			
		||||
				wspace_cu space(false, locale_slSI);
 | 
			
		||||
				wiban p(make_shared_no_delete(&space), locale_slSI);
 | 
			
		||||
				Assert::IsTrue(p.match(L"SI56023120015226972", 0, SIZE_MAX));
 | 
			
		||||
				Assert::IsTrue(p.is_valid);
 | 
			
		||||
				Assert::AreEqual(L"SI", p.country);
 | 
			
		||||
@@ -212,8 +213,9 @@ namespace UnitTests
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			{
 | 
			
		||||
				wspace_cu space;
 | 
			
		||||
				wcreditor_reference p(make_shared_no_delete(&space));
 | 
			
		||||
				std::locale locale_slSI("sl_SI");
 | 
			
		||||
				wspace_cu space(false, locale_slSI);
 | 
			
		||||
				wcreditor_reference p(make_shared_no_delete(&space), locale_slSI);
 | 
			
		||||
				Assert::IsTrue(p.match(L"RF18539007547034", 0, SIZE_MAX));
 | 
			
		||||
				Assert::IsTrue(p.is_valid);
 | 
			
		||||
				Assert::AreEqual(L"18", p.check_digits);
 | 
			
		||||
@@ -235,8 +237,9 @@ namespace UnitTests
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			{
 | 
			
		||||
				wspace_cu space;
 | 
			
		||||
				wsi_reference p(make_shared_no_delete(&space));
 | 
			
		||||
				std::locale locale_slSI("sl_SI");
 | 
			
		||||
				wspace_cu space(false, locale_slSI);
 | 
			
		||||
				wsi_reference p(make_shared_no_delete(&space), locale_slSI);
 | 
			
		||||
				Assert::IsTrue(p.match(L"SI121234567890120", 0, SIZE_MAX));
 | 
			
		||||
				Assert::IsTrue(p.is_valid);
 | 
			
		||||
				Assert::AreEqual(L"12", p.model);
 | 
			
		||||
@@ -301,8 +304,9 @@ namespace UnitTests
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			{
 | 
			
		||||
				sgml_space_cp space;
 | 
			
		||||
				sgml_iban p(make_shared_no_delete(&space));
 | 
			
		||||
				std::locale locale_slSI("sl_SI");
 | 
			
		||||
				sgml_space_cp space(false, locale_slSI);
 | 
			
		||||
				sgml_iban p(make_shared_no_delete(&space), locale_slSI);
 | 
			
		||||
				Assert::IsTrue(p.match("SI56023120015226972", 0, SIZE_MAX));
 | 
			
		||||
				Assert::IsTrue(p.is_valid);
 | 
			
		||||
				Assert::AreEqual("SI", p.country);
 | 
			
		||||
@@ -326,8 +330,9 @@ namespace UnitTests
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			{
 | 
			
		||||
				sgml_space_cp space;
 | 
			
		||||
				sgml_creditor_reference p(make_shared_no_delete(&space));
 | 
			
		||||
				std::locale locale_slSI("sl_SI");
 | 
			
		||||
				sgml_space_cp space(false, locale_slSI);
 | 
			
		||||
				sgml_creditor_reference p(make_shared_no_delete(&space), locale_slSI);
 | 
			
		||||
				Assert::IsTrue(p.match("RF18539007547034", 0, SIZE_MAX));
 | 
			
		||||
				Assert::IsTrue(p.is_valid);
 | 
			
		||||
				Assert::AreEqual("18", p.check_digits);
 | 
			
		||||
@@ -349,8 +354,9 @@ namespace UnitTests
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			{
 | 
			
		||||
				sgml_space_cp space;
 | 
			
		||||
				sgml_si_reference p(make_shared_no_delete(&space));
 | 
			
		||||
				std::locale locale_slSI("sl_SI");
 | 
			
		||||
				sgml_space_cp space(false, locale_slSI);
 | 
			
		||||
				sgml_si_reference p(make_shared_no_delete(&space), locale_slSI);
 | 
			
		||||
				Assert::IsTrue(p.match("SI121234567890120", 0, SIZE_MAX));
 | 
			
		||||
				Assert::IsTrue(p.is_valid);
 | 
			
		||||
				Assert::AreEqual("12", p.model);
 | 
			
		||||
 
 | 
			
		||||
@@ -414,7 +414,7 @@ namespace stdex
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		using space_cu = basic_space_cu<char>;
 | 
			
		||||
		using wspace_cu = basic_space_cu<wchar_t>;
 | 
			
		||||
			using wspace_cu = basic_space_cu<wchar_t>;
 | 
			
		||||
#ifdef _UNICODE
 | 
			
		||||
		using tspace_cu = wspace_cu;
 | 
			
		||||
#else
 | 
			
		||||
@@ -4692,18 +4692,6 @@ namespace stdex
 | 
			
		||||
				assert(text || start >= end);
 | 
			
		||||
				const auto& ctype = std::use_facet<std::ctype<T>>(this->m_locale);
 | 
			
		||||
				const bool case_insensitive = flags & match_case_insensitive ? true : false;
 | 
			
		||||
 | 
			
		||||
				this->interval.end = start;
 | 
			
		||||
				for (size_t i = 0; i < 2; ++i, ++this->interval.end) {
 | 
			
		||||
					if (this->interval.end >= end || !text[this->interval.end])
 | 
			
		||||
						goto error; // incomplete country code
 | 
			
		||||
					T chr = case_insensitive ? ctype.toupper(text[this->interval.end]) : text[this->interval.end];
 | 
			
		||||
					if (chr < 'A' || 'Z' < chr)
 | 
			
		||||
						goto error; // invalid country code
 | 
			
		||||
					this->country[i] = chr;
 | 
			
		||||
				}
 | 
			
		||||
				this->country[2] = 0;
 | 
			
		||||
 | 
			
		||||
				struct country_t {
 | 
			
		||||
					T country[2];
 | 
			
		||||
					T check_digits[2];
 | 
			
		||||
@@ -4818,6 +4806,17 @@ namespace stdex
 | 
			
		||||
					{ { 'X', 'K' }, {}, 20 }, // Kosovo
 | 
			
		||||
				};
 | 
			
		||||
				const country_t* country_desc = nullptr;
 | 
			
		||||
				size_t n;
 | 
			
		||||
 | 
			
		||||
				this->interval.end = start;
 | 
			
		||||
				for (size_t i = 0; i < 2; ++i, ++this->interval.end) {
 | 
			
		||||
					if (this->interval.end >= end || !text[this->interval.end])
 | 
			
		||||
						goto error; // incomplete country code
 | 
			
		||||
					T chr = case_insensitive ? ctype.toupper(text[this->interval.end]) : text[this->interval.end];
 | 
			
		||||
					if (chr < 'A' || 'Z' < chr)
 | 
			
		||||
						goto error; // invalid country code
 | 
			
		||||
					this->country[i] = chr;
 | 
			
		||||
				}
 | 
			
		||||
				for (size_t l = 0, r = _countof(s_countries);;) {
 | 
			
		||||
					if (l >= r)
 | 
			
		||||
						goto error; // unknown country
 | 
			
		||||
@@ -4832,6 +4831,7 @@ namespace stdex
 | 
			
		||||
						break;
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				this->country[2] = 0;
 | 
			
		||||
 | 
			
		||||
				for (size_t i = 0; i < 2; ++i, ++this->interval.end) {
 | 
			
		||||
					if (this->interval.end >= end || text[this->interval.end] < '0' || '9' < text[this->interval.end])
 | 
			
		||||
@@ -4844,8 +4844,7 @@ namespace stdex
 | 
			
		||||
					(country_desc->check_digits[1] && this->check_digits[1] != country_desc->check_digits[1]))
 | 
			
		||||
					goto error; // unexpected check digits
 | 
			
		||||
 | 
			
		||||
				size_t n = 0;
 | 
			
		||||
				for (; ;) {
 | 
			
		||||
				for (n = 0; ;) {
 | 
			
		||||
					if (m_space && m_space->match(text, this->interval.end, end, flags))
 | 
			
		||||
						this->interval.end = m_space->interval.end;
 | 
			
		||||
					for (size_t j = 0; j < 4; ++j) {
 | 
			
		||||
@@ -4994,6 +4993,8 @@ namespace stdex
 | 
			
		||||
				assert(text || start >= end);
 | 
			
		||||
				const auto& ctype = std::use_facet<std::ctype<T>>(this->m_locale);
 | 
			
		||||
				const bool case_insensitive = flags & match_case_insensitive ? true : false;
 | 
			
		||||
				size_t n, available, next;
 | 
			
		||||
				uint32_t nominator;
 | 
			
		||||
 | 
			
		||||
				this->interval.end = start;
 | 
			
		||||
				if (this->interval.end + 1 >= end ||
 | 
			
		||||
@@ -5009,8 +5010,7 @@ namespace stdex
 | 
			
		||||
				}
 | 
			
		||||
				this->check_digits[2] = 0;
 | 
			
		||||
 | 
			
		||||
				size_t n = 0;
 | 
			
		||||
				for (;;) {
 | 
			
		||||
				for (n = 0;;) {
 | 
			
		||||
					if (m_space && m_space->match(text, this->interval.end, end, flags))
 | 
			
		||||
						this->interval.end = m_space->interval.end;
 | 
			
		||||
					for (size_t j = 0; j < 4; ++j) {
 | 
			
		||||
@@ -5038,7 +5038,7 @@ namespace stdex
 | 
			
		||||
 | 
			
		||||
				// Normalize creditor reference.
 | 
			
		||||
				T normalized[47];
 | 
			
		||||
				size_t available = 0;
 | 
			
		||||
				available = 0;
 | 
			
		||||
				for (size_t i = 0; ; ++i) {
 | 
			
		||||
					if (!this->reference[i]) {
 | 
			
		||||
						normalized[available++] = '2'; // R
 | 
			
		||||
@@ -5067,8 +5067,7 @@ namespace stdex
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				// Calculate modulo 97.
 | 
			
		||||
				size_t next;
 | 
			
		||||
				uint32_t nominator = stdex::strtou32(normalized, 9, &next, 10);
 | 
			
		||||
				nominator = stdex::strtou32(normalized, 9, &next, 10);
 | 
			
		||||
				for (;;) {
 | 
			
		||||
					nominator %= 97;
 | 
			
		||||
					if (!normalized[next]) {
 | 
			
		||||
 
 | 
			
		||||
@@ -77,6 +77,8 @@ namespace stdex
 | 
			
		||||
		public:
 | 
			
		||||
			basic(_In_ state_t state = state_t::ok) : m_state(state) {}
 | 
			
		||||
 | 
			
		||||
			virtual ~basic() noexcept(false) {}
 | 
			
		||||
 | 
			
		||||
			///
 | 
			
		||||
			/// Reads block of data from the stream
 | 
			
		||||
			///
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
/*
 | 
			
		||||
/*
 | 
			
		||||
	SPDX-License-Identifier: MIT
 | 
			
		||||
	Copyright © 2016-2023 Amebis
 | 
			
		||||
*/
 | 
			
		||||
@@ -401,6 +401,57 @@ namespace stdex
 | 
			
		||||
		return collate.compare(str1, str1 + count1, str2, str2 + count2);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	///
 | 
			
		||||
	/// Binary compare two strings case-insensitive
 | 
			
		||||
	///
 | 
			
		||||
	/// \param[in] str1    String 1
 | 
			
		||||
	/// \param[in] str2    String 2
 | 
			
		||||
	///
 | 
			
		||||
	/// \return Negative if str1<str2; positive if str1>str2; zero if str1==str2
 | 
			
		||||
	///
 | 
			
		||||
	template <class T1, class T2>
 | 
			
		||||
	inline int stricmp(_In_z_ const T1* str1, _In_z_ const T2* str2, _In_ const std::locale& locale)
 | 
			
		||||
	{
 | 
			
		||||
		assert(str1);
 | 
			
		||||
		assert(str2);
 | 
			
		||||
		size_t i; T1 a; T2 b;
 | 
			
		||||
		const auto& ctype1 = std::use_facet<std::ctype<T1>>(locale);
 | 
			
		||||
		const auto& ctype2 = std::use_facet<std::ctype<T2>>(locale);
 | 
			
		||||
		for (i = 0; (a = ctype1.tolower(str1[i])) | (b = ctype2.tolower(str2[i])); i++) {
 | 
			
		||||
			if (a > b) return +1;
 | 
			
		||||
			if (a < b) return -1;
 | 
			
		||||
		}
 | 
			
		||||
		if (str1[i]) return +1;
 | 
			
		||||
		if (str2[i]) return -1;
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	///
 | 
			
		||||
	/// Binary compare two strings case-insensitive
 | 
			
		||||
	///
 | 
			
		||||
	/// \param[in] str1    String 1
 | 
			
		||||
	/// \param[in] str2    String 2
 | 
			
		||||
	/// \param[in] count   Code unit count limit
 | 
			
		||||
	///
 | 
			
		||||
	/// \return Negative if str1<str2; positive if str1>str2; zero if str1==str2
 | 
			
		||||
	///
 | 
			
		||||
	template <class T1, class T2>
 | 
			
		||||
	inline int strnicmp(_In_reads_or_z_opt_(count) const T1* str1, _In_reads_or_z_opt_(count) const T2* str2, _In_ size_t count, _In_ const std::locale& locale)
 | 
			
		||||
	{
 | 
			
		||||
		assert(str1 || !count);
 | 
			
		||||
		assert(str2 || !count);
 | 
			
		||||
		size_t i; T1 a; T2 b;
 | 
			
		||||
		const auto& ctype1 = std::use_facet<std::ctype<T1>>(locale);
 | 
			
		||||
		const auto& ctype2 = std::use_facet<std::ctype<T2>>(locale);
 | 
			
		||||
		for (i = 0; i < count && ((a = ctype1.tolower(str1[i])) | (b = ctype2.tolower(str2[i]))); i++) {
 | 
			
		||||
			if (a > b) return +1;
 | 
			
		||||
			if (a < b) return -1;
 | 
			
		||||
		}
 | 
			
		||||
		if (i < count && str1[i]) return +1;
 | 
			
		||||
		if (i < count && str2[i]) return -1;
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	///
 | 
			
		||||
	/// Binary compare two strings case-insensitive
 | 
			
		||||
	///
 | 
			
		||||
 
 | 
			
		||||
@@ -117,7 +117,7 @@ namespace stdex
 | 
			
		||||
			return *this;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		virtual ~sys_object()
 | 
			
		||||
		virtual ~sys_object() noexcept(false)
 | 
			
		||||
		{
 | 
			
		||||
			if (m_h != invalid_handle)
 | 
			
		||||
				close(m_h);
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
/*
 | 
			
		||||
/*
 | 
			
		||||
	SPDX-License-Identifier: MIT
 | 
			
		||||
	Copyright © 2023 Amebis
 | 
			
		||||
*/
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user