14#include "arccore/base/internal/StringImpl.h"
15#include "arccore/base/BasicTranscoder.h"
16#include "arccore/base/CStringUtils.h"
17#include "arccore/base/StringView.h"
32bool global_arccore_debug_string =
false;
36const char*
const global_empty_string =
"";
43:
public std::exception
48 virtual const char* what()
const ARCCORE_NOEXCEPT
59#ifdef ARCCORE_DEBUG_UNISTRING
61_badStringImplReference(StringImpl* ptr)
63 cerr <<
"** FATAL: Trying to use deleted StringImpl " << ptr <<
'\n';
67inline void StringImpl::
70#ifdef ARCCORE_DEBUG_UNISTRING
71 if (m_nb_ref.value()<=0){
72 _badStringImplReference(
this);
80inline void StringImpl::
81_finalizeUtf8Creation()
83 m_flags |= eValidUtf8;
85 if (m_utf8_array.empty())
86 m_utf8_array.add(
'\0');
87 else if (m_utf8_array.back()!=
'\0')
88 m_utf8_array.add(
'\0');
94inline void StringImpl::
95_initFromSpan(Span<const Byte> bytes)
98 _finalizeUtf8Creation();
105StringImpl(std::string_view str)
109 auto b =
reinterpret_cast<const Byte*
>(str.data());
110 _initFromSpan(Span<const Byte>(b,str.size()));
117StringImpl(Span<const UChar> uchars)
122 m_flags = eValidUtf16;
129StringImpl(
const StringImpl& str)
131, m_flags(str.m_flags)
132, m_utf16_array(str.m_utf16_array)
133, m_utf8_array(str.m_utf8_array)
141StringImpl(Span<const Byte> bytes)
145 _initFromSpan(bytes);
161Span<const Byte> StringImpl::
164 Span<const Byte> x = largeUtf8();
165 Int64 size = x.size();
167 return { x.data(), size-1 };
174 std::cerr <<
"INTERNAL ERROR: Null size in StringImpl::bytes()";
175 return {
reinterpret_cast<const Byte*
>(global_empty_string), 0 };
181std::string_view StringImpl::
184 Span<const Byte> x = bytes();
185 return std::string_view(
reinterpret_cast<const char*
>(x.data()),x.size());
191StringView StringImpl::
194 return StringView(bytes());
214 Int32 r = --m_nb_ref;
215#ifndef ARCCORE_DEBUG_UNISTRING
224ConstArrayView<UChar> StringImpl::
229 return m_utf16_array.view().smallView();
235Span<const Byte> StringImpl::
240 return m_utf8_array.view();
247isEqual(StringImpl* str)
251 Span<const Byte> ref_array = str->largeUtf8();
260isLessThan(StringImpl* str)
264 if (m_flags & eValidUtf8){
265 Span<const Byte> ref_array = str->largeUtf8();
269 ARCCORE_ASSERT((0),(
"InternalError in StringImpl::isEqual()"));
277isEqual(StringView str)
281 return str.toStdStringView() == toStdStringView();
288isLessThan(StringView str)
292 return toStdStringView() < str.toStdStringView();
298StringImpl* StringImpl::
303 StringImpl* n =
new StringImpl(*
this);
314 if (m_flags & eValidUtf8) {
315 ARCCORE_ASSERT((!m_utf8_array.empty()),(
"Not 0 terminated utf8 encoding"));
316 return m_utf8_array.size()<=1;
318 if (m_flags & eValidUtf16) {
319 ARCCORE_ASSERT((!m_utf16_array.empty()),(
"Not 0 terminated utf16 encoding"));
320 return m_utf16_array.size()<=1;
322 ARCCORE_ASSERT((0),(
"InternalError in StringImpl::empty()"));
329StringImpl* StringImpl::
330append(StringImpl* str)
334 Span<const Byte> ref_str = str->largeUtf8();
335 _appendUtf8(ref_str);
342StringImpl* StringImpl::
343append(StringView str)
345 Span<const Byte> str_bytes = str.bytes();
346 if (!str_bytes.data())
352 _appendUtf8(Span<const Byte>(str_bytes.data(),str_bytes.size() + 1));;
360_appendUtf8(Span<const Byte> ref_str)
362 Int64 ref_size = ref_str.size();
363 Int64 utf8_size = m_utf8_array.size();
364 Int64 current_size = utf8_size - 1;
366 ARCCORE_ASSERT((ref_size>0),(
"Bad ref_size"));
367 ARCCORE_ASSERT((utf8_size>0),(
"Bad utf8_size"));
368 ARCCORE_ASSERT((ref_str[ref_size-1]==0),(
"Bad ref null terminal"));
369 ARCCORE_ASSERT((m_utf8_array[utf8_size-1]==0),(
"Bad ref null terminal"));
371 m_utf8_array.resize(current_size + ref_size);
372 std::memcpy(&m_utf8_array[current_size],ref_str.data(),ref_size);
374 m_flags |= eValidUtf8;
381StringImpl* StringImpl::
386 BasicTranscoder::replaceWS(m_utf8_array);
393StringImpl* StringImpl::
398 BasicTranscoder::collapseWS(m_utf8_array);
405StringImpl* StringImpl::
410 BasicTranscoder::upperCase(m_utf8_array);
417StringImpl* StringImpl::
422 BasicTranscoder::lowerCase(m_utf8_array);
429StringImpl* StringImpl::
430substring(StringImpl* str,Int64 pos,Int64 len)
432 StringImpl* s =
new StringImpl();
433 BasicTranscoder::substring(s->m_utf8_array,str->largeUtf8(),pos,len);
434 s->m_flags |= eValidUtf8;
444 if (m_flags & eValidUtf16)
447 if (m_flags & eValidUtf8){
448 ARCCORE_ASSERT(m_utf16_array.empty(),(
"Not empty utf16_array"));
449 BasicTranscoder::transcodeFromUtf8ToUtf16(m_utf8_array,m_utf16_array);
450 m_flags |= eValidUtf16;
454 ARCCORE_ASSERT((0),(
"InternalError in StringImpl::_createUtf16()"));
463 if (m_flags & eValidUtf8)
466 if (m_flags & eValidUtf16){
467 ARCCORE_ASSERT(m_utf8_array.empty(),(
"Not empty utf8_array"));
469 _finalizeUtf8Creation();
473 ARCCORE_ASSERT((0),(
"InternalError in StringImpl::_createUtf16()"));
480_setUtf16(Span<const UChar> src)
483 if (m_utf16_array.empty())
484 m_utf16_array.add(0);
485 else if (m_utf16_array.back()!=
'\0')
486 m_utf16_array.add(0);
495 m_flags &= ~eValidUtf16;
496 m_utf16_array.clear();
505 m_flags &= ~eValidUtf8;
506 m_utf8_array.clear();
513_printStrUtf16(std::ostream& o,Span<const UChar> str)
515 Int64 buf_size = str.size();
516 o <<
"(bufsize=" << buf_size
517 <<
" begin=" << str.data() <<
" - ";
518 for( Int64 i=0; i<buf_size; ++i )
519 o << (
int)str[i] <<
' ';
527_printStrUtf8(std::ostream& o,Span<const Byte> str)
529 Int64 buf_size = str.size();
530 o <<
"(bufsize=" << buf_size <<
" - ";
531 for( Int64 i=0; i<buf_size; ++i )
532 o << (
int)str[i] <<
' ';
540internalDump(std::ostream& ostr)
542 ostr <<
"(utf8=valid=" << ((m_flags & eValidUtf8)!=0)
543 <<
",len=" << m_utf8_array.size() <<
",val=";
544 _printStrUtf8(ostr,m_utf8_array);
547 ostr <<
"(utf16=valid=" << ((m_flags & eValidUtf16)!=0)
548 <<
",len=" << m_utf16_array.size() <<
",val=";
549 _printStrUtf16(ostr,m_utf16_array);
static void transcodeFromUtf16ToUtf8(Span< const UChar > utf16, CoreArray< Byte > &utf8)
Traduit depuis UTF16 vers UTF8.
ARCCORE_BASE_EXPORT bool isLess(const char *s1, const char *s2)
Retourne true si s1 est inférieur (ordre alphabétique) à s2 , false sinon.
ARCCORE_BASE_EXPORT bool isEqual(const char *s1, const char *s2)
Retourne true si s1 et s2 sont identiques, false sinon.
Espace de nom de Arccore.
unsigned char Byte
Type d'un octet.