23 bool astringCheckReported=
false;
26template<
typename TChar>
27requires alib::characters::IsCharacter<TChar>
31 if ( !astringCheckReported ) {
32 astringCheckReported=
true;
33 ALIB_MESSAGE(
"STRINGS",
"ALIB_DEBUG_STRINGS is enabled" )
37 "Nulled string has a length of ", length )
39 for (
integer i= length -1 ; i >= 0 ; --i)
40 if ( buffer[i] ==
'\0' ) {
41 ALIB_ERROR(
"STRINGS",
"Found termination character '\\0' in buffer. Index=", i )
51template<
typename TChar>
52requires alib::characters::IsCharacter<TChar>
53template<lang::Case TSensitivity>
60 "Illegal start index given: 0 <= {} < {}.", startIdx, length )
62 "Illegal end index given: {} > {}.", endIdx, length -nLen + 1 )
63 const TChar* buf= buffer + startIdx;
64 const TChar* bufEnd= buffer + endIdx;
65 const TChar* nBuf= needle.Buffer();
66 const TChar* nBufEnd= nBuf + nLen;
68 while ( buf < bufEnd ) {
79template<
typename TChar>
80requires alib::characters::IsCharacter<TChar>
83 while( idx < length ) {
84 if( buffer[idx] == opener ) ++openCnt;
85 if( buffer[idx] == closer && --openCnt == 0 )
91 return openCnt == 0 ? idx : -openCnt;
97template<
typename TChar>
98requires alib::characters::IsCharacter<TChar>
104 if ( newIdx ==
nullptr )
105 indexPointer= &startIdx;
107 indexPointer= newIdx;
108 *indexPointer= startIdx;
115template<
typename TChar>
116requires alib::characters::IsCharacter<TChar>
122 if ( newIdx ==
nullptr )
123 indexPointer= &startIdx;
125 indexPointer= newIdx;
126 *indexPointer= startIdx;
133template<
typename TChar>
134requires alib::characters::IsCharacter<TChar>
140 if ( newIdx ==
nullptr )
141 indexPointer= &startIdx;
143 indexPointer= newIdx;
144 *indexPointer= startIdx;
151template<
typename TChar>
152requires alib::characters::IsCharacter<TChar>
158 if ( newIdx ==
nullptr )
159 indexPointer= &startIdx;
161 indexPointer= newIdx;
162 *indexPointer= startIdx;
169template<
typename TChar>
170requires alib::characters::IsCharacter<TChar>
176 if ( newIdx ==
nullptr )
177 indexPointer= &startIdx;
179 indexPointer= newIdx;
180 *indexPointer= startIdx;
187template<
typename TChar>
188requires alib::characters::IsCharacter<TChar>
194 if ( newIdx ==
nullptr )
195 indexPointer= &startIdx;
197 indexPointer= newIdx;
198 *indexPointer= startIdx;
205template<
typename TChar>
206requires alib::characters::IsCharacter<TChar>
212 if ( newIdx ==
nullptr )
213 indexPointer= &startIdx;
215 indexPointer= newIdx;
216 *indexPointer= startIdx;
232 const nchar* cs= buffer;
235 #if defined( _WIN32 )
237 int conversionSize= MultiByteToWideChar( CP_UTF8, 0, cs,
int( length ),
nullptr, 0 );
241 if ( conversionSize == 0 ) {
243 int error= GetLastError();
245 NString128 msg(
"AString: Conversion to wide character string failed (Error: " );
246 if ( error == ERROR_INSUFFICIENT_BUFFER ) msg._(
"ERROR_INSUFFICIENT_BUFFER." );
247 else if ( error == ERROR_INVALID_FLAGS ) msg._(
"ERROR_INVALID_FLAGS." );
248 else if ( error == ERROR_INVALID_PARAMETER ) msg._(
"ERROR_INVALID_PARAMETER" );
249 else if ( error == ERROR_NO_UNICODE_TRANSLATION ) msg._(
"ERROR_NO_UNICODE_TRANSLATION" );
257 if( conversionSize > length ) {
258 ALIB_ERROR(
"STRINGS",
"MBCS to WCS conversion failed. Conversion length=",
264 return conversionSize;
267 #elif defined (__GLIBCXX__) || defined(_LIBCPP_VERSION) || defined(__APPLE__) || defined(__ANDROID_NDK__)
269 size_t conversionSize= mbsnrtowcs(
nullptr, &cs,
size_t(length), 0,
nullptr );
270 if ( conversionSize ==
size_t(-1) ) {
271 ALIB_WARNING(
"STRINGS",
"MBCS to WCS conversion failed. Illegal MBC sequence. "
272 "Probably UTF-8 is not set in locale" )
277 "MBCS to WCS conversion failed. Conversion length=", conversionSize )
279 return
integer(conversionSize);
283 #pragma message ("Unknown Platform in file: " __FILE__ )
323 const xchar* src= buffer;
324 const xchar* srcEnd= buffer + length;
326#if ALIB_SIZEOF_WCHAR_T == 4
329 while (src < srcEnd) {
330 const char32_t uc =
static_cast<char32_t>( *src++ );
331 if ((uc - 0xd800) >= 2048)
335 && ((uc & 0xfffffc00) == 0xd800)
336 && ((
char32_t(*src++) & 0xfffffc00) == 0xdc00),
337 "STRINGS",
"Error decoding UTF16" )
346 while (src < srcEnd) {
349 || ( uc >= 0xe000 && uc <= 0x10ffff ),
"STRINGS",
350 "Illegal unicode 32 bit codepoint" )
378template<
typename TChar>
379requires alib::characters::IsCharacter<TChar>
382 return std::hash<std::basic_string_view<TChar>>()(
383 std::basic_string_view<TChar>( Buffer(),
size_t(
Length() ) ) );
391template<
typename TChar>
392requires alib::characters::IsCharacter<TChar>
394 std::size_t result= 68460391ul * ( size_t(length) + 1 );
397 auto* end = buffer + length;
398 while( begin != end )
399 result = 199ul * result + std::size_t(
ToUpper<TChar>( *begin++ ) );
410#if ALIB_DEBUG_STRINGS
#define ALIB_MESSAGE(domain,...)
#define ALIB_WARNING(domain,...)
#define ALIB_ERROR(domain,...)
#define ALIB_ASSERT_ERROR(cond, domain,...)
uint64_t ParseDec(integer startIdx=0, TNumberFormat< TChar > *numberFormat=nullptr, integer *newIdx=nullptr) const
uint64_t ParseDecDigits(integer startIdx=0, integer *newIdx=nullptr) const
constexpr integer Length() const
std::size_t HashcodeIgnoreCase() const
double ParseFloat(integer startIdx=0, TNumberFormat< TChar > *numberFormat=nullptr, integer *newIdx=nullptr) const
std::size_t Hashcode() const
int64_t ParseInt(integer startIdx=0, TNumberFormat< TChar > *numberFormat=nullptr, integer *newIdx=nullptr) const
uint64_t ParseBin(integer startIdx=0, TNumberFormat< TChar > *numberFormat=nullptr, integer *newIdx=nullptr) const
uint64_t ParseHex(integer startIdx=0, TNumberFormat< TChar > *numberFormat=nullptr, integer *newIdx=nullptr) const
integer WStringLength() const
integer indexOfString(const TString &needle, integer startIdx, integer endIdx) const
integer IndexOfSegmentEnd(TChar opener, TChar closer, integer idx) const
uint64_t ParseOct(integer startIdx=0, TNumberFormat< TChar > *numberFormat=nullptr, integer *newIdx=nullptr) const
integer Length(const TChar *cstring)
bool Equal(TChar lhs, TRhs rhs)
uint64_t ParseOct(const TString< TChar > &src, integer &idx, const TNumberFormat< TChar > &nf)
uint64_t ParseHex(const TString< TChar > &src, integer &idx, const TNumberFormat< TChar > &nf)
int64_t ParseInt(const TString< TChar > &src, integer &idx, const TNumberFormat< TChar > &nf)
uint64_t ParseDecDigits(const TString< TChar > &src, integer &idx)
double ParseFloat(const TString< TChar > &src, integer &idx, const TNumberFormat< TChar > &nf)
uint64_t ParseDec(const TString< TChar > &src, integer &idx, const TNumberFormat< TChar > &nf)
uint64_t ParseBin(const TString< TChar > &src, integer &idx, const TNumberFormat< TChar > &nf)
characters::wchar wchar
Type alias in namespace #"%alib".
lang::integer integer
Type alias in namespace #"%alib".
characters::nchar nchar
Type alias in namespace #"%alib".
characters::xchar xchar
Type alias in namespace #"%alib".
NLocalString< 128 > NString128
Type alias name for #"TLocalString;TLocalString<nchar,128>".
lang::uinteger uinteger
Type alias in namespace #"%alib".