cipher/base/stringutils.cpp

338 lines
10 KiB
C++

/*
** Copyright (C) 2014 Wang Yaofu
** All rights reserved.
**
**Author:Wang Yaofu voipman@qq.com
**Description: The source file of class CStringUitls.
*/
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <cstdarg>
#include <iomanip>
#include "stringutils.h"
namespace common {
const char kWhitespaceASCII[] =
{
0x09, // <control-0009> to <control-000D>
0x0A,
0x0B,
0x0C,
0x0D,
0x20, // Space
0
};
template<typename STR>
void TrimStringT(const STR& input,
const typename STR::value_type trim_chars[],
TrimOption option,
STR* output) {
// Find the edges of leading/trailing whitespace as desired.
const typename STR::size_type last_char = input.length() - 1;
const typename STR::size_type first_good_char = (option & kTrimLeading) ?
input.find_first_not_of(trim_chars) : 0;
const typename STR::size_type last_good_char = (option & kTrimTrailing) ?
input.find_last_not_of(trim_chars) : last_char;
// When the string was all whitespace, report that we stripped off
// whitespace from whichever position the caller was interested in.
// For empty input, we stripped no whitespace, but we still need to
// clear |output|.
if (input.empty() ||
(first_good_char == STR::npos) || (last_good_char == STR::npos)) {
output->clear();
return;
}
// Trim the whitespace.
*output =
input.substr(first_good_char, last_good_char - first_good_char + 1);
}
void StrUtils::TrimWhitespace(const std::string& input,
TrimOption option,
std::string* output) {
TrimStringT(input, kWhitespaceASCII, option, output);
}
void StrUtils::ReplaceString(const std::string& input,
const std::string& old_val,
const std::string& new_val,
std::string* output) {
if (old_val.empty()) {
return;
}
std::ostringstream ss;
std::string::size_type pos = 0;
std::string::size_type pos_prev = 0;
while (pos != std::string::npos) {
pos_prev = pos;
if ((pos = input.find(old_val, pos)) != std::string::npos) {
if (pos > pos_prev) {
ss << input.substr(pos_prev, pos - pos_prev);
}
ss << new_val;
pos += old_val.length();
} else {
if (pos_prev + 1 <= input.length()) {
ss << input.substr(pos_prev);
}
break;
}
}
*output = ss.str();
}
std::string StrUtils::ToLowerCase(const std::string& input) {
if (input.empty()) {
return std::string();
}
std::string output(input);
std::string::pointer begin = &output[0];
std::string::pointer end = begin + output.size();
for (; begin < end; ++begin) {
*begin = tolower(*begin);
}
return output;
}
std::string StrUtils::ToUpperCase(const std::string& input) {
if (input.empty()) {
return std::string();
}
std::string output(input);
std::string::pointer begin = &output[0];
std::string::pointer end = begin + output.size();
for (; begin < end; ++begin) {
*begin = toupper(*begin);
}
return output;
}
template <typename STR>
void SplitStringT(const STR& str,
const STR& s,
std::vector<STR>* r) {
r->clear();
typename STR::size_type begin_index = 0;
while (true) {
const typename STR::size_type end_index = str.find(s, begin_index);
if (end_index == STR::npos) {
const STR term = str.substr(begin_index);
r->push_back(term);
return;
}
const STR term = str.substr(begin_index, end_index - begin_index);
r->push_back(term);
begin_index = end_index + s.size();
}
}
void StrUtils::SplitString(const std::string& str,
const std::string& s,
std::vector<std::string>* r) {
SplitStringT(str, s, r);
}
bool StrUtils::Split(const std::string& s,
char sep,
std::string& first,
std::string& second) {
std::string::size_type sep_pos = s.find(sep);
first = s.substr(0, sep_pos);
if (sep_pos!=std::string::npos)
second = s.substr(sep_pos+1);
return true;
}
int StrUtils::stoi(const std::string &str) {
return ::atoi(str.c_str());
}
long StrUtils::stol(const std::string &str, const int base) {
char *ep;
return ::strtol(str.c_str(), &ep, base);
}
long long StrUtils::stoll(const std::string &str, const int base) {
char *ep;
return ::strtoll(str.c_str(), &ep, base);
}
unsigned long StrUtils::stoul(const std::string &str, const int base) {
char *ep;
return ::strtoul(str.c_str(), &ep, base);
}
unsigned long long StrUtils::stoull(const std::string &str, const int base) {
char *ep;
return ::strtoull(str.c_str(), &ep, base);
}
float StrUtils::stof(const std::string& str) {
char *ep;
return ::strtof(str.data(), &ep);
}
double StrUtils::stod(const std::string& str) {
char *ep;
return ::strtold(str.data(), &ep);
}
long double StrUtils::stold(const std::string& str) {
char *ep;
return ::strtod(str.data(), &ep);
}
std::string StrUtils::JoinStr(std::vector<std::string>& parts,
const std::string& delimiter) {
if (parts.empty()) {
return "";
}
std::stringstream ss;
for (size_t i = 0; i < parts.size() - 1; ++i) {
ss << parts[i];
ss << delimiter;
}
ss << parts[parts.size() - 1]; //no delimiter at last
return ss.str();
}
std::string StrUtils::JoinStr(std::vector<std::string>& parts, char delimiter) {
std::string tmp;
tmp.assign(1, delimiter);
return JoinStr(parts, tmp);
}
std::string StrUtils::Hex(const char* cpSrcStr, int len, bool isUpper) {
if (cpSrcStr == NULL) {
return "";
}
std::string ret(len * 2, 0x00);
const char* hex = isUpper ? "0123456789ABCDEF" : "0123456789abcdef";
for (size_t i = 0; i < len; ++i) {
unsigned char v = static_cast<unsigned char>(cpSrcStr[i]);
ret[2*i] = hex[(v >> 4) & 0x0f];
ret[2*i+1] = hex[ v & 0x0f];
}
return ret;
}
std::string StrUtils::Hex(const std::string& srcStr, bool isUpper) {
return Hex(srcStr.c_str(), srcStr.size(), isUpper);
}
std::string StrUtils::Hex(const char ch, bool isUpper) {
return Hex(&ch, 1, isUpper);
}
namespace {
char asc_bcd(const char *what) {
unsigned char digit;
unsigned char m;
digit = (what[0] >= 'a' ? ((what[0]) - 'a') + 10 : (what[0] - '0'));
digit *= 16;
digit += (what[1] >= 'a' ? ((what[1]) - 'a') + 10 : (what[1] - '0'));
return(digit);
}
}
std::string StrUtils::fromHex(const char* from, size_t len) {
std::string ret(len / 2, 0x00);
for (size_t ii = 0; ii < len / 2; ii++)
ret[ii] = asc_bcd(from + ii * 2);
return ret;
}
std::string StrUtils::fromHex(const std::string& from) {
return fromHex(from.c_str(), from.length());
}
int StrUtils::fromHex(const char* from, char* to) {
int len = strlen(from)/2;
for (size_t ii = 0; ii < len; ii++)
to[ii] = asc_bcd(from + ii * 2);
return len;
}
int StrUtils::HexStr2Int(const char* aStr, int len) {
int i, res = 0;
for(i = 0; i < len; i++) {
res *= 16;
if ((aStr[i] >= '0') && (aStr[i] <= '9')) {
res += aStr[i] - '0';
} else if ((aStr[i] >= 'a') && (aStr[i] <= 'f')) {
res += aStr[i] - 'a' + 10;
} else if ((aStr[i] >= 'A') && (aStr[i] <= 'F')) {
res += aStr[i] - 'A' + 10;
} else {
return 0;
}
}
return res;
}
int StrUtils::HexStr2Int(const std::string& srcStr) {
return HexStr2Int(srcStr.c_str(), srcStr.length());
}
int StrUtils::Int2HexInt(int src) {
std::string hexStr;
Format(hexStr, "%d", src);
return HexStr2Int(hexStr.c_str(), hexStr.length());
}
bool StrUtils::IsNumber(char ch) {
return (ch >= '0' && ch <= '9');
}
bool StrUtils::IsLetter(char ch) {
return ((ch >= 'a' && ch <= 'z') || ((ch >= 'A') && (ch <= 'Z')));
}
bool StrUtils::IsUnderLine(char ch) {
return (ch == '_');
}
bool StrUtils::Format(std::string &outStr, const char *format, ...) {
char* mem;
va_list ap;
va_start(ap, format);
if (vasprintf(&mem, format, ap) < 0) {
va_end(ap);
return false;
}
outStr = mem;
va_end(ap);
free(mem);
return true;
}
unsigned int StrUtils::ELFhash(const char* aStr, unsigned int aHashMod) {
unsigned int h = 0;
while (*aStr) {
h = (h << 4) + *aStr++;
unsigned int g = h & 0xF0000000;
if (g) h ^= g >> 24;
h &= ~g;
}
return h % aHashMod;
}
unsigned int StrUtils::HfIp(const char* aStr, unsigned int aHashMod) {
unsigned int n = 0;
unsigned char* b = (unsigned char*)&n;
for (unsigned int i = 0; aStr[i] != 0x00; i++)
b[i%4] ^= aStr[i];
return n % aHashMod;
}
unsigned int StrUtils::hf(const char* aStr, unsigned int aHashMod) {
int result = 0;
const char* ptr = aStr;
int c;
for (int i = 1; (c = *ptr++); i++)
result += c * 3 * i;
if (result < 0) result = -result;
return result % aHashMod;
}
}// namespace common