add utilities
This commit is contained in:
parent
fbca5468f1
commit
baeed0acea
|
@ -0,0 +1,106 @@
|
||||||
|
#include "cmd.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
namespace parser
|
||||||
|
{
|
||||||
|
static void command_line_to_arguments(const char* cmdl, std::vector<std::string>& args)
|
||||||
|
{
|
||||||
|
while(*cmdl)
|
||||||
|
{
|
||||||
|
const char* h = cmdl;
|
||||||
|
while(*h == ' ' || *h == '\t')
|
||||||
|
h++;
|
||||||
|
if(*h == 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
cmdl = h;
|
||||||
|
if(*h == '\"')
|
||||||
|
{
|
||||||
|
cmdl++;
|
||||||
|
h++;
|
||||||
|
while(*h)
|
||||||
|
{
|
||||||
|
if(*h == '\"')
|
||||||
|
break;
|
||||||
|
if(*h == '\\')
|
||||||
|
h++;
|
||||||
|
h++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
while(*h)
|
||||||
|
{
|
||||||
|
if(*h == ' ' || *h == '\t')
|
||||||
|
break;
|
||||||
|
h++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(h > cmdl)
|
||||||
|
args.push_back(std::string(cmdl, h - cmdl));
|
||||||
|
else if(*h == '\"')
|
||||||
|
args.push_back("");
|
||||||
|
|
||||||
|
if(*h == 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
cmdl = h + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
cmd_line::cmd_line()
|
||||||
|
{}
|
||||||
|
cmd_line::~cmd_line()
|
||||||
|
{}
|
||||||
|
|
||||||
|
cmd_line* cmd_line::from_console(const char* tips)
|
||||||
|
{
|
||||||
|
std::string in("");
|
||||||
|
char ch = 0;
|
||||||
|
|
||||||
|
if(!tips || *tips == 0)
|
||||||
|
tips = "input";
|
||||||
|
|
||||||
|
printf("%s%s>%s", CONSOLE_COLOR_FRONT_BLUE, tips, CONSOLE_COLOR_NONE);
|
||||||
|
while((ch = getchar()) != '\n')
|
||||||
|
in.append(1, ch);
|
||||||
|
|
||||||
|
return cmd_line::from_command_line(in.c_str());
|
||||||
|
}
|
||||||
|
cmd_line* cmd_line::from_command_line(const char* cmdl)
|
||||||
|
{
|
||||||
|
cmd_line* cmd = new cmd_line();
|
||||||
|
|
||||||
|
cmd->cmd_line_ = cmdl;
|
||||||
|
parser::command_line_to_arguments(cmdl, cmd->arguments_);
|
||||||
|
|
||||||
|
return cmd;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t cmd_line::count(void)
|
||||||
|
{
|
||||||
|
return arguments_.size();
|
||||||
|
}
|
||||||
|
const char* cmd_line::parameter(int ind)
|
||||||
|
{
|
||||||
|
if(ind >= 0 && ind < arguments_.size())
|
||||||
|
return arguments_[ind].c_str();
|
||||||
|
else
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
const char* cmd_line::parameter(const char* key)
|
||||||
|
{
|
||||||
|
for(int i = 0; i < arguments_.size() - 1; ++i)
|
||||||
|
{
|
||||||
|
if(arguments_[i] == key)
|
||||||
|
return arguments_[i + 1].c_str();
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
|
@ -0,0 +1,92 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
// command line utility
|
||||||
|
//
|
||||||
|
// created on 2023-02-10
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "referer.h"
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#define CONSOLE_COLOR_NONE "\033[0m"
|
||||||
|
#define CONSOLE_COLOR_FRONT_BLACK "\033[0;30m"
|
||||||
|
#define CONSOLE_COLOR_FRONT_DARK_GRAY "\033[1;30m"
|
||||||
|
#define CONSOLE_COLOR_FRONT_RED "\033[0;31m"
|
||||||
|
#define CONSOLE_COLOR_FRONT_LIGHT_RED "\033[1;31m"
|
||||||
|
#define CONSOLE_COLOR_FRONT_GREEN "\033[0;32m"
|
||||||
|
#define CONSOLE_COLOR_FRONT_LIGHT_GREEN "\033[1;32m"
|
||||||
|
#define CONSOLE_COLOR_FRONT_BROWN "\033[0;33m"
|
||||||
|
#define CONSOLE_COLOR_FRONT_YELLOW "\033[1;33m"
|
||||||
|
#define CONSOLE_COLOR_FRONT_BLUE "\033[0;34m"
|
||||||
|
#define CONSOLE_COLOR_FRONT_LIGHT_BLUE "\033[1;34m"
|
||||||
|
#define CONSOLE_COLOR_FRONT_PURPLE "\033[0;35m"
|
||||||
|
#define CONSOLE_COLOR_FRONT_LIGHT_PURPLE "\033[1;35m"
|
||||||
|
#define CONSOLE_COLOR_FRONT_CYAN "\033[0;36m"
|
||||||
|
#define CONSOLE_COLOR_FRONT_LIGHT_CYAN "\033[1;36m"
|
||||||
|
#define CONSOLE_COLOR_FRONT_LIGHT_GRAY "\033[0;37m"
|
||||||
|
#define CONSOLE_COLOR_FRONT_WHITE "\033[1;37m"
|
||||||
|
|
||||||
|
#define CONSOLE_COLOR_BACK_BLACK "\033[0;40m"
|
||||||
|
#define CONSOLE_COLOR_BACK_DARK_GRAY "\033[1;40m"
|
||||||
|
#define CONSOLE_COLOR_BACK_RED "\033[0;41m"
|
||||||
|
#define CONSOLE_COLOR_BACK_LIGHT_RED "\033[1;41m"
|
||||||
|
#define CONSOLE_COLOR_BACK_GREEN "\033[0;42m"
|
||||||
|
#define CONSOLE_COLOR_BACK_LIGHT_GREEN "\033[1;42m"
|
||||||
|
#define CONSOLE_COLOR_BACK_BROWN "\033[0;43m"
|
||||||
|
#define CONSOLE_COLOR_BACK_YELLOW "\033[1;43m"
|
||||||
|
#define CONSOLE_COLOR_BACK_BLUE "\033[0;44m"
|
||||||
|
#define CONSOLE_COLOR_BACK_LIGHT_BLUE "\033[1;44m"
|
||||||
|
#define CONSOLE_COLOR_BACK_PURPLE "\033[0;45m"
|
||||||
|
#define CONSOLE_COLOR_BACK_LIGHT_PURPLE "\033[1;45m"
|
||||||
|
#define CONSOLE_COLOR_BACK_CYAN "\033[0;46m"
|
||||||
|
#define CONSOLE_COLOR_BACK_LIGHT_CYAN "\033[1;46m"
|
||||||
|
#define CONSOLE_COLOR_BACK_LIGHT_GRAY "\033[0;47m"
|
||||||
|
#define CONSOLE_COLOR_BACK_WHITE "\033[1;47m"
|
||||||
|
|
||||||
|
|
||||||
|
namespace console
|
||||||
|
{
|
||||||
|
// special effects:
|
||||||
|
// \033[0m close all attributes
|
||||||
|
// \033[1m set high-light
|
||||||
|
// \033[4m underline
|
||||||
|
// \033[5m blink
|
||||||
|
// \033[7m reverse(反显)
|
||||||
|
// \033[8m blanking(消隐)
|
||||||
|
// \033[30m -- \033[37m set foreground color
|
||||||
|
// \033[40m -- \033[47m set background color
|
||||||
|
//
|
||||||
|
// cursor position:
|
||||||
|
// \033[nA move up n lines
|
||||||
|
// \033[nB move down n lines
|
||||||
|
// \033[nC move right n cols
|
||||||
|
// \033[nD move left n cols
|
||||||
|
// \033[y;xH set cursor position
|
||||||
|
// \033[2J clear screen
|
||||||
|
// \033[K clear the line after cursor position
|
||||||
|
// \033[s save cursor position
|
||||||
|
// \033[u restore cursor position
|
||||||
|
// \033[?25l hide cursor
|
||||||
|
// \033[?25h show cursor
|
||||||
|
};
|
||||||
|
|
||||||
|
class cmd_line : public refer
|
||||||
|
{
|
||||||
|
std::string cmd_line_;
|
||||||
|
std::vector<std::string> arguments_;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
cmd_line();
|
||||||
|
~cmd_line();
|
||||||
|
|
||||||
|
public:
|
||||||
|
static cmd_line* from_console(const char* tips);
|
||||||
|
static cmd_line* from_command_line(const char* cmdl);
|
||||||
|
|
||||||
|
public:
|
||||||
|
size_t count(void);
|
||||||
|
const char* parameter(int ind);
|
||||||
|
const char* parameter(const char* key);
|
||||||
|
};
|
||||||
|
|
|
@ -311,6 +311,7 @@ int32_t shared_mem::open(int32_t id, size_t* bytes, const char* name)
|
||||||
|
|
||||||
return errno;
|
return errno;
|
||||||
}
|
}
|
||||||
|
log_cls::log(LOG_LEVEL_DEBUG, "shared memory key: %p\n", key);
|
||||||
|
|
||||||
size = ALIGN_INT(size, shared_mem::page_unit_);
|
size = ALIGN_INT(size, shared_mem::page_unit_);
|
||||||
if (!bytes || *bytes != size)
|
if (!bytes || *bytes != size)
|
||||||
|
@ -380,7 +381,7 @@ int32_t shared_mem::close(void)
|
||||||
if (first_ && shm_id_ >= 0)
|
if (first_ && shm_id_ >= 0)
|
||||||
{
|
{
|
||||||
ret = log_cls::log_when_err(shmctl(shm_id_, IPC_RMID, nullptr), "shmctrl(IPC_RMID)");
|
ret = log_cls::log_when_err(shmctl(shm_id_, IPC_RMID, nullptr), "shmctrl(IPC_RMID)");
|
||||||
if (ret)
|
if (ret && ret != ENOENT)
|
||||||
{
|
{
|
||||||
// re-map buffer ...
|
// re-map buffer ...
|
||||||
shm_buf_ = (char*)shmat(shm_id_, nullptr, 0);
|
shm_buf_ = (char*)shmat(shm_id_, nullptr, 0);
|
||||||
|
|
|
@ -36,6 +36,8 @@ void log_cls::create_log_file(void)
|
||||||
else
|
else
|
||||||
fwrite("\n\n\n", 1, 3, dst_);
|
fwrite("\n\n\n", 1, 3, dst_);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
printf("# Failed to create log file(%s): %d(%s)\n", file_.c_str(), errno, strerror(errno));
|
||||||
}
|
}
|
||||||
|
|
||||||
void log_cls::log_internal(const char* txt)
|
void log_cls::log_internal(const char* txt)
|
||||||
|
@ -47,7 +49,10 @@ void log_cls::log_internal(const char* txt)
|
||||||
LOCKER locker(lock_);
|
LOCKER locker(lock_);
|
||||||
if (dst_)
|
if (dst_)
|
||||||
{
|
{
|
||||||
fwrite(now.c_str(), 1, now.length(), dst_);
|
size_t wrote = fwrite(now.c_str(), 1, now.length(), dst_);
|
||||||
|
if(wrote != now.length())
|
||||||
|
printf("# Write log failed: %d(%s)\n", errno, strerror(errno));
|
||||||
|
|
||||||
fflush(dst_);
|
fflush(dst_);
|
||||||
if (ftell(dst_) >= max_size_)
|
if (ftell(dst_) >= max_size_)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#include "referer.h"
|
#include "referer.h"
|
||||||
|
|
||||||
|
#include <iconv.h>
|
||||||
|
|
||||||
#include "log_util.h"
|
#include "log_util.h"
|
||||||
|
|
||||||
|
@ -165,9 +166,17 @@ namespace sys_util
|
||||||
|
|
||||||
if (para[0].empty())
|
if (para[0].empty())
|
||||||
{
|
{
|
||||||
|
const char* now = getenv("PWD");
|
||||||
|
bool found = strstr(path, now) == path;
|
||||||
|
|
||||||
|
if(found)
|
||||||
|
{
|
||||||
|
found = path[strlen(now)] == '/' && strstr(path + strlen(now) + 1, "/") == nullptr;
|
||||||
|
}
|
||||||
|
if(found || para[1].empty())
|
||||||
para[1] = path;
|
para[1] = path;
|
||||||
|
|
||||||
return false;
|
return !found;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -210,7 +219,7 @@ namespace sys_util
|
||||||
pid += *id - '0';
|
pid += *id - '0';
|
||||||
id++;
|
id++;
|
||||||
}
|
}
|
||||||
if (*id)
|
if (*id || pid == 0)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (cb->process)
|
if (cb->process)
|
||||||
|
@ -284,7 +293,11 @@ namespace sys_util
|
||||||
file += "/";
|
file += "/";
|
||||||
file += ent->d_name;
|
file += ent->d_name;
|
||||||
if ((ent->d_type & DT_DIR) == 0)
|
if ((ent->d_type & DT_DIR) == 0)
|
||||||
|
{
|
||||||
file = read_link(file.c_str());
|
file = read_link(file.c_str());
|
||||||
|
if(file.empty())
|
||||||
|
file = std::string(dir) + "/" + ent->d_name;
|
||||||
|
}
|
||||||
if (!on_found(file.c_str(), ent->d_type & DT_DIR, param))
|
if (!on_found(file.c_str(), ent->d_type & DT_DIR, param))
|
||||||
{
|
{
|
||||||
ret = 0x5e17;
|
ret = 0x5e17;
|
||||||
|
@ -586,5 +599,347 @@ namespace sys_util
|
||||||
|
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static uint64_t from_dec_str(const char* str, const char** end)
|
||||||
|
{
|
||||||
|
uint64_t val = 0;
|
||||||
|
|
||||||
|
for(int i = 0; *str && i < 19; ++i, ++str)
|
||||||
|
{
|
||||||
|
if(*str >= '0' && *str <= '9')
|
||||||
|
{
|
||||||
|
val *= 10;
|
||||||
|
val += *str - '0';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(end)
|
||||||
|
*end = str;
|
||||||
|
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
static uint64_t from_oct_str(const char* str, const char** end)
|
||||||
|
{
|
||||||
|
uint64_t val = 0;
|
||||||
|
|
||||||
|
for(int i = 0; *str && i < 21; ++i, ++str)
|
||||||
|
{
|
||||||
|
if(*str >= '0' && *str <= '7')
|
||||||
|
{
|
||||||
|
val *= 8;
|
||||||
|
val += *str - '0';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(end)
|
||||||
|
*end = str;
|
||||||
|
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
static uint64_t from_bin_str(const char* str, const char** end)
|
||||||
|
{
|
||||||
|
uint64_t val = 0;
|
||||||
|
|
||||||
|
for(int i = 0; *str && i < 64; ++i, ++str)
|
||||||
|
{
|
||||||
|
if(*str >= '0' && *str <= '1')
|
||||||
|
{
|
||||||
|
val *= 2;
|
||||||
|
val += *str - '0';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(end)
|
||||||
|
*end = str;
|
||||||
|
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
uint64_t to_int(const char* str, const char** end)
|
||||||
|
{
|
||||||
|
if(!str || *str == 0)
|
||||||
|
{
|
||||||
|
if(end)
|
||||||
|
*end = str;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(strstr(str, "0x") == str)
|
||||||
|
return from_hex_str(str + 2, end);
|
||||||
|
|
||||||
|
if(str[strlen(str) - 1] == 'h' || str[strlen(str) - 1] == 'H')
|
||||||
|
return from_hex_str(str, end);
|
||||||
|
if(str[strlen(str) - 1] == 'o' || str[strlen(str) - 1] == 'O')
|
||||||
|
return from_oct_str(str, end);
|
||||||
|
if(str[strlen(str) - 1] == 'b' || str[strlen(str) - 1] == 'B')
|
||||||
|
return from_bin_str(str, end);
|
||||||
|
|
||||||
|
bool hex = false;
|
||||||
|
for(int i = 0; str[i]; ++i)
|
||||||
|
{
|
||||||
|
if(str[i] < '0')
|
||||||
|
break;
|
||||||
|
if(str[i] > '9')
|
||||||
|
{
|
||||||
|
if((str[i] >= 'a' && str[i] <= 'f') ||
|
||||||
|
(str[i] >= 'A' && str[i] <= 'F'))
|
||||||
|
hex = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return hex ? from_hex_str(str, end) : from_dec_str(str, end);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* iconv_open language options:
|
||||||
|
|
||||||
|
Europe:
|
||||||
|
ASCII, ISO-8859-{1,2,3,4,5,7,9,10,13,14,15,16}, KOI8-R, KOI8-U, KOI8-RU,
|
||||||
|
CP{1250,1251,1252,1253,1254,1257}, CP{850,866},
|
||||||
|
Mac{Roman,CentralEurope,Iceland,Croatian,Romania},
|
||||||
|
Mac{Cyrillic,Ukraine,Greek,Turkish}, Macintosh
|
||||||
|
|
||||||
|
Semitic:
|
||||||
|
ISO-8859-{6,8}, CP{1255,1256}, CP862, Mac{Hebrew,Arabic}
|
||||||
|
|
||||||
|
Janpanese:
|
||||||
|
EUC-JP, SHIFT-JIS, CP932, ISO-2022-JP, ISO-2022-JP-2, ISO-2022-JP-1
|
||||||
|
|
||||||
|
Chinese:
|
||||||
|
EUC-CN, HZ, GBK, GB18030, EUC-TW, BIG5, CP950, BIG5-HKSCS, ISO-2022-CN, ISO-2022-CN-EXT
|
||||||
|
|
||||||
|
Korean:
|
||||||
|
EUC-KR, CP949, ISO-2022-KR, JOHAB
|
||||||
|
|
||||||
|
Armenian:
|
||||||
|
ARMSCII-8
|
||||||
|
|
||||||
|
Georgian:
|
||||||
|
Georgian-Academy, Georgian-PS
|
||||||
|
|
||||||
|
Thai:
|
||||||
|
TIS-620, CP874, MacThai
|
||||||
|
|
||||||
|
Laos:
|
||||||
|
MuleLao-1, CP1133
|
||||||
|
|
||||||
|
Vietnam:
|
||||||
|
VISCII, TCVN, CP1258
|
||||||
|
|
||||||
|
Special:
|
||||||
|
HP-ROMAN8, NEXTSTEP
|
||||||
|
|
||||||
|
Full Unicode:
|
||||||
|
UTF-8
|
||||||
|
UCS-2, UCS-2BE, UCS-2LE
|
||||||
|
UCS-4, UCS-4BE, UCS-4LE
|
||||||
|
UTF-16, UTF-16BE, UTF-16LE
|
||||||
|
UTF-32, UTF-32BE, UTF-32LE
|
||||||
|
UTF-7
|
||||||
|
JAVA
|
||||||
|
*/
|
||||||
|
std::string transform_between_gbk_and_utf8(const char* in, bool to_utf8, int *err)
|
||||||
|
{
|
||||||
|
size_t len = strlen(in) + 8, ol = len * 2;
|
||||||
|
char *buf = (char*)malloc(len), *oper = buf, *out = nullptr, *oper1 = nullptr;
|
||||||
|
iconv_t conv;
|
||||||
|
|
||||||
|
memset(buf, 0, len);
|
||||||
|
strcpy(buf, in);
|
||||||
|
if(to_utf8)
|
||||||
|
conv = iconv_open("UTF-8", "GBK");
|
||||||
|
else
|
||||||
|
conv = iconv_open("GBK", "UTF-8");
|
||||||
|
if(conv == (iconv_t)-1)
|
||||||
|
{
|
||||||
|
if(err)
|
||||||
|
*err = errno;
|
||||||
|
|
||||||
|
free(buf);
|
||||||
|
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
oper1 = out = (char*)malloc(ol);
|
||||||
|
memset(out, 0, ol);
|
||||||
|
len -= 8;
|
||||||
|
if(iconv(conv, &oper, &len, &oper1, &ol))
|
||||||
|
{
|
||||||
|
if(err)
|
||||||
|
*err = errno;
|
||||||
|
}
|
||||||
|
else if(err)
|
||||||
|
*err = 0;
|
||||||
|
|
||||||
|
std::string ret(out);
|
||||||
|
|
||||||
|
free(buf);
|
||||||
|
free(out);
|
||||||
|
iconv_close(conv);
|
||||||
|
|
||||||
|
return std::move(ret);
|
||||||
|
}
|
||||||
|
std::string transform_between_utf16_and_utf8(const char* in, size_t bytes, bool to_utf8)
|
||||||
|
{
|
||||||
|
static const unsigned char firstByteMark[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
|
||||||
|
std::string ret("");
|
||||||
|
|
||||||
|
if(to_utf8)
|
||||||
|
{
|
||||||
|
unsigned short *uc = *(unsigned short**)&in, val = 0;
|
||||||
|
for(size_t i = 0; i < bytes / 2; ++i, ++uc)
|
||||||
|
{
|
||||||
|
val = *uc;
|
||||||
|
if ((*uc>=0xDC00 && *uc<=0xDFFF) || *uc==0) break; /* check for invalid. */
|
||||||
|
|
||||||
|
if (*uc>=0xD800 && *uc<=0xDBFF) /* UTF16 surrogate pairs. */
|
||||||
|
{
|
||||||
|
unsigned short uc2 = uc[1];
|
||||||
|
if (uc2 < 0xDC00 || uc2 > 0xDFFF) break; /* invalid second-half of surrogate. */
|
||||||
|
val = 0x10000 + (((*uc & 0x3FF) << 10) | (uc2 & 0x3FF));
|
||||||
|
}
|
||||||
|
|
||||||
|
int len = 4;
|
||||||
|
char buf[4] = {0}, *ptr2 = buf;
|
||||||
|
if (val<0x80) len=1;else if (val<0x800) len=2;else if (val<0x10000) len=3; ptr2+=len;
|
||||||
|
|
||||||
|
switch (len) {
|
||||||
|
case 4: *--ptr2 =((val | 0x80) & 0xBF); val >>= 6;
|
||||||
|
case 3: *--ptr2 =((val | 0x80) & 0xBF); val >>= 6;
|
||||||
|
case 2: *--ptr2 =((val | 0x80) & 0xBF); val >>= 6;
|
||||||
|
case 1: *--ptr2 =(val | firstByteMark[len]);
|
||||||
|
}
|
||||||
|
ret += std::string(buf, len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
char* unic = (char*)malloc(strlen(in) * 3 + 8);
|
||||||
|
unsigned char * cur = (unsigned char*)unic;
|
||||||
|
|
||||||
|
while (*cur = *in++)
|
||||||
|
{
|
||||||
|
if ((*cur & 0x0f0) == 0x0e0)
|
||||||
|
{
|
||||||
|
if (((unsigned char)in[0] & 0x0c0) == 0x80 &&
|
||||||
|
((unsigned char)in[1] & 0x0c0) == 0x80)
|
||||||
|
{
|
||||||
|
char* hex = "0123456789ABCDEF";
|
||||||
|
unsigned short us = *cur & 0x0f;
|
||||||
|
us <<= 6;
|
||||||
|
us += in[0] & 0x3f;
|
||||||
|
us <<= 6;
|
||||||
|
us += in[1] & 0x3f;
|
||||||
|
|
||||||
|
*cur++ = '\\';
|
||||||
|
*cur++ = 'u';
|
||||||
|
cur[3] = hex[us & 0x0f];
|
||||||
|
us >>= 4;
|
||||||
|
cur[2] = hex[us & 0x0f];
|
||||||
|
us >>= 4;
|
||||||
|
cur[1] = hex[us & 0x0f];
|
||||||
|
us >>= 4;
|
||||||
|
cur[0] = hex[us & 0x0f];
|
||||||
|
cur += 3;
|
||||||
|
in += 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cur++;
|
||||||
|
}
|
||||||
|
*cur++ = 0;
|
||||||
|
ret = std::string(unic, (char*)cur - unic);
|
||||||
|
free(unic);
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::move(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string to_abs_path(const char* base, const char* rel_path)
|
||||||
|
{
|
||||||
|
if(*rel_path == '/')
|
||||||
|
return rel_path;
|
||||||
|
|
||||||
|
std::string b(base), r(rel_path);
|
||||||
|
size_t pos = 0;
|
||||||
|
|
||||||
|
while(b.length() && b[b.length() - 1] == '/')
|
||||||
|
b.erase(b.length() - 1);
|
||||||
|
|
||||||
|
while(r[0] == '.')
|
||||||
|
{
|
||||||
|
if(r[1] == '/')
|
||||||
|
r.erase(0, 2);
|
||||||
|
else if(r[1] == '.' && r[2] == '/')
|
||||||
|
{
|
||||||
|
pos = b.rfind('/');
|
||||||
|
if(pos == std::string::npos)
|
||||||
|
break;
|
||||||
|
b.erase(pos);
|
||||||
|
r.erase(0, 3);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
b += "/" + r;
|
||||||
|
|
||||||
|
return std::move(b);
|
||||||
|
}
|
||||||
|
std::string to_rel_path(const char* base, const char* abs_path)
|
||||||
|
{
|
||||||
|
if(*abs_path != '/')
|
||||||
|
return abs_path;
|
||||||
|
|
||||||
|
std::string rel(""), b(base), a(abs_path);
|
||||||
|
size_t pos = 0;
|
||||||
|
|
||||||
|
while(b.length() && b[b.length() - 1] == '/')
|
||||||
|
b.erase(b.length() - 1);
|
||||||
|
|
||||||
|
while(a.find(b) == std::string::npos)
|
||||||
|
{
|
||||||
|
rel += "../";
|
||||||
|
pos = b.rfind('/');
|
||||||
|
if(pos == 0)
|
||||||
|
break;
|
||||||
|
b.erase(pos - 1);
|
||||||
|
}
|
||||||
|
if(rel.empty())
|
||||||
|
rel = "./";
|
||||||
|
|
||||||
|
return std::move(rel + a);
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* pick_simple_block(const char* head, char end)
|
||||||
|
{
|
||||||
|
const char* tail = head + 1;
|
||||||
|
int cnt = 1;
|
||||||
|
|
||||||
|
while(*tail)
|
||||||
|
{
|
||||||
|
if(*tail == end)
|
||||||
|
{
|
||||||
|
cnt--;
|
||||||
|
if(cnt == 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if(*tail == *head)
|
||||||
|
{
|
||||||
|
cnt++;
|
||||||
|
}
|
||||||
|
else if(*tail == '\\')
|
||||||
|
{
|
||||||
|
tail++;
|
||||||
|
if(*tail == 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
tail++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return cnt == 0 ? tail : nullptr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -173,4 +173,32 @@ namespace sys_util
|
||||||
bool trim_left(std::string& str, const char* space = " \t");
|
bool trim_left(std::string& str, const char* space = " \t");
|
||||||
bool trim_right(std::string& str, const char* space = " \t");
|
bool trim_right(std::string& str, const char* space = " \t");
|
||||||
uint64_t from_hex_str(const char* hex, const char** end = nullptr); // convert 0x100 to 256. parameter 'end' to receive the stopped position
|
uint64_t from_hex_str(const char* hex, const char** end = nullptr); // convert 0x100 to 256. parameter 'end' to receive the stopped position
|
||||||
|
|
||||||
|
// Function: convert number string to integer, support hex, dec, oct and bin
|
||||||
|
//
|
||||||
|
// Parameter: str - number string.
|
||||||
|
// 0x.../...h: as hexadecimal
|
||||||
|
// ...o: as octonary
|
||||||
|
// ...b: as binary
|
||||||
|
// ...: as decimal, or as hexadecimal if has hex letter
|
||||||
|
//
|
||||||
|
// end - to receive the ending point when covert over
|
||||||
|
//
|
||||||
|
// Return: integer, default is ZERO, you should check the ending point when this value returned
|
||||||
|
uint64_t to_int(const char* str, const char** end = nullptr);
|
||||||
|
|
||||||
|
std::string transform_between_gbk_and_utf8(const char* in, bool to_utf8, int* err = nullptr);
|
||||||
|
std::string transform_between_utf16_and_utf8(const char* in, size_t bytes, bool to_utf8);
|
||||||
|
|
||||||
|
std::string to_abs_path(const char* base, const char* rel_path);
|
||||||
|
std::string to_rel_path(const char* base, const char* abs_path);
|
||||||
|
|
||||||
|
// Function: pick simple block in pair chars
|
||||||
|
//
|
||||||
|
// Parameter: head - beginning of the string, and the first character is the beginning char
|
||||||
|
//
|
||||||
|
// end - ending character of the block
|
||||||
|
//
|
||||||
|
// Return: the last positoin of the block (*ret = end), or nullptr if not matched
|
||||||
|
const char* pick_simple_block(const char* head, char end);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue