• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include <taihe/string.abi.h>
16 
17 #include <algorithm>
18 
19 // Converts a TString into its corresponding heap-allocated TStringData
20 // structure.
21 // # Arguments
22 // - `tstr`: The TString to be converted.
23 // # Returns
24 // - A pointer to the TStringData structure if the TString is heap-allocated.
25 // - `nullptr` if the TString is a reference (TSTRING_REF is set).
to_heap(struct TString tstr)26 TH_INLINE struct TStringData *to_heap(struct TString tstr)
27 {
28     if (tstr.flags & TSTRING_REF) {
29         return nullptr;
30     }
31     return reinterpret_cast<struct TStringData *>(const_cast<char *>(tstr.ptr) - offsetof(struct TStringData, buffer));
32 }
33 
tstr_initialize(struct TString * tstr_ptr,uint32_t capacity)34 char *tstr_initialize(struct TString *tstr_ptr, uint32_t capacity)
35 {
36     size_t bytes_required = sizeof(struct TStringData) + sizeof(char) * capacity;
37     struct TStringData *sh = reinterpret_cast<struct TStringData *>(malloc(bytes_required));
38     tref_set(&sh->count, 1);
39     tstr_ptr->flags = 0;
40     tstr_ptr->ptr = sh->buffer;
41     return sh->buffer;
42 }
43 
tstr_new(char const * value TH_NONNULL,size_t len)44 struct TString tstr_new(char const *value TH_NONNULL, size_t len)
45 {
46     struct TString tstr;
47     char *buf = tstr_initialize(&tstr, len + 1);
48     buf = std::copy(value, value + len, buf);
49     *buf = '\0';
50     tstr.length = len;
51     return tstr;
52 }
53 
tstr_new_ref(char const * buf TH_NONNULL,size_t len)54 struct TString tstr_new_ref(char const *buf TH_NONNULL, size_t len)
55 {
56     struct TString tstr;
57     tstr.flags = TSTRING_REF;
58     tstr.length = len;
59     tstr.ptr = buf;
60     return tstr;
61 }
62 
tstr_dup(struct TString tstr)63 struct TString tstr_dup(struct TString tstr)
64 {
65     struct TStringData *sh = to_heap(tstr);
66     if (!sh) {
67         return tstr_new(tstr.ptr, tstr.length);
68     }
69     tref_inc(&sh->count);
70     return tstr;
71 }
72 
tstr_drop(struct TString tstr)73 void tstr_drop(struct TString tstr)
74 {
75     struct TStringData *sh = to_heap(tstr);
76     if (!sh) {
77         return;
78     }
79     if (tref_dec(&sh->count)) {
80         free(sh);
81     }
82 }
83 
tstr_concat(size_t count,struct TString const * tstr_list)84 struct TString tstr_concat(size_t count, struct TString const *tstr_list)
85 {
86     size_t len = 0;
87     for (size_t i = 0; i < count; ++i) {
88         len += tstr_list[i].length;
89     }
90     struct TString tstr;
91     char *buf = tstr_initialize(&tstr, len + 1);
92     for (size_t i = 0; i < count; ++i) {
93         buf = std::copy(tstr_list[i].ptr, tstr_list[i].ptr + tstr_list[i].length, buf);
94     }
95     *buf = '\0';
96     tstr.length = len;
97     return tstr;
98 }
99 
tstr_substr(struct TString tstr,size_t pos,size_t len)100 struct TString tstr_substr(struct TString tstr, size_t pos, size_t len)
101 {
102     if (pos > tstr.length) {
103         len = 0;
104     } else if (pos + len > tstr.length) {
105         len = tstr.length - pos;
106     }
107     return tstr_new_ref(tstr.ptr + pos, len);
108 }