1 /*
2 * Copyright (c) 2025 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #ifndef COMMON_INTERFACES_OBJECTS_STRING_BASE_STRING_INL1_H
17 #define COMMON_INTERFACES_OBJECTS_STRING_BASE_STRING_INL1_H
18
19 #include <cstring>
20
21 #include "common_interfaces/objects/string/base_string_declare.h"
22
23 #include "common_interfaces/objects/string/line_string-inl.h"
24 #include "common_interfaces/objects/string/sliced_string-inl.h"
25 #include "common_interfaces/objects/string/tree_string-inl.h"
26 #include "common_interfaces/objects/utils/utf_utils.h"
27
28 namespace common {
IsUtf8()29 inline bool BaseString::IsUtf8() const
30 {
31 uint32_t bits = GetLengthAndFlags();
32 return CompressedStatusBit::Decode(bits) == STRING_COMPRESSED;
33 }
34
IsUtf16()35 inline bool BaseString::IsUtf16() const
36 {
37 uint32_t bits = GetLengthAndFlags();
38 return CompressedStatusBit::Decode(bits) == STRING_UNCOMPRESSED;
39 }
40
GetLength()41 inline uint32_t BaseString::GetLength() const
42 {
43 uint32_t bits = GetLengthAndFlags();
44 return LengthBits::Decode(bits);
45 }
46
InitLengthAndFlags(uint32_t length,bool compressed,bool isIntern)47 inline void BaseString::InitLengthAndFlags(uint32_t length, bool compressed, bool isIntern)
48 {
49 DCHECK_CC(length < BaseString::MAX_STRING_LENGTH);
50 uint32_t newVal = 0;
51 newVal = IsInternBit::Update(newVal, isIntern);
52 newVal = CompressedStatusBit::Update(newVal, (compressed ? STRING_COMPRESSED : STRING_UNCOMPRESSED));
53 newVal = LengthBits::Update(newVal, length);
54 SetLengthAndFlags(newVal);
55 }
56
SetIsInternString()57 inline void BaseString::SetIsInternString()
58 {
59 uint32_t bits = GetLengthAndFlags();
60 uint32_t newVal = IsInternBit::Update(bits, true);
61 SetLengthAndFlags(newVal);
62 }
63
IsInternString()64 inline bool BaseString::IsInternString() const
65 {
66 uint32_t bits = GetLengthAndFlags();
67 return IsInternBit::Decode(bits);
68 }
69
ClearInternStringFlag()70 inline void BaseString::ClearInternStringFlag()
71 {
72 uint32_t bits = GetLengthAndFlags();
73 uint32_t newVal = IsInternBit::Update(bits, false);
74 SetLengthAndFlags(newVal);
75 }
76
TryGetHashCode(uint32_t * hash)77 inline bool BaseString::TryGetHashCode(uint32_t *hash) const
78 {
79 uint32_t hashcode = GetMixHashcode();
80 if (hashcode == 0 && GetLength() != 0) {
81 return false;
82 }
83 *hash = hashcode;
84 return true;
85 }
86
87 // not change this data structure.
88 // if string is not flat, this func has low efficiency.
89 template <typename ReadBarrier>
GetHashcode(ReadBarrier && readBarrier)90 uint32_t PUBLIC_API BaseString::GetHashcode(ReadBarrier &&readBarrier)
91 {
92 uint32_t hashcode = GetMixHashcode();
93 // GetLength() == 0 means it's an empty array.No need to computeHashCode again when hashseed is 0.
94 if (hashcode == 0 && GetLength() != 0) {
95 hashcode = ComputeHashcode(std::forward<ReadBarrier>(readBarrier));
96 SetMixHashcode(hashcode);
97 }
98 return hashcode;
99 }
100
101 // Check that two spans are equal. Should have the same length.
102 /* static */
103 template <typename T, typename T1>
StringsAreEquals(Span<const T> & str1,Span<const T1> & str2)104 bool BaseString::StringsAreEquals(Span<const T> &str1, Span<const T1> &str2)
105 {
106 DCHECK_CC(str1.Size() <= str2.Size());
107 size_t size = str1.Size();
108 if constexpr (std::is_same_v<T, T1>) {
109 return !memcmp(str1.data(), str2.data(), size * sizeof(T));
110 } else {
111 for (size_t i = 0; i < size; i++) {
112 auto left = static_cast<uint16_t>(str1[i]);
113 auto right = static_cast<uint16_t>(str2[i]);
114 if (left != right) {
115 return false;
116 }
117 }
118 return true;
119 }
120 }
121
MixHashcode(uint32_t hashcode,bool isInteger)122 inline uint32_t BaseString::MixHashcode(uint32_t hashcode, bool isInteger)
123 {
124 return isInteger ? (hashcode | IS_INTEGER_MASK) : (hashcode & (~IS_INTEGER_MASK));
125 }
126 } // namespace common
127
128 #endif //COMMON_INTERFACES_OBJECTS_STRING_BASE_STRING_INL1_H