📄 istring.cpp
字号:
/*
This file is part of KCeasy (http://www.kceasy.com)
Copyright (C) 2002-2004 Markus Kern <mkern@kceasy.com>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
*/
//---------------------------------------------------------------------------
#include <stdio.h> // snprintf
#include <algorithm> // for STL transform
#include <cctype> // for toupper
#include "istring.h"
//---------------------------------------------------------------------------
using namespace std;
namespace KCeasyEngine {
// int <=> string conversion
string int_to_string(int Val)
{
char buf[34];
return itoa(Val,buf,10);
}
string uint_to_string(unsigned int Val)
{
char buf[34];
return ultoa(Val,buf,10);
}
string float_to_string(double Val)
{
char buf[32];
snprintf(buf,32,"%lf",Val);
return (string)buf;
}
// Thanks to jmehney@umich.edu for this.
string string_tolower(const string& str)
{
string lower(str);
transform(lower.begin(), lower.end(), lower.begin(), tolower);
return lower;
}
string string_toupper(const string& str)
{
string upper(str);
transform(upper.begin(), upper.end(), upper.begin(), toupper);
return upper;
}
string string_trim(const string& str)
{
string trimmed(str);
int pos;
if((pos = trimmed.find_first_not_of(" \t\r\n")) == -1)
return "";
else if(pos > 0)
trimmed.erase(0,pos);
if((pos = trimmed.find_last_not_of(" \t\r\n")) == -1)
return "";
else if(pos < ((int)trimmed.length())-1)
trimmed.erase(pos+1);
return trimmed;
}
// Thanks to jmehney@umich.edu for this.
string string_replace(const string& str, const char* match, const char* replacement)
{
string res = str;
int charpos;
int matchpos = res.find(match);
int matchlen = strlen(match);
int replacementlen = strlen(replacement);
while(matchpos != res.npos)
{
res.replace(matchpos, matchlen, replacement);
charpos = matchpos + replacementlen;
matchpos = res.find(match, charpos);
}
return res;
}
list<string> string_split(const string& str, const char* separator)
{
list<string> strlist;
if(str == "")
return strlist;
int p1 = str.find(separator);
int p2 = 0;
while(p1 != -1) {
strlist.push_back(str.substr(p2,p1-p2));
p2 = p1 + strlen(separator);
p1 = str.find(separator,p2);
}
strlist.push_back(str.substr(p2));
return strlist;
}
string string_join(const list<string>& strlist, const char* separator)
{
if(strlist.empty())
return "";
list<string>::const_iterator itr = strlist.begin();
string str = (*itr);
for(++itr; itr!=strlist.end(); ++itr)
str += string(separator) + (*itr);
return str;
}
// FIXME: clean this mess up
string FormatNumber(unsigned long Value, const char* BaseUnit, int NoOfDecimals)
{
char buf[128];
if(NoOfDecimals == -1) {
// no scaling
int len = snprintf(buf,128,"%lu",Value);
if(len > 3) {
char *p = buf + ((len%3 == 0) ? 3 : (len%3));
for(;*p;p+=4) {
memmove(p+1,p,strlen(p)+1);
*p = ',';
}
}
if(BaseUnit) {
strcat(buf," ");
strcat(buf,BaseUnit);
}
} else {
if(Value > (unsigned long)1024*1024*1024)
snprintf(buf,128,"%.*lf G%s",NoOfDecimals,((double)Value)/1024/1024/1024,BaseUnit);
else if(Value > (unsigned long)1024*1024)
snprintf(buf,128,"%.*lf M%s",NoOfDecimals,((double)Value)/1024/1024,BaseUnit);
else if(Value > (unsigned long)1024)
snprintf(buf,128,"%.*lf K%s",NoOfDecimals,((double)Value)/1024,BaseUnit);
else
snprintf(buf,128,"%.*lf %s",NoOfDecimals,((double)Value),BaseUnit);
}
buf[127] = 0;
return (string)buf;
}
string FormatTime(unsigned long Seconds)
{
char buf[128];
if(Seconds >= 3600)
snprintf(buf,128,"%d:%02d:%02d", Seconds/3600, (Seconds/60)%60, Seconds%60);
else
snprintf(buf,128,"%d:%02d", (Seconds/60)%60, Seconds%60);
return (string)buf;
}
// base64 encoder/decoder
// caller delete[]s returned string
char* Base64Encode (const unsigned char *data, int src_len)
{
static const char base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
unsigned char *dst, *out;
if(!data)
return NULL;
if((out = dst = new char[(src_len + 4) * 2]) == NULL)
return NULL;
for (; src_len > 2; src_len-=3, dst+=4, data+=3)
{
dst[0] = base64[data[0] >> 2];
dst[1] = base64[((data[0] & 0x03) << 4) + (data[1] >> 4)];
dst[2] = base64[((data[1] & 0x0f) << 2) + (data[2] >> 6)];
dst[3] = base64[data[2] & 0x3f];
}
dst[0] = '\0';
if (src_len == 1)
{
dst[0] = base64[data[0] >> 2];
dst[1] = base64[((data[0] & 0x03) << 4)];
dst[2] = '=';
dst[3] = '=';
dst[4] = '\0';
}
if (src_len == 2)
{
dst[0] = base64[data[0] >> 2];
dst[1] = base64[((data[0] & 0x03) << 4) + (data[1] >> 4)];
dst[2] = base64[((data[1] & 0x0f) << 2)];
dst[3] = '=';
dst[4] = '\0';
}
return out;
}
// caller delete[]s returned string
unsigned char* Base64Decode (const char *data, int *dst_len)
{
static const char base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
unsigned char *dst, *out;
char *p;
int i;
unsigned char in[4];
if(!data)
return NULL;
if((out = dst = new unsigned char[strlen(data)]) == NULL)
return NULL;
for (i=0, *dst_len=0; *data; data++)
{
if((p = strchr((char*)base64, *data)) == NULL)
continue;
in[i++] = (unsigned char)(p - base64);
if (i == 4)
{
dst[0] = (in[0] << 2) | ((in[1] & 0x30) >> 4);
dst[1] = ((in[1] & 0x0F) << 4) | ((in[2] & 0x3C) >> 2);
dst[2] = ((in[2] & 0x03) << 6) | (in[3] & 0x3F);
dst += 3;
*dst_len += 3;
i = 0;
}
}
if (i >= 2)
{
dst[0] = (in[0] << 2) | ((in[1] & 0x30) >> 4);
(*dst_len)++;
}
if (i == 3)
{
dst[1] = ((in[1] & 0x0F) << 4) | ((in[2] & 0x3C) >> 2);
(*dst_len)++;
}
return out;
}
// hex encoder/decoder
// caller delete[]s returned string
char* Base16Encode (const unsigned char *data, int src_len)
{
static const char hex_string[] = "0123456789abcdefABCDEF";
char *out, *dst;
int i;
if (!data)
return NULL;
if (! (out = dst = new char[src_len * 2 + 1]))
return NULL;
for(i=0; i<src_len; i++, dst += 2)
{
dst[0] = hex_string[data[i] >> 4];
dst[1] = hex_string[data[i] & 0x0F];
}
dst[0] = 0;
return out;
}
// caller delete[]s returned string
unsigned char* Base16Decode (const char *data, int *dst_len)
{
static const char hex_string[] = "0123456789abcdefABCDEF";
char *dst;
const char *h;
int i;
unsigned char hi, lo;
if (!data)
return NULL;
if (! (dst = new unsigned char [strlen (data) / 2 + 1]))
return NULL;
for(i=0; *data && data[1]; i++, data += 2)
{
/* high nibble */
if( (h = strchr (hex_string, data[0])) == NULL)
{
free (dst);
return NULL;
}
hi = (h - hex_string) > 0x0F ? (h - hex_string - 6) : (h - hex_string);
/* low nibble */
if ( (h = strchr (hex_string, data[1])) == NULL)
{
free (dst);
return NULL;
}
lo = (h - hex_string) > 0x0F ? (h - hex_string - 6) : (h - hex_string);
dst[i] = (hi << 4) | lo;
}
if (dst_len)
*dst_len = i;
return dst;
}
// url parsing
string UrlEncode(const string& Url)
{
static const char HexString[] = "0123456789abcdef0123456789ABCDEF";
string Buffer;
Buffer = "";
for(const char* p=Url.c_str();p && *p;p++) {
if( (*p >= 0x30 && *p <= 0x39) || // 0-9
(*p >= 0x41 && *p <= 0x5a) || // A-Z
(*p >= 0x61 && *p <= 0x7a) || // a-z
*p == '(' || *p == ')' ||
*p == '-' || *p == '_' ||
*p == '.' || *p == '+'
)
{
Buffer += *p;
} else {
Buffer += '%';
Buffer += HexString[((unsigned char)*p) >> 4];
Buffer += HexString[((unsigned char)*p) & 15];
}
}
return Buffer;
}
string UrlDecode(const string& Url)
{
static const char HexString[] = "0123456789abcdef0123456789ABCDEF";
string Buffer;
const char *pHigh, *pLow;
Buffer = "";
for(const char* p=Url.c_str();p && *p;p++) {
if(*p == '%') {
if(p[1] == 0 || p[2] == 0) {
Buffer += *p;
return Buffer;
}
pHigh = strchr(HexString,p[1]);
pLow = strchr(HexString,p[2]);
if(!pHigh || !pLow) {
Buffer += *p;
p++;
} else {
Buffer += (((pHigh - HexString) & 15) << 4) + ((pLow - HexString) & 15);
p += 2;
}
} else {
Buffer += *p;
}
}
return Buffer;
}
string FileFromUrl(const string& Url)
{
string Buffer;
int pos;
Buffer = PathFromUrl(Url);
if((pos = Url.rfind('/')) != -1)
Buffer = Url.substr(pos+1);
return Buffer;
}
string PathFromUrl(const string& Url)
{
string Buffer;
int p1;
Buffer = "";
if((p1 = Url.find("//")) == -1)
return Buffer;
if((p1 = Url.find('/',p1+2)) == -1)
return Buffer;
Buffer = Url.substr(p1);
return Buffer;
}
string HostFromUrl(const string& Url)
{
string Buffer;
int p1, p2;
Buffer = "";
if((p1 = Url.find("//")) == -1)
return Buffer;
// url is either "OpenFT://host:port/path"
// or "OpenFT://fw_host:my_port@node_host:node_port/path"
if((p2 = Url.find_first_of(":@/",p1+2)) != -1)
Buffer = Url.substr(p1+2,p2-p1-2);
return Buffer;
}
unsigned int PortFromUrl(const string& Url)
{
int p1, p2;
if((p1 = Url.find("//")) == -1)
return 0;
// url is either "OpenFT://host:port/path"
// or "OpenFT://fw_host:my_port@node_host:node_port/path"
if(Url.find('@',p1+2) != -1)
return 0; // returning our own port makes no sense
if((p1 = Url.find(':',p1+2)) == -1)
return 0;
if((p2 = Url.find('/',p1+1)) == -1)
return 0;
return atoi(Url.substr(p1+1,p2-p1-1).c_str());
}
string ProtocolFromUrl(const string& Url)
{
int p1;
if((p1 = Url.find(":")) == -1)
return "";
return Url.substr(0,p1);
}
// path mangling
string SanitizePath(const string& Path)
{
static const char HexString[] = "0123456789abcdef0123456789ABCDEF";
string Buffer;
Buffer = "";
// urlencode everything not explicitly allowed
for(const char* p=Path.c_str();p && *p;p++) {
if( (*p >= 0x30 && *p <= 0x39) || // 0-9
(*p >= 0x41 && *p <= 0x5a) || // A-Z
(*p >= 0x61 && *p <= 0x7a) || // a-z
*p == '
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -