* Copyright (c) 2025 Huawei Technologies Co., Ltd.
* This program is free software, you can redistribute it and/or modify it under the terms and conditions of
* CANN Open Software License Agreement Version 2.0 (the "License").
* Please refer to the License for details. You may not use this file except in compliance with the License.
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
* INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
* See LICENSE in the root of the software repository for the full text of the License.
*/
* \file string_utils.h
* \brief
*/
#pragma once
#include <cstddef>
#include <cstring>
#include <string>
#include <vector>
#include "securec.h"
#include "tilefwk/error.h"
namespace npu::tile_fwk {
template <typename T>
std::ostream& operator<<(std::ostream& os, const std::vector<T>& vec)
{
os << "[";
for (auto iter = vec.begin(); iter != vec.end(); ++iter) {
if (iter != vec.begin()) {
os << ", ";
}
os << *iter;
}
os << "]";
return os;
}
class StringUtils {
public:
static constexpr size_t MAX_DATA_LEN = 0x40000000UL;
static void Trim(std::string& str)
{
if (str.empty()) {
return;
}
size_t startPos = str.find_first_not_of(" \t");
size_t endPos = str.find_last_not_of(" \t");
if (startPos == std::string::npos || startPos > endPos) {
str.clear();
return;
}
str = str.substr(startPos, endPos - startPos + 1);
}
static std::vector<std::string> Split(const std::string& str, const std::string& pattern)
{
std::vector<std::string> resVec;
if (str.empty() || pattern.empty()) {
return resVec;
}
std::string strAndPattern = str + pattern;
size_t pos = strAndPattern.find(pattern);
while (pos != std::string::npos) {
resVec.push_back(strAndPattern.substr(0, pos));
strAndPattern = strAndPattern.substr(pos + pattern.size());
pos = strAndPattern.find(pattern);
}
return resVec;
}
static bool StartsWith(const std::string& str, const std::string& prefix)
{
if (str.size() < prefix.size())
return false;
for (size_t i = 0; i < prefix.size(); i++) {
if (prefix[i] != str[i]) {
return false;
}
}
return true;
}
static bool EndsWith(const std::string& str, const std::string& suffix)
{
if (str.size() < suffix.size())
return false;
for (size_t i = 0; i < suffix.size(); i++) {
if (suffix[suffix.size() - 1 - i] != str[str.size() - 1 - i]) {
return false;
}
}
return true;
}
static std::string BaseName(const char* fname)
{
if (auto start = strrchr(fname, '/')) {
return start + 1;
}
return fname;
}
static std::string ToLower(const std::string& str)
{
std::string res(str);
for (auto& c : res) {
c = std::tolower(c);
}
return res;
}
static std::string ToUpper(const std::string& str)
{
std::string res(str);
for (auto& c : res) {
c = std::toupper(c);
}
return res;
}
static void DataCopy(void* dest, size_t destMax, const void* src, size_t count)
{
ASSERT(destMax >= count) << "destMax: " << destMax << ", count: " << count;
size_t offset = 0;
while (offset < count) {
size_t copyLen = std::min(count - offset, MAX_DATA_LEN);
auto err =
memcpy_s(static_cast<char*>(dest) + offset, copyLen, static_cast<const char*>(src) + offset, copyLen);
ASSERT(err == 0) << "errCode: " << err;
offset += copyLen;
}
}
static void DataSet(void* dest, size_t destMax, int c, size_t count)
{
ASSERT(destMax >= count) << "destMax: " << destMax << ", count: " << count;
size_t offset = 0;
while (offset < count) {
size_t copyLen = std::min(count - offset, MAX_DATA_LEN);
auto err = memset_s(static_cast<char*>(dest) + offset, copyLen, c, copyLen);
ASSERT(err == 0) << "errCode: " << err;
offset += copyLen;
}
}
template <typename T>
static std::string ToString(const std::vector<T>& args)
{
std::stringstream ss;
ss << args;
return ss.str();
}
static void AppendUniqueToken(std::string& acc, const std::string& tok, char sep = ';')
{
if (tok.empty()) {
return;
}
size_t pos = 0;
while (pos <= acc.size()) {
size_t s = acc.find(sep, pos);
size_t end = (s == std::string::npos) ? acc.size() : s;
if (acc.compare(pos, end - pos, tok) == 0) {
return;
}
if (s == std::string::npos) {
break;
}
pos = s + 1;
}
if (!acc.empty()) {
acc.push_back(sep);
}
acc.append(tok);
}
};
}