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"
33bool global_arccore_debug_string =
false;
37 const char*
const global_empty_string =
"";
44:
public std::exception
48 StringException(
const char* where)
51 ~StringException() ARCCORE_NOEXCEPT {}
52 virtual const char* what()
const ARCCORE_NOEXCEPT
65#ifdef ARCCORE_DEBUG_UNISTRING
69 cerr <<
"** FATAL: Trying to use deleted StringImpl " << ptr <<
'\n';
73inline void StringImpl::
76#ifdef ARCCORE_DEBUG_UNISTRING
77 if (m_nb_ref.value() <= 0) {
78 _badStringImplReference(
this);
86inline void StringImpl::
87_finalizeUtf8Creation()
89 m_flags |= eValidUtf8;
91 if (m_utf8_array.empty())
92 m_utf8_array.add(
'\0');
93 else if (m_utf8_array.back() !=
'\0')
94 m_utf8_array.add(
'\0');
100inline void StringImpl::
103 m_utf8_array =
bytes;
104 _finalizeUtf8Creation();
111StringImpl(std::string_view str)
115 auto b =
reinterpret_cast<const Byte*
>(str.data());
116 _initFromSpan(Span<const Byte>(b, str.size()));
128 m_flags = eValidUtf16;
137, m_flags(str.m_flags)
138, m_utf16_array(str.m_utf16_array)
139, m_utf8_array(str.m_utf8_array)
151 _initFromSpan(bytes);
173 return { x.
data(), size - 1 };
180 std::cerr <<
"INTERNAL ERROR: Null size in StringImpl::bytes()";
181 return {
reinterpret_cast<const Byte*
>(global_empty_string), 0 };
187std::string_view StringImpl::
191 return std::string_view(
reinterpret_cast<const char*
>(x.
data()), x.
size());
197StringView StringImpl::
200 return StringView(
bytes());
220 Int32 r = --m_nb_ref;
221#ifndef ARCCORE_DEBUG_UNISTRING
235 return m_utf16_array.view();
246 return m_utf8_array.view();
266isLessThan(StringImpl* str)
270 if (m_flags & eValidUtf8) {
271 Span<const Byte> ref_array = str->largeUtf8();
275 ARCCORE_ASSERT((0), (
"InternalError in StringImpl::isEqual()"));
287 return str.toStdStringView() == toStdStringView();
298 return toStdStringView() < str.toStdStringView();
309 StringImpl* n =
new StringImpl(*
this);
320 if (m_flags & eValidUtf8) {
321 ARCCORE_ASSERT((!m_utf8_array.empty()), (
"Not 0 terminated utf8 encoding"));
322 return m_utf8_array.size() <= 1;
324 if (m_flags & eValidUtf16) {
325 ARCCORE_ASSERT((!m_utf16_array.empty()), (
"Not 0 terminated utf16 encoding"));
326 return m_utf16_array.size() <= 1;
328 ARCCORE_ASSERT((0), (
"InternalError in StringImpl::empty()"));
340 Span<const Byte> ref_str = str->largeUtf8();
341 _appendUtf8(ref_str);
351 Span<const Byte> str_bytes = str.
bytes();
352 if (!str_bytes.data())
358 _appendUtf8(Span<const Byte>(str_bytes.data(), str_bytes.size() + 1));
369 Int64 ref_size = ref_str.size();
370 Int64 utf8_size = m_utf8_array.size();
371 Int64 current_size = utf8_size - 1;
373 ARCCORE_ASSERT((ref_size > 0), (
"Bad ref_size"));
374 ARCCORE_ASSERT((utf8_size > 0), (
"Bad utf8_size"));
375 ARCCORE_ASSERT((ref_str[ref_size - 1] == 0), (
"Bad ref null terminal"));
376 ARCCORE_ASSERT((m_utf8_array[utf8_size - 1] == 0), (
"Bad ref null terminal"));
378 m_utf8_array.resize(current_size + ref_size);
379 std::memcpy(&m_utf8_array[current_size], ref_str.data(), ref_size);
381 m_flags |= eValidUtf8;
393 Impl::BasicTranscoder::replaceWS(m_utf8_array);
405 Impl::BasicTranscoder::collapseWS(m_utf8_array);
417 Impl::BasicTranscoder::upperCase(m_utf8_array);
429 Impl::BasicTranscoder::lowerCase(m_utf8_array);
439 StringImpl* s =
new StringImpl();
440 Impl::BasicTranscoder::substring(s->m_utf8_array, str->largeUtf8(), pos, len);
441 s->m_flags |= eValidUtf8;
451 if (m_flags & eValidUtf16)
454 if (m_flags & eValidUtf8) {
455 ARCCORE_ASSERT(m_utf16_array.empty(), (
"Not empty utf16_array"));
456 Impl::BasicTranscoder::transcodeFromUtf8ToUtf16(m_utf8_array, m_utf16_array);
457 m_flags |= eValidUtf16;
461 ARCCORE_ASSERT((0), (
"InternalError in StringImpl::_createUtf16()"));
470 if (m_flags & eValidUtf8)
473 if (m_flags & eValidUtf16) {
474 ARCCORE_ASSERT(m_utf8_array.empty(), (
"Not empty utf8_array"));
476 _finalizeUtf8Creation();
480 ARCCORE_ASSERT((0), (
"InternalError in StringImpl::_createUtf16()"));
490 if (m_utf16_array.empty())
491 m_utf16_array.add(0);
492 else if (m_utf16_array.back() !=
'\0')
493 m_utf16_array.add(0);
502 m_flags &= ~eValidUtf16;
503 m_utf16_array.clear();
512 m_flags &= ~eValidUtf8;
513 m_utf8_array.clear();
522 Int64 buf_size = str.size();
523 o <<
"(bufsize=" << buf_size
524 <<
" begin=" << str.data() <<
" - ";
525 for (
Int64 i = 0; i < buf_size; ++i)
526 o << (
int)str[i] <<
' ';
536 Int64 buf_size = str.size();
537 o <<
"(bufsize=" << buf_size <<
" - ";
538 for (
Int64 i = 0; i < buf_size; ++i)
539 o << (
int)str[i] <<
' ';
547internalDump(std::ostream& ostr)
549 ostr <<
"(utf8=valid=" << ((m_flags & eValidUtf8) != 0)
550 <<
",len=" << m_utf8_array.size() <<
",val=";
551 _printStrUtf8(ostr, m_utf8_array);
554 ostr <<
"(utf16=valid=" << ((m_flags & eValidUtf16) != 0)
555 <<
",len=" << m_utf16_array.size() <<
",val=";
556 _printStrUtf16(ostr, m_utf16_array);
Constant view of an array of type T.
static void transcodeFromUtf16ToUtf8(Span< const UChar > utf16, CoreArray< Byte > &utf8)
Translates from UTF16 to UTF8.
constexpr __host__ __device__ pointer data() const noexcept
Pointer to the start of the view.
constexpr __host__ __device__ SizeType size() const noexcept
Returns the size of the array.
View of an array of elements of type T.
Implementation of the String class.
Span< const Byte > bytes()
same as largeUtf8() but WITHOUT the null terminator
Span< const Byte > largeUtf8()
View of the UTF-8 encoding WITH null terminator.
View of a UTF-8 character string.
bool isLess(const char *s1, const char *s2)
Returns true if s1 is less than (alphabetical order) s2 , false otherwise.
bool isEqual(const char *s1, const char *s2)
Returns true if s1 and s2 are identical, false otherwise.
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --
std::int64_t Int64
Signed integer type of 64 bits.
unsigned char Byte
Type of a byte.
std::int32_t Int32
Signed integer type of 32 bits.