1/* 2 * Copyright (c) 2024 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 UTIL_STRING_UTIL_H 17#define UTIL_STRING_UTIL_H 18 19#include <algorithm> 20#include <cctype> 21#include <cstdint> 22#include <iterator> 23 24#include <base/containers/string_view.h> 25#include <base/containers/vector.h> 26#include <render/namespace.h> 27 28#include "util/log.h" 29 30RENDER_BEGIN_NAMESPACE() 31namespace StringUtil { 32template<class T, size_t N> 33constexpr size_t MaxStringLengthFromArray(T (&)[N]) 34{ 35 return N - 1u; 36} 37 38inline void CopyStringToArray(const BASE_NS::string_view source, char* target, size_t maxLength) 39{ 40 if (source.size() > maxLength) { 41 PLUGIN_LOG_W("CopyStringToArray: string (%zu) longer than %zu", source.size(), maxLength); 42 } 43 size_t const length = source.copy(target, maxLength); 44 target[length] = '\0'; 45} 46 47inline bool NotSpace(unsigned char ch) 48{ 49 return !std::isspace(static_cast<int>(ch)); 50} 51 52// trim from start (in place) 53inline void LTrim(BASE_NS::string_view& string) 54{ 55 auto const count = size_t(std::find_if(string.begin(), string.end(), NotSpace) - string.begin()); 56 string.remove_prefix(count); 57} 58 59// trim from end (in place) 60inline void RTrim(BASE_NS::string_view& string) 61{ 62 auto const count = 63 size_t(std::distance(std::find_if(string.rbegin(), string.rend(), NotSpace).base(), string.end())); 64 string.remove_suffix(count); 65} 66 67// trim from both ends (in place) 68inline size_t Trim(BASE_NS::string_view& string) 69{ 70 RTrim(string); 71 LTrim(string); 72 return string.length(); 73} 74 75inline BASE_NS::vector<BASE_NS::string_view> Split( 76 const BASE_NS::string_view string, const BASE_NS::string_view delims = "|") 77{ 78 BASE_NS::vector<BASE_NS::string_view> output; 79 auto left = string; 80 81 while (!left.empty()) { 82 auto const pos = left.find_first_of(delims); 83 84 auto found = left.substr(0, pos); 85 if (Trim(found) > 0) { 86 output.push_back(found); 87 } 88 if (pos != BASE_NS::string_view::npos) { 89 left.remove_prefix(pos + 1); 90 } else { 91 break; 92 } 93 } 94 95 return output; 96} 97 98// find and replace first instance of "find" with "replace" in "source" 99inline bool FindAndReplaceOne( 100 BASE_NS::string& source, const BASE_NS::string_view find, const BASE_NS::string_view replace) 101{ 102 const auto p = source.find(find); 103 if (p != BASE_NS::string::npos) { 104 source.replace(source.begin() + static_cast<BASE_NS::string::difference_type>(p), 105 source.begin() + static_cast<BASE_NS::string::difference_type>(p + find.length()), replace); 106 } 107 return (p != BASE_NS::string::npos); 108} 109// find and replace all instances of "find" with "replace" in "source" 110inline void FindAndReplaceAll( 111 BASE_NS::string& source, const BASE_NS::string_view find, const BASE_NS::string_view replace) 112{ 113 while (FindAndReplaceOne(source, find, replace)) 114 ; 115} 116} // namespace StringUtil 117RENDER_END_NAMESPACE() 118 119#endif // UTIL_STRING_UTIL_H 120