1 /*
2 * Copyright (C) 2021 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 #include <string.h>
17 #include "hcf_string.h"
18
19 const uint32_t STRING_ALLOC_SIZE = 10;
20 const uint32_t STRING_END_CHAR_LENGTH = 1;
21 const char STRING_END_CHAR = '\0';
22 #define MAX_INT 0x7FFFFFFF
23 #define MAX_UINT 0xFFFFFFFF
24
25 /*
26 * Append string pointer
27 * Notice: It will add '\0' automatically.
28 * @param self: self pointer.
29 * @param str: string pointer.
30 * @return true (ok), false (error)
31 */
StringAppendPointer(HcString * self,const char * str)32 bool StringAppendPointer(HcString *self, const char *str)
33 {
34 if (self != NULL && str != NULL) {
35 // remove '\0'
36 ParcelPopBack(&self->parcel, STRING_END_CHAR_LENGTH);
37 // append string (include '\0')
38 return ParcelWrite(&self->parcel, (void *)str, strlen(str) + 1);
39 }
40
41 return false;
42 }
43
44 /*
45 * Assign a value to the HcString
46 * Notice: It will add '\0' automatically.
47 * @param self: self pointer.
48 * @param str: assign value of string pointer.
49 * @return true (ok), false (error)
50 */
StringSetPointer(HcString * self,const char * str)51 bool StringSetPointer(HcString *self, const char *str)
52 {
53 if (self != NULL) {
54 DeleteParcel(&self->parcel);
55 return StringAppendPointer(self, str);
56 }
57
58 return false;
59 }
60
61 /*
62 * Assign a value to the HcString with fixed length
63 * Notice: It will add '\0' automatically.
64 * @param self: self pointer.
65 * @param str: assign value of string pointer.
66 * @param len: the length of string.
67 * @return true (ok), false (error)
68 */
StringSetPointerWithLength(HcString * self,const char * str,uint32_t len)69 bool StringSetPointerWithLength(HcString* self, const char *str, uint32_t len)
70 {
71 if (self == NULL || str == NULL) {
72 return false;
73 }
74 uint32_t strLen = strlen(str);
75 if (strLen < len) {
76 return false;
77 }
78 DeleteParcel(&self->parcel);
79 if (len > 0) {
80 if (false == ParcelWrite(&self->parcel, str, len)) {
81 return false;
82 }
83 }
84 return ParcelWriteInt8(&self->parcel, (uint32_t)STRING_END_CHAR);
85 }
86
87 /*
88 * Get the string pointer data
89 * @param self: self pointer.
90 * @return the pointer data of the string
91 */
StringGet(const HcString * self)92 const char *StringGet(const HcString *self)
93 {
94 if (self == NULL) {
95 return NULL;
96 }
97
98 return GetParcelData(&self->parcel);
99 }
100
101 /*
102 * Get the length of the string
103 * @param self: self pointer.
104 * @return the length of the string
105 */
StringLength(const HcString * self)106 uint32_t StringLength(const HcString *self)
107 {
108 if (self == NULL) {
109 return 0;
110 } else {
111 uint32_t length = GetParcelDataSize(&self->parcel);
112 if (length > 0) {
113 return length - STRING_END_CHAR_LENGTH;
114 } else {
115 return 0;
116 }
117 }
118 }
119
120 /*
121 * Find a char from string
122 * @param self: self pointer.
123 * @param c: the char you want find
124 * @param begin: the position find from
125 * @return the position of the char
126 */
StringFind(const HcString * self,char c,uint32_t begin)127 int StringFind(const HcString *self, char c, uint32_t begin)
128 {
129 if (self == NULL) {
130 return -1;
131 }
132
133 // because the return value is int
134 // so the string length cannot bigger than MAX_INT
135 uint32_t strLen = StringLength(self);
136 if (strLen >= MAX_INT) {
137 return -1;
138 }
139
140 const char* curChar = StringGet(self);
141 while (begin < strLen) {
142 if (*(curChar + begin) == c) {
143 return begin;
144 }
145 ++begin;
146 }
147 return -1;
148 }
149
150 /*
151 * Get sub string from a string.
152 * @param self: self pointer.
153 * @param begin: the begin position of the sub string.
154 * @param len: the length of the sub string.
155 * @param dst: the string pointer which saved the sub string content.
156 * @return the operation result.
157 */
StringSubString(const HcString * self,uint32_t begin,uint32_t len,HcString * dst)158 bool StringSubString(const HcString *self, uint32_t begin, uint32_t len, HcString* dst)
159 {
160 if (self == NULL || dst == NULL) {
161 return false;
162 }
163 if (MAX_UINT - len <= begin) {
164 return false;
165 }
166 const char* beingPointer = StringGet(self) + begin;
167 return StringSetPointerWithLength(dst, beingPointer, len);
168 }
169
170 /*
171 * Compare the string with another string.
172 * @param self: self pointer.
173 * @param dst: the pointer of another string.
174 * @return the compare result.
175 * -1: self is smaller than dst
176 * 0: self is equal with dst
177 * 1: self is bigger than dst
178 */
StringCompare(const HcString * self,const char * dst)179 int StringCompare(const HcString *self, const char* dst)
180 {
181 if (self == NULL || dst == NULL) {
182 return 0;
183 }
184
185 const char* src = StringGet(self);
186 if (src == NULL) {
187 return -1;
188 }
189
190 do {
191 if ((*src) > (*dst)) {
192 return 1;
193 } else if ((*src) < (*dst)) {
194 return -1;
195 } else {
196 if ((*src) == '\0') {
197 return 0;
198 }
199 ++src;
200 ++dst;
201 }
202 } while (1);
203 // should never be here
204 return 0;
205 }
206
207 /*
208 * Create a string.
209 * Notice: You should delete_string when you don't need the string anymore.
210 * @return return the created string.
211 */
CreateString(void)212 HcString CreateString(void)
213 {
214 HcString str;
215 str.parcel = CreateParcel(0, STRING_ALLOC_SIZE);
216 ParcelWriteInt8(&str.parcel, STRING_END_CHAR);
217 return str;
218 }
219
220 /*
221 * Delete a string. In fact it will not destroy the string,
222 * but only free the allocate memory of the string and reset the member's value
223 * of the string.
224 * You can continue to use the string if you want.
225 * Notice: You should delete the string when you don't need it any more to avoid memory leak.
226 * @param str: The string you want to delete.
227 */
DeleteString(HcString * str)228 void DeleteString(HcString *str)
229 {
230 if (str != NULL) {
231 DeleteParcel(&str->parcel);
232 }
233 }
234