/** * Copyright (c) 2021-2022 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef LIBPANDABASE_UTILS_STRING_HELPERS_H #define LIBPANDABASE_UTILS_STRING_HELPERS_H #include #include #include #include #include #include #include #include #include namespace panda::helpers::string { inline std::string Vformat(const char *fmt, va_list args) { static constexpr size_t SIZE = 1024; std::string result; result.resize(SIZE); bool is_truncated = true; while (is_truncated) { va_list copy_args; va_copy(copy_args, args); int r = vsnprintf_truncated_s(result.data(), result.size() + 1, fmt, copy_args); va_end(copy_args); if (r < 0) { return ""; } is_truncated = static_cast(r) == result.size(); result.resize(result.size() * 2U); } result.erase(std::find(result.begin(), result.end(), '\0'), result.end()); return result; } // NOLINTNEXTLINE(cert-dcl50-cpp) inline std::string Format(const char *fmt, ...) { va_list args; va_start(args, fmt); // NOLINT(cppcoreguidelines-pro-type-vararg) std::string result = Vformat(fmt, args); va_end(args); return result; } template bool ParseInt(const char *str, T *num, T min = std::numeric_limits::min(), T max = std::numeric_limits::max()) { static_assert(std::is_signed::value, "it can't parse unsigned types"); while (isspace(*str)) { // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) str++; } constexpr size_t BASE16 = 16; constexpr size_t BASE10 = 10; // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) int base = (str[0] == '0' && (str[1] == 'x' || str[1] == 'X')) ? BASE16 : BASE10; errno = 0; char *end = nullptr; // NOLINTNEXTLINE(google-runtime-int) long long int result = strtoll(str, &end, base); if (str == end || *end != '\0') { errno = EINVAL; return false; } if (result < min || max < result) { errno = ERANGE; return false; } if (num != nullptr) { *num = static_cast(result); } return true; } template bool ParseInt(const std::string &str, T *num, T min = std::numeric_limits::min(), T max = std::numeric_limits::max()) { return ParseInt(str.c_str(), num, min, max); } } // namespace panda::helpers::string #endif // LIBPANDABASE_UTILS_STRING_HELPERS_H