Ai
9 Star 32 Fork 21

10km/common_source_cpp

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
common_utilits.h 9.71 KB
一键复制 编辑 原始数据 按行查看 历史
10km 提交于 2024-07-14 20:55 +08:00 . 增加 bit_set,bit_clear,bit_check函数
/*
* common_utilits.h
*
* Created on: 2016年1月7日
* Author: guyadong
*/
#ifndef COMMON_SOURCE_CPP_COMMON_UTILITS_H_
#define COMMON_SOURCE_CPP_COMMON_UTILITS_H_
#include <cstring>
#include <string>
#include <memory>
#include <list>
#include <vector>
#include <algorithm>
#include <type_traits>
#include <stdexcept>
#include <assert.h>
#include <string_utils.h>
namespace gdface {
inline namespace com_utilits{
inline char hex_to_byte(char c){
if(c>='0' && c<='9')return c-'0';
else if(c>='a' && c<='f')return c-'a'+10;
else if(c>='A' && c<='F')return c-'A'+10;
else
throw std::invalid_argument("invalid hex char[0-9a-fA-F]");
}
inline void hex_to_bytes(const char* hex_str, void *out, size_t size) {
static const std::string err_invalid_hex_str="the argument hex_str is not a valid hex string";
if (nullptr==hex_str||nullptr == out)
throw std::invalid_argument("the argument 'hex_str' and 'bytes' must not be null");
auto len=strlen(hex_str);
if (0==len||(len&1))
throw std::invalid_argument(err_invalid_hex_str);
auto limit = std::min(len >> 1, size) << 1;
try{
auto bytes=reinterpret_cast<uint8_t*>(out);
for (auto i = 0; i < limit; i += 2) {
bytes[i >> 1] = (hex_to_byte(hex_str[i]) << 4) + hex_to_byte(hex_str[i + 1]);
}
}catch(std::invalid_argument &e){
throw std::invalid_argument(std::string(err_invalid_hex_str).append(" because:").append(e.what()));
}
}
inline std::vector<uint8_t> hex_to_bytes(const char* hex_str) {
std::vector<uint8_t> v(strlen(hex_str) >> 1);
hex_to_bytes(hex_str, v.data(), v.size());
return std::move(v);
}
inline std::vector<uint8_t> hex_to_bytes(const std::string &hex_str) {
return hex_to_bytes(hex_str.data());
}
inline void bytes_to_hex(const void *in, size_t size, char* hex_str, size_t limit) {
const static char hex_char[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
if (nullptr == in || nullptr == hex_str)
throw std::invalid_argument("the argument 'bytes' and 'hex_str' must not be null");
if (limit < size << 1)
throw std::invalid_argument("the capacity of out buffer 'hex_str' can't fit size of input ");
auto bytes=reinterpret_cast<const uint8_t*>(in);
for (decltype(size) i = 0; i < size; ++i) {
hex_str[i << 1] = hex_char[bytes[i] >> 4]; // 高四位
hex_str[(i << 1) + 1] = hex_char[bytes[i] & 0x0f]; // 低四位
}
}
inline std::vector<char> bytes_to_hex(const void *bytes, size_t size) {
std::vector<char> v((size << 1) + 1);
bytes_to_hex(bytes, size, v.data(), v.size());
v[size << 1] = 0;
return std::move(v);
}
inline std::vector<char> bytes_to_hex(const std::vector<uint8_t> &v) {
return bytes_to_hex(v.data(), v.size());
}
inline std::string bytes_to_hex_string(const void *bytes, size_t size) {
return std::string(bytes_to_hex(bytes, size).data());
}
inline std::string bytes_to_hex_string(const std::vector<uint8_t> &v) {
return bytes_to_hex_string(v.data(), v.size());
}
inline void bit_set(void *in, size_t size, int index)
{
if (nullptr == in)
throw std::invalid_argument("the argument 'in' must not be null");
auto byteIndex = size - 1 - (index >> 3);
if (byteIndex < 0 || byteIndex >= size)
throw std::invalid_argument("the bit index is out of range");
auto bytes = reinterpret_cast<uint8_t *>(in);
bytes[byteIndex] |= (1 << (index & 0x07));
}
inline void bit_clear(void *in, size_t size, int index)
{
if (nullptr == in)
throw std::invalid_argument("the argument 'in' must not be null");
auto byteIndex = size - 1 - (index >> 3);
if (byteIndex < 0 || byteIndex >= size)
throw std::invalid_argument("the bit index is out of range");
auto bytes = reinterpret_cast<uint8_t *>(in);
bytes[byteIndex] &= ~(1 << (index & 0x07));
}
inline bool bit_check(const void *in, size_t size, int index)
{
if (nullptr == in)
throw std::invalid_argument("the argument 'in' must not be null");
auto byteIndex = size - 1 - (index >> 3);
if (byteIndex < 0 || byteIndex >= size)
throw std::invalid_argument("the bit index is out of range");
auto bytes = reinterpret_cast<const uint8_t *>(in);
return (bytes[byteIndex] & (1 << (index & 0x07))) != 0;
}
inline void bit_set(void *in, size_t size, int index, bool isSet)
{
if(isSet){
bit_set(in, size, index);
}else{
bit_set(in, size, index);
}
}
inline void bit_set(std::vector<uint8_t> &in, int index)
{
bit_set(in.data(), in.size(), index);
}
inline void bit_clear(std::vector<uint8_t> &in, int index){
bit_clear(in.data(), in.size(), index);
}
inline void bit_set(std::vector<uint8_t> &in, int index, bool isSet){
bit_set(in.data(), in.size(), index, isSet);
}
inline bool bit_check(const std::vector<uint8_t> &in, int index){
return bit_check(in.data(), in.size(), index);
}
//************************************
// 将4字节的IP地址转为.分割十进制的标准IP地址字符串(如'192.168.0.1'),如果输入的字符串非4字节长度返回'0.0.0.0'
// @param const std::string & byte4
// @return std::string
//************************************
inline std::string format_ip(const std::string& byte4)
{
if (byte4.size() != 4)
{
return "0.0.0.0";
}
std::stringstream ss;
int c = 0;
for_each(byte4.begin(), byte4.end(), [&](char ch) {
if (c++) {
ss << ".";
}
ss << ((uint32_t)ch & 0xff);
});
return std::move(ss.str());
}
//************************************
// 将输入的.分割十进制的标准IP地址字符串(如'192.168.0.1')转为4字节数组,如果输入格式不为.分隔的4节字符,返回空字符串
// @param const std::string & ipstr
// @return std::string
//************************************
inline std::string parse_ip(const std::string& ipstr)
{
if (std::regex_match(ipstr, std::regex("^((?:(?:25[0-5]|2[0-4]\\d|[01]?\\d?\\d)\\.){3}(?:25[0-5]|2[0-4]\\d|[01]?\\d?\\d))$")))
{
uint8_t num[] = { 0,0,0,0 };
auto four = split(ipstr, "\\.");
if (4 == four.size()) {
int c = 0;
std::for_each(four.begin(), four.end(), [&](const std::string&e) {
num[c++] = (uint8_t)atoi(e.c_str());
});
}
return std::string((char*)num, sizeof(num));
}
return "";
}
//************************************
// 将6字节的MAC地址转为:分割十六进制的标准MAC地址字符串(如'd0:17:c2:d0:3f:bf'),如果输入格式不正确返回'00.00.00.00.00.00'
// @param const std::string & byte6
// @param const std::string & delim 分割符,默认:
// @return std::string
//************************************
inline std::string format_mac(const std::string& byte6, const std::string &delim = ":")
{
if (byte6.size() != 6)
{
return "00.00.00.00.00.00";
}
std::stringstream ss;
int c = 0;
std::for_each(byte6.begin(), byte6.end(), [&](char ch) {
if (c++) {
ss << delim;
}
ss << std::hex << ((uint32_t)ch & 0xff);
});
return ss.str();
}
//************************************
// 将输入的:或-分割(或无分割符)十六进制的标准MAC地址字符串(如'D0:17:C2:D0:3F:BF')转为6字节数组,如果输入格式不正确,返回空字符串
// @param const std::string & input
// @return std::string
//************************************
inline std::string parse_mac(const std::string& input)
{
if (std::regex_match(input, std::regex("^([a-fA-F0-9]{2}[:-]?){5}[a-fA-F0-9]{2}$")))
{
auto cleaned = std::regex_replace(input, std::regex("[-:]"), "");
auto byte6 = hex_to_bytes(cleaned);
return std::string((char*)byte6.data(), byte6.size());
}
return "";
}
//************************************
// 将输入的字符串转为int,如果输入格式不正确,返回nullptr
// @param const std::string & input
// @return std::shared_ptr<int>
//************************************
inline std::shared_ptr<int> parse_int(const std::string& input)
{
if (std::regex_match(input, std::regex("^[-+]?\\d{1,10}$")))
{
return std::make_shared<int>(std::atoi(input.c_str()));
}
return nullptr;
}
//************************************
// 将输入的字符串转为float,如果输入格式不正确,返回nullptr
// @param const std::string & input
// @return std::shared_ptr<float>
//************************************
inline std::shared_ptr<double> parse_float(const std::string& input)
{
if (std::regex_match(input, std::regex("^[-+]?(\\d*\\.\\d+|\\d+)$")))
{
return std::make_shared<double>(std::atof(input.c_str()));
}
return nullptr;
}
//************************************
// 将输入的字符串转为bool,如果输入格式不正确,返回nullptr
// @param const std::string & input
// @return std::shared_ptr<float>
//************************************
inline std::shared_ptr<bool> parse_bool(const std::string& input)
{
if (std::regex_match(input, std::regex("^(true|false|1|0|on|off|yes|no)$", std::regex::icase)))
{
auto b = std::regex_match(input, std::regex("^(true|1|on|yes)$", std::regex::icase));
return std::make_shared<bool>(b);
}
return nullptr;
}
//************************************
// 将输入的字符串转为int,如果输入格式不正确,返回nullptr
// @param const std::string & input
// @return std::shared_ptr<std::list<int>> 解析的数字列表
//************************************
inline std::shared_ptr<std::list<int>> parse_int_list(const std::string& input)
{
if (std::regex_match(input, std::regex("^[\\s,;:]*(([-+]?\\d+)[\\s,;:]+([-+]?\\d+)?)+$")))
{
std::list<int> parsed;
std::vector<std::string> nums;
const std::regex ws_re("[-+]?\\d{1,10}"); // whitespace
std::copy(std::sregex_token_iterator(input.begin(), input.end(), ws_re, 0),
std::sregex_token_iterator(),
std::inserter(nums, nums.begin()));
std::transform(nums.begin(), nums.end(), std::inserter(parsed, parsed.begin()), [](const std::string &n) {
auto p = parse_int(n);
assert(p);
return *p;
});
if (!parsed.empty()) {
return std::make_shared<std::list<int>>(parsed);
}
}
return nullptr;
}
} /* namespace com_utilits */
} /* namespace gdface */
#endif /* COMMON_SOURCE_CPP_COMMON_UTILITS_H_ */
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
C++
1
https://gitee.com/l0km/common_source_cpp.git
git@gitee.com:l0km/common_source_cpp.git
l0km
common_source_cpp
common_source_cpp
master

搜索帮助