From 7abe4b340a1fb943d0a7936dd8b921965e760cff Mon Sep 17 00:00:00 2001 From: Tomasz Sowa Date: Mon, 10 May 2021 20:04:12 +0200 Subject: [PATCH] changes in convert/text functions - changed function names: PascalCase to snake_case - templates functions moved to a seperate file (text_private.h) - as a public api only available functions with char/wchar_t/std::string/std::wstring - ToLower(...) changed to to_lower_emplace(...), similar ToUpper(...) to to_upper_emplace(...) - added functions: std::string to_lower(const std::string & str); std::string to_upper(const std::string & str); and with std::wstring too - functions with postfix 'NoCase' changed to 'nc' --- src/convert/strtoint.h | 14 +- src/convert/text.cpp | 312 ++++++++++++++++++++++++++++++++++--- src/convert/text.h | 284 ++++++++------------------------- src/convert/text_private.h | 225 +++++++++++++++++++++++++- src/space/space.cpp | 4 +- 5 files changed, 585 insertions(+), 254 deletions(-) diff --git a/src/convert/strtoint.h b/src/convert/strtoint.h index 3aae7dc..3324d3a 100644 --- a/src/convert/strtoint.h +++ b/src/convert/strtoint.h @@ -5,7 +5,7 @@ */ /* - * Copyright (c) 2017, Tomasz Sowa + * Copyright (c) 2017-2021, Tomasz Sowa * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -59,9 +59,9 @@ unsigned long long Toull(const CharType * str, int base = 10, const CharType ** SetOverflow(was_overflow, false); if( allow_skip_whitechars ) - str = SkipWhite(str); + str = skip_white(str); - while( !carry && IsDigit(*str, base, &digit) ) + while( !carry && is_digit(*str, base, &digit) ) { #ifdef __GNUC__ carry = __builtin_mul_overflow(res, static_cast(base), &res); @@ -82,7 +82,7 @@ unsigned long long Toull(const CharType * str, int base = 10, const CharType ** { if( after_str ) { - while( IsDigit(*str, base, &digit) ) + while( is_digit(*str, base, &digit) ) { str += 1; } @@ -108,7 +108,7 @@ long long Toll(const CharType * str, int base = 10, const CharType ** after_str SetOverflow(was_overflow, false); if( allow_skip_whitechars ) - str = SkipWhite(str); + str = skip_white(str); if( *str == '-' ) { @@ -230,7 +230,7 @@ template unsigned long long Toull_b(const CharType * str, const CharType ** after_str = 0, bool * was_overflow = 0, bool allow_skip_whitechars = true) { if( allow_skip_whitechars ) - str = SkipWhite(str); + str = skip_white(str); int base = 10; @@ -266,7 +266,7 @@ long long Toll_b(const CharType * str, const CharType ** after_str = 0, bool * w SetOverflow(was_overflow, false); if( allow_skip_whitechars ) - str = SkipWhite(str); + str = skip_white(str); if( *str == '-' ) { diff --git a/src/convert/text.cpp b/src/convert/text.cpp index ebaa175..c8d8fa0 100644 --- a/src/convert/text.cpp +++ b/src/convert/text.cpp @@ -37,6 +37,7 @@ #include #include "text.h" +#include "text_private.h" namespace PT @@ -78,7 +79,7 @@ static const wchar_t white_chars_table[] = { /* if check_additional_chars is false then we are testing only a space (32), tab (9) and a new line (10) (if treat_new_line_as_white is true) */ -bool IsWhite(wchar_t c, bool check_additional_chars, bool treat_new_line_as_white) +bool is_white(wchar_t c, bool check_additional_chars, bool treat_new_line_as_white) { // space (32) and tab (9) are the most common white chars // so we check them at the beginning (optimisation) @@ -119,7 +120,7 @@ return false; -bool IsDigit(wchar_t c, int base, int * digit) +bool is_digit(wchar_t c, int base, int * digit) { int d = 0; @@ -152,54 +153,317 @@ bool IsDigit(wchar_t c, int base, int * digit) } - -char ToLower(char c) +const char * skip_white(const char * str, bool check_additional_chars, bool treat_new_line_as_white) { - return pt_private::ToLowerGeneric(c); + return pt_private::skip_white_generic(str, check_additional_chars, treat_new_line_as_white); } -wchar_t ToLower(wchar_t c) +const wchar_t * skip_white(const wchar_t * str, bool check_additional_chars, bool treat_new_line_as_white) { - return pt_private::ToLowerGeneric(c); + return pt_private::skip_white_generic(str, check_additional_chars, treat_new_line_as_white); } - -char ToUpper(char c) +const char * skip_white_from_back(const char * str_begin, const char * str_end, bool check_additional_chars, bool treat_new_line_as_white) { - return pt_private::ToUpperGeneric(c); + return pt_private::skip_white_from_back_generic(str_begin, str_end, check_additional_chars, treat_new_line_as_white); } -wchar_t ToUpper(wchar_t c) +const wchar_t * skip_white_from_back(const wchar_t * str_begin, const wchar_t * str_end, bool check_additional_chars, bool treat_new_line_as_white) { - return pt_private::ToUpperGeneric(c); - + return pt_private::skip_white_from_back_generic(str_begin, str_end, check_additional_chars, treat_new_line_as_white); } - - - -void ToLower(std::string & str) +const char * skip_white_from_back(const char * str, bool check_additional_chars, bool treat_new_line_as_white) { - pt_private::ToLowerStrGeneric(str); + return pt_private::skip_white_from_back_generic(str, check_additional_chars, treat_new_line_as_white); } -void ToLower(std::wstring & str) +const wchar_t * skip_white_from_back(const wchar_t * str, bool check_additional_chars, bool treat_new_line_as_white) { - pt_private::ToLowerStrGeneric(str); + return pt_private::skip_white_from_back_generic(str, check_additional_chars, treat_new_line_as_white); } -void ToUpper(std::string & str) + + +char to_lower(char c) { - pt_private::ToLowerStrGeneric(str); + return pt_private::to_lower_generic(c); } -void ToUpper(std::wstring & str) +wchar_t to_lower(wchar_t c) { - pt_private::ToLowerStrGeneric(str); + return pt_private::to_lower_generic(c); } +char to_upper(char c) +{ + return pt_private::to_upper_generic(c); +} + +wchar_t to_upper(wchar_t c) +{ + return pt_private::to_upper_generic(c); + +} + + + + +void to_lower_emplace(std::string & str) +{ + pt_private::to_lower_str_generic(str); +} + + +void to_lower_emplace(std::wstring & str) +{ + pt_private::to_lower_str_generic(str); +} + + +void to_upper_emplace(std::string & str) +{ + pt_private::to_upper_str_generic(str); +} + + +void to_upper_emplace(std::wstring & str) +{ + pt_private::to_upper_str_generic(str); +} + + + + + +std::string to_lower(const std::string & str) +{ + std::string res(str); + to_lower_emplace(res); + + return res; +} + + +std::wstring to_lower(const std::wstring & str) +{ + std::wstring res(str); + to_lower_emplace(res); + + return res; +} + + +std::string to_upper(const std::string & str) +{ + std::string res(str); + to_upper_emplace(res); + + return res; +} + + +std::wstring to_upper(const std::wstring & str) +{ + std::wstring res(str); + to_upper_emplace(res); + + return res; +} + + + +int compare(const char * str1, const char * str2) +{ + return pt_private::compare_generic(str1, str2); +} + +int compare(const wchar_t * str1, const wchar_t * str2) +{ + return pt_private::compare_generic(str1, str2); +} + +int compare(const std::string & str1, const std::string & str2) +{ + return pt_private::compare_str_generic(str1, str2); +} + +int compare(const std::wstring & str1, const std::wstring & str2) +{ + return pt_private::compare_str_generic(str1, str2); +} + +int compare(const char * str1_begin, const char * str1_end, const char * str2) +{ + return pt_private::compare_generic(str1_begin, str1_end, str2); +} + +int compare(const wchar_t * str1_begin, const wchar_t * str1_end, const wchar_t * str2) +{ + return pt_private::compare_generic(str1_begin, str1_end, str2); +} + + + + + + + +int compare_nc(const char * str1, const char * str2) +{ + return pt_private::compare_nc_generic(str1, str2); +} + +int compare_nc(const wchar_t * str1, const wchar_t * str2) +{ + return pt_private::compare_nc_generic(str1, str2); +} + +int compare_nc(const std::string & str1, const std::string & str2) +{ + return pt_private::compare_nc_str_generic(str1, str2); +} + +int compare_nc(const std::wstring & str1, const std::wstring & str2) +{ + return pt_private::compare_nc_str_generic(str1, str2); +} + +int compare_nc(const char * str1_begin, const char * str1_end, const char * str2) +{ + return pt_private::compare_nc_generic(str1_begin, str1_end, str2); +} + +int compare_nc(const wchar_t * str1_begin, const wchar_t * str1_end, const wchar_t * str2) +{ + return pt_private::compare_nc_generic(str1_begin, str1_end, str2); +} + + +bool is_equal(const char * str1, const char * str2) +{ + return pt_private::compare_generic(str1, str2) == 0; +} + +bool is_equal(const wchar_t * str1, const wchar_t * str2) +{ + return pt_private::compare_generic(str1, str2) == 0; +} + + +bool is_equal(const std::string & str1, const std::string & str2) +{ + return is_equal(str1.c_str(), str2.c_str()); +} + + +bool is_equal(const std::wstring & str1, const std::wstring & str2) +{ + return is_equal(str1.c_str(), str2.c_str()); +} + + + +bool is_equal(const char * str1_begin, const char * str1_end, const char * str2) +{ + return pt_private::compare_generic(str1_begin, str1_end, str2) == 0; +} + + +bool is_equal(const wchar_t * str1_begin, const wchar_t * str1_end, const wchar_t * str2) +{ + return pt_private::compare_generic(str1_begin, str1_end, str2) == 0; +} + + +bool is_equal_nc(const char * str1, const char * str2) +{ + return pt_private::compare_nc_generic(str1, str2) == 0; +} + + +bool is_equal_nc(const wchar_t * str1, const wchar_t * str2) +{ + return pt_private::compare_nc_generic(str1, str2) == 0; +} + + +bool is_equal_nc(const std::string & str1, const std::string & str2) +{ + return is_equal_nc(str1.c_str(), str2.c_str()); +} + + +bool is_equal_nc(const std::wstring & str1, const std::wstring & str2) +{ + return is_equal_nc(str1.c_str(), str2.c_str()); +} + + +bool is_equal_nc(const char * str1_begin, const char * str1_end, const char * str2) +{ + return pt_private::compare_nc_generic(str1_begin, str1_end, str2) == 0; +} + + +bool is_equal_nc(const wchar_t * str1_begin, const wchar_t * str1_end, const wchar_t * str2) +{ + return pt_private::compare_nc_generic(str1_begin, str1_end, str2) == 0; +} + + + + +bool is_substr(const char * short_str, const char * long_str) +{ + return pt_private::is_substr_generic(short_str, long_str); +} + + +bool is_substr(const wchar_t * short_str, const wchar_t * long_str) +{ + return pt_private::is_substr_generic(short_str, long_str); +} + + +bool is_substr(const std::string & short_str, const std::string & long_str) +{ + return is_substr(short_str.c_str(), long_str.c_str()); +} + + +bool is_substr(const std::wstring & short_str, const std::wstring & long_str) +{ + return is_substr(short_str.c_str(), long_str.c_str()); +} + + +bool is_substr_nc(const char * short_str, const char * long_str) +{ + return pt_private::is_substr_nc_generic(short_str, long_str); +} + +bool is_substr_nc(const wchar_t * short_str, const wchar_t * long_str) +{ + return pt_private::is_substr_nc_generic(short_str, long_str); +} + + +bool is_substr_nc(const std::string & short_str, const std::string & long_str) +{ + return pt_private::is_substr_nc_generic(short_str.c_str(), long_str.c_str()); +} + + +bool is_substr_nc(const std::wstring & short_str, const std::wstring & long_str) +{ + return pt_private::is_substr_nc_generic(short_str.c_str(), long_str.c_str()); +} + + + diff --git a/src/convert/text.h b/src/convert/text.h index d5b0532..d698047 100644 --- a/src/convert/text.h +++ b/src/convert/text.h @@ -38,46 +38,18 @@ #ifndef headerfile_picotools_convert_text #define headerfile_picotools_convert_text -#include "text_private.h" - +#include namespace PT { -bool IsWhite(wchar_t c, bool check_additional_chars = true, bool treat_new_line_as_white = true); +bool is_white(wchar_t c, bool check_additional_chars = true, bool treat_new_line_as_white = true); +bool is_digit(wchar_t c, int base = 10, int * digit = 0); +const char * skip_white(const char * str, bool check_additional_chars = true, bool treat_new_line_as_white = true); +const wchar_t * skip_white(const wchar_t * str, bool check_additional_chars = true, bool treat_new_line_as_white = true); -bool IsDigit(wchar_t c, int base = 10, int * digit = 0); - - -char ToLower(char c); -wchar_t ToLower(wchar_t c); - -char ToUpper(char c); -wchar_t ToUpper(wchar_t c); - -// rename to something like to_lower_emplace -// and add to_lower which returns string -void ToLower(std::string & str); -void ToLower(std::wstring & str); - -void ToUpper(std::string & str); -void ToUpper(std::wstring & str); - - -//////////////////////////// - -template -CharType * SkipWhite(CharType * str, bool check_additional_chars = true, bool treat_new_line_as_white = true) -{ - while( IsWhite(static_cast(*str), check_additional_chars, treat_new_line_as_white) ) - { - str += 1; - } - - return str; -} /* @@ -88,205 +60,87 @@ CharType * SkipWhite(CharType * str, bool check_additional_chars = true, bool tr * or to the last+one if there is no any white characters * */ -template -CharType * SkipWhiteFromBack(CharType * str_begin, CharType * str_end, bool check_additional_chars = true, bool treat_new_line_as_white = true) -{ - while( str_end > str_begin && IsWhite(static_cast(*(str_end-1)), check_additional_chars, treat_new_line_as_white) ) - { - str_end -= 1; - } +const char * skip_white_from_back(const char * str_begin, const char * str_end, bool check_additional_chars = true, bool treat_new_line_as_white = true); +const wchar_t * skip_white_from_back(const wchar_t * str_begin, const wchar_t * str_end, bool check_additional_chars = true, bool treat_new_line_as_white = true); - return str_end; -} - - -template -CharType * SkipWhiteFromBack(CharType * str, bool check_additional_chars = true, bool treat_new_line_as_white = true) -{ - CharType * str_begin = str; - - while( *str != 0 ) - { - str += 1; - } - - return SkipWhiteFromBack(str_begin, str, check_additional_chars, treat_new_line_as_white); -} - - -template -int CompareNoCase(const StringType1 * str1, const StringType2 * str2) -{ - while( *str1 && *str2 && ToLower(*str1) == ToLower(*str2) ) - { - ++str1; - ++str2; - } - - if( *str1 == 0 && *str2 == 0 ) - return 0; - - int c1; - int c2; - - if constexpr (sizeof(StringType1) == 1 && sizeof(StringType2) == 1) - { - c1 = ToLower((wchar_t)(unsigned char)(*str1)); - c2 = ToLower((wchar_t)(unsigned char)(*str2)); - } - else - { - c1 = ToLower(*str1); - c2 = ToLower(*str2); - } - - return c1 - c2; -} - - -template -int CompareNoCase(const StringType1 & str1, const StringType2 & str2) -{ - return CompareNoCase(str1.c_str(), str2.c_str()); -} - - -template -int CompareNoCasep(const StringType1 * str1, const StringType2 * str2) -{ - return CompareNoCase(str1, str2); -} +const char * skip_white_from_back(const char * str, bool check_additional_chars = true, bool treat_new_line_as_white = true); +const wchar_t * skip_white_from_back(const wchar_t * str, bool check_additional_chars = true, bool treat_new_line_as_white = true); +char to_lower(char c); +wchar_t to_lower(wchar_t c); -template -int CompareNoCase(const StringType1 * str1_begin, const StringType1 * str1_end, const StringType2 * str2) -{ - while( str1_begin < str1_end && *str2 && ToLower(*str1_begin) == ToLower(*str2) ) - { - ++str1_begin; - ++str2; - } +char to_upper(char c); +wchar_t to_upper(wchar_t c); - if( str1_begin == str1_end && *str2 == 0 ) - return 0; +void to_lower_emplace(std::string & str); +void to_lower_emplace(std::wstring & str); - int c1; - int c2; +void to_upper_emplace(std::string & str); +void to_upper_emplace(std::wstring & str); - if constexpr (sizeof(StringType1) == 1 && sizeof(StringType2) == 1) - { - c1 = str1_begin < str1_end ? ToLower((wchar_t)(unsigned char)(*str1_begin)) : 0; - c2 = ToLower((wchar_t)(unsigned char)(*str2)); - } - else - { - c1 = str1_begin < str1_end ? ToLower(*str1_begin) : 0; - c2 = ToLower(*str2); - } +std::string to_lower(const std::string & str); +std::wstring to_lower(const std::wstring & str); - return c1 - c2; -} +std::string to_upper(const std::string & str); +std::wstring to_upper(const std::wstring & str); + + +int compare(const char * str1, const char * str2); +int compare(const wchar_t * str1, const wchar_t * str2); + +int compare(const std::string & str1, const std::string & str2); +int compare(const std::wstring & str1, const std::wstring & str2); + +int compare(const char * str1_begin, const char * str1_end, const char * str2); +int compare(const wchar_t * str1_begin, const wchar_t * str1_end, const wchar_t * str2); + + +/* + * compare no case + */ +int compare_nc(const char * str1, const char * str2); +int compare_nc(const wchar_t * str1, const wchar_t * str2); + +int compare_nc(const std::string & str1, const std::string & str2); +int compare_nc(const std::wstring & str1, const std::wstring & str2); + +int compare_nc(const char * str1_begin, const char * str1_end, const char * str2); +int compare_nc(const wchar_t * str1_begin, const wchar_t * str1_end, const wchar_t * str2); +bool is_equal(const char * str1, const char * str2); +bool is_equal(const wchar_t * str1, const wchar_t * str2); + +bool is_equal(const std::string & str1, const std::string & str2); +bool is_equal(const std::wstring & str1, const std::wstring & str2); + +bool is_equal(const char * str1_begin, const char * str1_end, const char * str2); +bool is_equal(const wchar_t * str1_begin, const wchar_t * str1_end, const wchar_t * str2); + +bool is_equal_nc(const char * str1, const char * str2); +bool is_equal_nc(const wchar_t * str1, const wchar_t * str2); + +bool is_equal_nc(const std::string & str1, const std::string & str2); +bool is_equal_nc(const std::wstring & str1, const std::wstring & str2); + +bool is_equal_nc(const char * str1_begin, const char * str1_end, const char * str2); +bool is_equal_nc(const wchar_t * str1_begin, const wchar_t * str1_end, const wchar_t * str2); -template -bool EqualNoCase(const StringType1 * str1, const StringType2 * str2) -{ - return CompareNoCase(str1, str2) == 0; -} +bool is_substr(const char * short_str, const char * long_str); +bool is_substr(const wchar_t * short_str, const wchar_t * long_str); +bool is_substr(const std::string & short_str, const std::string & long_str); +bool is_substr(const std::wstring & short_str, const std::wstring & long_str); -template -bool EqualNoCase(const StringType1 & str1, const StringType2 & str2) -{ - return EqualNoCase(str1.c_str(), str2.c_str()); -} - - -template -bool EqualNoCasep(const StringType1 * str1, const StringType2 * str2) -{ - return EqualNoCase(str1, str2); -} - - - -template -bool EqualNoCase(const StringType1 * str1_begin, const StringType1 * str1_end, const StringType2 * str2) -{ - return CompareNoCase(str1_begin, str1_end, str2) == 0; -} - - - - - - - -template -bool IsSubStringp(const StringType1 * short_str, const StringType2 * long_str) -{ - while( *short_str && *long_str && wchar_t(*short_str) == wchar_t(*long_str) ) - { - ++short_str; - ++long_str; - } - - if( *short_str == 0 ) - return true; - -return false; -} - - -template -bool IsSubString(const StringType1 * short_str, const StringType2 * long_str) -{ - return IsSubStringp(short_str, long_str); -} - - -template -bool IsSubString(const StringType1 & short_str, const StringType2 & long_str) -{ - return IsSubStringp(short_str.c_str(), long_str.c_str()); -} - - -template -bool IsSubStringNoCasep(const StringType1 * short_str, const StringType2 * long_str) -{ - while( *short_str && *long_str && ToLower(*short_str) == ToLower(*long_str) ) - { - ++short_str; - ++long_str; - } - - if( *short_str == 0 ) - return true; - -return false; -} - - -template -bool IsSubStringNoCase(const StringType1 * short_str, const StringType2 * long_str) -{ - return IsSubStringNoCasep(short_str, long_str); -} - - -template -bool IsSubStringNoCase(const StringType1 & short_str, const StringType2 & long_str) -{ - return IsSubStringNoCasep(short_str.c_str(), long_str.c_str()); -} - +bool is_substr_nc(const char * short_str, const char * long_str); +bool is_substr_nc(const wchar_t * short_str, const wchar_t * long_str); +bool is_substr_nc(const std::string & short_str, const std::string & long_str); +bool is_substr_nc(const std::wstring & short_str, const std::wstring & long_str); diff --git a/src/convert/text_private.h b/src/convert/text_private.h index f1007fd..5957367 100644 --- a/src/convert/text_private.h +++ b/src/convert/text_private.h @@ -39,6 +39,7 @@ #define headerfile_picotools_convert_text_private #include +#include "text.h" namespace PT @@ -48,7 +49,7 @@ namespace pt_private { template -CharType ToLowerGeneric(CharType c) +CharType to_lower_generic(CharType c) { if( c >= 'A' && c <= 'Z' ) return c - 'A' + 'a'; @@ -58,7 +59,7 @@ CharType ToLowerGeneric(CharType c) template -CharType ToUpperGeneric(CharType c) +CharType to_upper_generic(CharType c) { if( c >= 'a' && c <= 'z' ) return c - 'a' + 'A'; @@ -68,25 +69,237 @@ CharType ToUpperGeneric(CharType c) template -void ToLowerStrGeneric(StringType & s) +void to_lower_str_generic(StringType & s) { typename StringType::size_type i; for(i=0 ; i -void ToUpperStrGeneric(StringType & s) +void to_upper_str_generic(StringType & s) { typename StringType::size_type i; for(i=0 ; i +CharType * skip_white_generic(CharType * str, bool check_additional_chars, bool treat_new_line_as_white) +{ + while( is_white(static_cast(*str), check_additional_chars, treat_new_line_as_white) ) + { + str += 1; + } + + return str; +} + + +template +CharType * skip_white_from_back_generic(CharType * str_begin, CharType * str_end, bool check_additional_chars, bool treat_new_line_as_white) +{ + while( str_end > str_begin && is_white(static_cast(*(str_end-1)), check_additional_chars, treat_new_line_as_white) ) + { + str_end -= 1; + } + + return str_end; +} + + +template +CharType * skip_white_from_back_generic(CharType * str, bool check_additional_chars, bool treat_new_line_as_white) +{ + CharType * str_begin = str; + + while( *str != 0 ) + { + str += 1; + } + + return skip_white_from_back_generic(str_begin, str, check_additional_chars, treat_new_line_as_white); +} + + + + +template +int compare_generic(const StringType1 * str1, const StringType2 * str2) +{ + while( *str1 && *str2 && *str1 == *str2 ) + { + ++str1; + ++str2; + } + + if( *str1 == 0 && *str2 == 0 ) + return 0; + + int c1; + int c2; + + if constexpr (sizeof(StringType1) == 1 && sizeof(StringType2) == 1) + { + c1 = (wchar_t)(unsigned char)(*str1); + c2 = (wchar_t)(unsigned char)(*str2); + } + else + { + c1 = *str1; + c2 = *str2; + } + + return c1 - c2; +} + + +template +int compare_str_generic(const StringType1 & str1, const StringType2 & str2) +{ + return compare_generic(str1.c_str(), str2.c_str()); +} + + +template +int compare_generic(const StringType1 * str1_begin, const StringType1 * str1_end, const StringType2 * str2) +{ + while( str1_begin < str1_end && *str2 && *str1_begin == *str2 ) + { + ++str1_begin; + ++str2; + } + + if( str1_begin == str1_end && *str2 == 0 ) + return 0; + + int c1; + int c2; + + if constexpr (sizeof(StringType1) == 1 && sizeof(StringType2) == 1) + { + c1 = str1_begin < str1_end ? (wchar_t)(unsigned char)(*str1_begin) : 0; + c2 = (wchar_t)(unsigned char)(*str2); + } + else + { + c1 = str1_begin < str1_end ? *str1_begin : 0; + c2 = *str2; + } + + return c1 - c2; +} + + + +template +int compare_nc_generic(const StringType1 * str1, const StringType2 * str2) +{ + while( *str1 && *str2 && to_lower(*str1) == to_lower(*str2) ) + { + ++str1; + ++str2; + } + + if( *str1 == 0 && *str2 == 0 ) + return 0; + + int c1; + int c2; + + if constexpr (sizeof(StringType1) == 1 && sizeof(StringType2) == 1) + { + c1 = to_lower((wchar_t)(unsigned char)(*str1)); + c2 = to_lower((wchar_t)(unsigned char)(*str2)); + } + else + { + c1 = to_lower(*str1); + c2 = to_lower(*str2); + } + + return c1 - c2; +} + + +template +int compare_nc_str_generic(const StringType1 & str1, const StringType2 & str2) +{ + return compare_nc(str1.c_str(), str2.c_str()); +} + + +template +int compare_nc_generic(const StringType1 * str1_begin, const StringType1 * str1_end, const StringType2 * str2) +{ + while( str1_begin < str1_end && *str2 && to_lower(*str1_begin) == to_lower(*str2) ) + { + ++str1_begin; + ++str2; + } + + if( str1_begin == str1_end && *str2 == 0 ) + return 0; + + int c1; + int c2; + + if constexpr (sizeof(StringType1) == 1 && sizeof(StringType2) == 1) + { + c1 = str1_begin < str1_end ? to_lower((wchar_t)(unsigned char)(*str1_begin)) : 0; + c2 = to_lower((wchar_t)(unsigned char)(*str2)); + } + else + { + c1 = str1_begin < str1_end ? to_lower(*str1_begin) : 0; + c2 = to_lower(*str2); + } + + return c1 - c2; +} + + + + +template +bool is_substr_generic(const StringType1 * short_str, const StringType2 * long_str) +{ + while( *short_str && *long_str && *short_str == *long_str ) + { + ++short_str; + ++long_str; + } + + if( *short_str == 0 ) + return true; + + return false; +} + + + +template +bool is_substr_nc_generic(const StringType1 * short_str, const StringType2 * long_str) +{ + while( *short_str && *long_str && to_lower(*short_str) == to_lower(*long_str) ) + { + ++short_str; + ++long_str; + } + + if( *short_str == 0 ) + return true; + + return false; +} + + + + } // namespace pt_private } // namespace PT diff --git a/src/space/space.cpp b/src/space/space.cpp index 4db4f1d..0e53374 100644 --- a/src/space/space.cpp +++ b/src/space/space.cpp @@ -1614,7 +1614,7 @@ Space * Space::get_object_field_nc(const wchar_t * field) while( i != value.value_object.end() ) { - if( EqualNoCase(field, i->first.c_str()) ) + if( is_equal_nc(field, i->first.c_str()) ) { return i->second; } @@ -1639,7 +1639,7 @@ const Space * Space::get_object_field_nc(const wchar_t * field) const while( i != value.value_object.cend() ) { - if( EqualNoCase(field, i->first.c_str()) ) + if( is_equal_nc(field, i->first.c_str()) ) { return i->second; }