📄 util.cpp
字号:
////////////////////////////////////////////////////////////////////////////////
// 工具模块
////////////////////////////////////////////////////////////////////////////////
// Author : Darkay Li
// Description : 实现各种工具函数,类等
//
// Version : 1.0
//
// Standard include files : std_inc.hpp
//
// Start Date : 2003年5月7日
//
// Change Log :
// 2003年5月7日 by Darkay Li
//-- Created
// [5/16/2003] by Darkay Li
//-- move bcdcode class to single file
// [5/19/2003] by Darkay Li
//-- add class FixedVector
////////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "janitor.h"
#include "util.h"
#ifdef __linux__
#include <iconv.h> // for iconv_xxxx
#endif
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
namespace stk
{
static std::string m_strEmpty;
//////////////////////////////////////////////////////////////////////////////
// Function Name : FileSize
// Author : Darkay Li
// Description : get the size of specail file
// Input Parameters : file -- file name with full path
// Return Value : int -- the file size, -1 means get file size failed
// Ext Function called : none
// Start Date : 2003年5月7日
// Change log : 2003年5月7日 by Darkay Li -- Created
//////////////////////////////////////////////////////////////////////////////
int fileSize(const char* file)
{
struct stat stbuf;
if (stat(file, &stbuf) == -1)
return -1;
else
return stbuf.st_size;
}
//////////////////////////////////////////////////////////////////////////////
// Function Name : CheckHalfChinese
// Author : Darkay Li
// Description : check whether the buf contain half chinese
// Input Parameters : buf -- the string will be check
// Return Value : bool(true-contian half chinse, false-no)
// Ext Function called : none
// Start Date : 2003年5月7日
// Change log : 2003年5月7日 by Darkay Li -- Created
//////////////////////////////////////////////////////////////////////////////
bool checkHalfChinese(const std::string& buf)
{
size_t count = 0;
size_t size = buf.size();
for(size_t i=0; i<size; ++i)
{
if(static_cast<unsigned char>(buf[i]) > 128)
count++;
}
//if odd value means
return count & 0x1;
}
const char* toHex(unsigned char byte, char* buf)
{
assert(buf);
sprintf(buf, "%02X", byte);
return buf;
}
//////////////////////////////////////////////////////////////////////////////
// Function Name : ToHex
// Author : Darkay Li
// Description : convert a stream to hex string format
// Input Parameters : buf -- the stream
// length -- length of the stream
// : hex -- which store the hex format string
// Return Value : pointer to the hex
// Ext Function called :
// Start Date : 2003年5月7日
// Change log : 2003年5月7日 by Darkay Li -- Created
//////////////////////////////////////////////////////////////////////////////
const char* toHex(const char* buf, size_t length, std::string& hex)
{
assert(buf);
assert(length >= 0);
hex.reserve(2*strlen(buf)+3);
hex = "";
char tmp[16];
while(length--)
hex += toHex(static_cast<unsigned char >(*buf++), tmp);
return hex.c_str();
}
void fromHex(const char *buf, size_t length, std::string &oct)
{
char tmp[16];
unsigned int hexVal = 0;
for(size_t index = 0; index < length-1; /*在循环内改变index*/)
{
tmp[0] = buf[index];
tmp[1] = buf[index+1];
tmp[2] = '\0';
sscanf(tmp, "%02X", &hexVal);
oct += hexVal;
index += 2;
}
// append the last char if length is odd(last bit is 1)
if((length & 1) != 0)
oct += buf[length-1];
}
//////////////////////////////////////////////////////////////////////////////
// Function Name : strncpy
// Author : 黎达文
// Description : copy count-1 at most from source to dest
// and append \0 at the end of the dest
// more safe check than the STD strncpy
// Input Parameters :
// Return Value :
// Ext Function called :
// Start Date : 2003年7月8日
// Change log : 2003年7月8日 by 黎达文 -- Created
//////////////////////////////////////////////////////////////////////////////
char* strncpy(char* dest, const char* source, size_t count)
{
if(dest && source && count>0)
{
::strncpy(dest, source, count);
dest[count] = '\0';
}
//trace("strncpy parameter error!");
return dest;
}
//////////////////////////////////////////////////////////////////////////////
// Function Name : takeUnicode
// Author : 黎达文
// Description : 从[begin, end)中取"howmany"个字符(UCS格式的字符)
// howmany是指UNICODE字符的长度,一个汉字和一个ASCII字符都是一个UNICODE字符。
// output的至少需要"howmany"*2字节大小。
// Input Parameters :
// Return Value : -1 : error, else
// Ext Function called :
// Start Date : 2003年7月8日
// Change log : 2003年7月8日 by 黎达文 -- Created
//////////////////////////////////////////////////////////////////////////////
int takeUnicode(const char *begin, const char *end,
size_t howmany, char *output)
{
if(end <= begin || howmany<=0)
return -1;
const char *ptr = begin;
size_t read = 0; // how many bytes read
howmany *= 2; // the real bytes we will read
while(ptr < end && read < howmany)
{
read++;
if(static_cast<unsigned char>(*ptr) < 0x80)
{
//one ASCII char use 2 bytes in UCS format, so read plus more one
read ++;
}
*output++ = *ptr++;
}
return ptr - begin;
}
//////////////////////////////////////////////////////////////////////////////
// Function Name : splitString
// Description : split "str" with "spliter" into string vector.
// "want" indicate you just want to copy how may slice
// if str = "123|234|567" and slipter = '|' then
// vec[0] = "123", vec[1] = "234", vec[2] = "567"
// Input Parameters : str -- the string with spliter
// spliter --
// want -- how many slice you want
// vec -- output result
// Return Value : how many slice find
//////////////////////////////////////////////////////////////////////////////
size_t splitString(const char *str,
char spliter,
int want,
std::vector<std::string> &vec)
{
assert(str);
assert(want>0);
const char *pbeg = str;
--want;
while(*str && want>0)
{
if(*str == spliter)
{
vec.push_back(std::string(pbeg, str));
pbeg = str+1;
--want;
}
++str;
}
if(*pbeg)
vec.push_back(std::string(pbeg));
return vec.size();
}
//////////////////////////////////////////////////////////////////////////////
// Function Name : splitString
// Description : split "source" with "delims" into string vector.
// if str = "123,234|567" and slipter = ',|' then
// vec[0] = "123", vec[1] = "234", vec[2] = "567"
// this function with more power than above function, coz it support multi-spliter
// and it more effective using the STL method.
// Input Parameters : source -- the string with spliter
// delims -- the spliters
// vec -- output result -- string vector
// Return Value : how many slice had found
//////////////////////////////////////////////////////////////////////////////
size_t splitString(const std::string &source,
const char *delims,
std::vector<std::string> &vec,
bool keepEmpty /*= false*/)
{
// find the index of which not delims
std::string::size_type beg = source.find_first_not_of(delims);
std::string::size_type end;
std::string::size_type nextBeg = beg;
while(beg != std::string::npos)
{
// find the index which is delims, than [beg, end) is the slice we want
end = source.find_first_of(delims, nextBeg+1);
nextBeg = end;
if(end < beg)
{
// we find that case : two delims
if(keepEmpty)
vec.push_back("");
}
else if(end != std::string::npos)
{
vec.push_back(source.substr(beg, end-beg));
// update the begin index from the end index
beg = source.find_first_not_of(delims, nextBeg);
}
else
{
vec.push_back(source.substr(beg));
break;
}
}
return vec.size();
}
//////////////////////////////////////////////////////////////////////////////
// Function Name : ConvertUCS2ToGB2312
// Description : convert ucs2 format unicode data to GB2312
// Input Parameters : unicode -- the unicode buffer
// unicodeLength -- the length of unicode buffer
// gbBuffer
// Return Value :
// Ext Function called :
//////////////////////////////////////////////////////////////////////////////
std::string ConvertUCS2ToGB2312(const char *unicode, size_t unicodeLength)
{
//make the new buffer and convert to network bytes order
ArrayJanitor<char> inBufferJanitor(new char[unicodeLength]);
char *inBuffer = inBufferJanitor.get();
memcpy(inBuffer, unicode, unicodeLength);
unsigned short *pbuf = (unsigned short *)inBuffer;
unsigned short tmp;
for(size_t i=0; i<unicodeLength/2; i++)
{
tmp = *pbuf;
*pbuf++ = ntohs(tmp);
}
#if defined(_WIN32) || defined(WIN32)
//get the output length
size_t outLength = WideCharToMultiByte(936, MB_PRECOMPOSED,
(LPCWSTR)inBuffer, static_cast<int>(unicodeLength/2),
NULL, 0, NULL, NULL);
ArrayJanitor<char> outBufferJanitor(new char[outLength+1]);
char *outBuffer = outBufferJanitor.get();
//convert it!
outLength = WideCharToMultiByte(936, MB_PRECOMPOSED,
(LPCWSTR)inBuffer, static_cast<int>(unicodeLength/2),
(char*)outBuffer, static_cast<int>(outLength), NULL, NULL);
outBuffer[outLength] = '\0';
return outBuffer;
#else //linux
size_t outLength = unicodeLength*2+128;
ArrayJanitor<char> outBufferJanitor(new char[outLength+1]);
char *outBuffer = outBufferJanitor.get();
//set the conversion descriptor as From UCS-2 to GB2312
iconv_t convDesc= iconv_open("GB2312", "UNICODE");
int error = iconv(convDesc, &inBuffer, &unicodeLength,
&outBuffer, &outLength);
iconv_close(convDesc);
return outBuffer;
#endif
}
void trim(std::string &str)
{
static const std::string SPACE_CHARS = " \t\r\n";
std::string::size_type first = str.find_first_not_of(SPACE_CHARS);
if(first == std::string::npos)
{
// all data is SPACE;
str = "";
}
else
{
std::string::size_type last = str.find_last_not_of(SPACE_CHARS);
str = str.substr(first, last-first+1);
}
}
unsigned char calcCheckSum(const unsigned char *checkBegin, size_t length)
{
unsigned char checkSum = 0;
for(size_t i=0; i<length; i++)
checkSum += *checkBegin++;
return 256 - checkSum;
}
std::string indentSpace(int indent)
{
std::string space = "";
for(int i=0; i<indent; ++i)
{
space += "\t";
}
return space;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -