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 "hc_string.h"
18 #include "hc_types.h"
19 
20 const uint32_t STRING_ALLOC_SIZE = 10;
21 const uint32_t STRING_END_CHAR_LENGTH = 1;
22 const char STRING_END_CHAR = '\0';
23 
24 /*
25  * Append a HcString
26  * Notice: It will add '\0' automatically.
27  * @param self: self pointer.
28  * @param str: append string.
29  * @return HC_TRUE (ok), HC_FALSE (error)
30  */
StringAppend(HcString * self,HcString str)31 HcBool StringAppend(HcString *self, HcString str)
32 {
33     uint32_t length = GetParcelDataSize(&str.parcel);
34     if (self != NULL && length > 0) {
35         // remove '\0'
36         ParcelPopBack(&self->parcel, STRING_END_CHAR_LENGTH);
37         // append string(include '\0')
38         return StringAppendPointer(self, GetParcelData(&str.parcel));
39     }
40 
41     return HC_FALSE;
42 }
43 
44 /*
45  * Append string pointer
46  * Notice: It will add '\0' automatically.
47  * @param self: self pointer.
48  * @param str: string pointer.
49  * @return HC_TRUE (ok), HC_FALSE (error)
50  */
StringAppendPointer(HcString * self,const char * str)51 HcBool StringAppendPointer(HcString *self, const char *str)
52 {
53     if (self != NULL && str != NULL) {
54         // remove '\0'
55         ParcelPopBack(&self->parcel, STRING_END_CHAR_LENGTH);
56         // append string (include '\0')
57         return ParcelWrite(&self->parcel, (void *)str, HcStrlen(str) + 1);
58     }
59 
60     return HC_FALSE;
61 }
62 
63 /*
64  * Append a char
65  * Notice: It will add '\0' automatically.
66  * @param self: self pointer.
67  * @param str: char.
68  * @return HC_TRUE (ok), HC_FALSE (error)
69  */
StringAppendChar(HcString * self,char c)70 HcBool StringAppendChar(HcString *self, char c)
71 {
72     if (self != NULL && c != STRING_END_CHAR) {
73         // remove '\0'
74         ParcelPopBack(&self->parcel, STRING_END_CHAR_LENGTH);
75 
76         if (ParcelWriteInt8(&self->parcel, c)) {
77             return ParcelWriteInt8(&self->parcel, (uint32_t)STRING_END_CHAR);
78         }
79     }
80 
81     return HC_FALSE;
82 }
83 
84 /*
85  * Assign a value to the HcString
86  * Notice: It will add '\0' automatically.
87  * @param self: self pointer.
88  * @param str: assign value of ta_sting.
89  * @return HC_TRUE (ok), HC_FALSE (error)
90  */
StringSet(HcString * self,HcString str)91 HcBool StringSet(HcString *self, HcString str)
92 {
93     if (self != NULL) {
94         DeleteParcel(&self->parcel);
95         return StringAppend(self, str);
96     }
97 
98     return HC_FALSE;
99 }
100 
101 /*
102  * Assign a value to the HcString
103  * Notice: It will add '\0' automatically.
104  * @param self: self pointer.
105  * @param str: assign value of string pointer.
106  * @return HC_TRUE (ok), HC_FALSE (error)
107  */
StringSetPointer(HcString * self,const char * str)108 HcBool StringSetPointer(HcString *self, const char *str)
109 {
110     if (self != NULL) {
111         DeleteParcel(&self->parcel);
112         return StringAppendPointer(self, str);
113     }
114 
115     return HC_FALSE;
116 }
117 
118 /*
119  * Get the string pointer data
120  * @param self: self pointer.
121  * @return the pointer data of the string
122  */
StringGet(const HcString * self)123 const char *StringGet(const HcString *self)
124 {
125     if (self == NULL) {
126         return NULL;
127     }
128 
129     return GetParcelData(&self->parcel);
130 }
131 
132 /*
133  * Get the length of the string
134  * @param self: self pointer.
135  * @return the length of the string
136  */
StringLength(const HcString * self)137 uint32_t StringLength(const HcString *self)
138 {
139     if (self == NULL) {
140         return 0;
141     } else {
142         uint32_t length = GetParcelDataSize(&self->parcel);
143         if (length > 0) {
144             return length - STRING_END_CHAR_LENGTH;
145         } else {
146             return 0;
147         }
148     }
149 }
150 
151 /*
152  * Create a string.
153  * Notice: You should delete_string when you don't need the string anymore.
154  * @return return the created string.
155  */
CreateString(void)156 HcString CreateString(void)
157 {
158     HcString str;
159     str.parcel = CreateParcel(0, STRING_ALLOC_SIZE);
160     ParcelWriteInt8(&str.parcel, STRING_END_CHAR);
161     return str;
162 }
163 
164 /*
165  * Delete a string. In fact it will not destroy the string,
166  * but only free the allocate memory of the string and reset the member's value
167  * of the string.
168  * You can continue to use the string if you want.
169  * Notice: You should delete the string when you don't need it any more to avoid memory leak.
170  * @param str: The string you want to delete.
171  */
DeleteString(HcString * str)172 void DeleteString(HcString *str)
173 {
174     if (str != NULL) {
175         DeleteParcel(&str->parcel);
176     }
177 }
178