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 19const uint32_t STRING_ALLOC_SIZE = 10; 20const uint32_t STRING_END_CHAR_LENGTH = 1; 21const 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*/ 32bool 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*/ 51bool 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*/ 69bool 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*/ 92const 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*/ 106uint32_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*/ 127int StringFind(const HcString *self, char c, uint32_t begin) 128{ 129 if (self == NULL) { 130 return -1; 131 } 132 uint32_t p = begin; 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 (p < strLen) { 142 if (*(curChar + p) == c) { 143 return p; 144 } 145 ++p; 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*/ 158bool 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*/ 179int 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*/ 212HcString 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*/ 228void DeleteString(HcString *str) 229{ 230 if (str != NULL) { 231 DeleteParcel(&str->parcel); 232 } 233} 234