219 lines
5.5 KiB
C++
219 lines
5.5 KiB
C++
/*
|
||
@2017-12-06,add by jidzh,for 各种辅助函数
|
||
*/
|
||
|
||
#include "AuxFun.h"
|
||
#include<Windows.h>
|
||
#include <string>
|
||
#include <assert.h>
|
||
|
||
#include "zconf.h"
|
||
#include "zlib.h"
|
||
std::string MBCStoUTF8(const char* mbcsStr)
|
||
{
|
||
wchar_t* wideStr;
|
||
char* strAnsi;
|
||
int charLen;
|
||
//先转换成utf-16
|
||
charLen = MultiByteToWideChar(CP_ACP, 0, mbcsStr, -1, NULL, 0);
|
||
wideStr = (wchar_t*)malloc(sizeof(wchar_t)*charLen);
|
||
MultiByteToWideChar(CP_ACP, 0, mbcsStr, -1, wideStr, charLen);
|
||
//再转换成utf-8
|
||
charLen = WideCharToMultiByte(CP_UTF8, 0, wideStr, -1, NULL, 0, NULL, NULL);
|
||
strAnsi = (char*)malloc(charLen);
|
||
WideCharToMultiByte(CP_UTF8, 0, wideStr, -1, strAnsi, charLen, NULL, NULL);
|
||
std::string strRet = strAnsi;
|
||
|
||
free(wideStr);
|
||
free(strAnsi);
|
||
return strRet;
|
||
}
|
||
std::string UTF8ToMultiByte(const char* mbcsStr)
|
||
{
|
||
wchar_t* wideStr;
|
||
char* strAnsi;
|
||
int charLen;
|
||
|
||
charLen = MultiByteToWideChar(CP_UTF8, 0, mbcsStr, -1, NULL, 0);
|
||
wideStr = (wchar_t*)malloc(sizeof(wchar_t)*charLen);
|
||
MultiByteToWideChar(CP_UTF8, 0, mbcsStr, -1, wideStr, charLen);
|
||
|
||
charLen = WideCharToMultiByte(CP_ACP, 0, wideStr, -1, NULL, 0, NULL, NULL);
|
||
strAnsi = (char*)malloc(charLen);
|
||
WideCharToMultiByte(CP_ACP, 0, wideStr, -1, strAnsi, charLen, NULL, NULL);
|
||
|
||
std::string strRet = strAnsi;
|
||
free(wideStr);
|
||
free(strAnsi);
|
||
return strRet;
|
||
}
|
||
|
||
//----------------------------------------------
|
||
//Reference:http://blog.csdn.net/gemo/article/details/8468311
|
||
//______________________________________________
|
||
unsigned char ToHex(unsigned char x)
|
||
{
|
||
//十进制 'A'65 '0'48
|
||
return x > 9 ? x + 55 : x + 48;
|
||
}
|
||
|
||
unsigned char FromHex(unsigned char x)
|
||
{
|
||
unsigned char y;
|
||
if (x >= 'A' && x <= 'Z') { y = x - 'A' + 10; }
|
||
else if (x >= 'a' && x <= 'z') { y = x - 'a' + 10; }
|
||
else if (x >= '0' && x <= '9') { y = x - '0'; }
|
||
else { assert(0); }
|
||
return y;
|
||
}
|
||
|
||
std::string UrlEncode(const std::string& str)
|
||
{
|
||
std::string strTemp = "";
|
||
size_t length = str.length();
|
||
for (size_t i = 0; i < length; i++)
|
||
{
|
||
if (isalnum((unsigned char)str[i]) ||
|
||
(str[i] == '-') ||
|
||
(str[i] == '_') ||
|
||
(str[i] == '.') ||
|
||
(str[i] == '~')) { strTemp += str[i]; }
|
||
|
||
else if (str[i] == ' ') { strTemp += "+"; }
|
||
else
|
||
{
|
||
strTemp += '%';
|
||
strTemp += ToHex((unsigned char)str[i] >> 4);
|
||
strTemp += ToHex((unsigned char)str[i] % 16);
|
||
}
|
||
}
|
||
return strTemp;
|
||
}
|
||
|
||
std::string UrlDecode(const std::string& str)
|
||
{
|
||
std::string strTemp = "";
|
||
size_t length = str.length();
|
||
for (size_t i = 0; i < length; i++)
|
||
{
|
||
if (str[i] == '+') strTemp += ' ';
|
||
else if (str[i] == '%')
|
||
{
|
||
assert(i + 2 < length);
|
||
unsigned char high = FromHex((unsigned char)str[++i]);
|
||
unsigned char low = FromHex((unsigned char)str[++i]);
|
||
strTemp += high * 16 + low;
|
||
}
|
||
else strTemp += str[i];
|
||
}
|
||
return strTemp;
|
||
}
|
||
|
||
int inflate_read(char *source, int len, char **dest, int gzip, int& iTotalRead)
|
||
{
|
||
int ret;
|
||
unsigned have;
|
||
z_stream strm;
|
||
unsigned char out[10000] = {0};
|
||
|
||
int totalsize = 0;
|
||
|
||
/* allocate inflate state */
|
||
strcpy((char*)out, "");
|
||
strm.zalloc = Z_NULL;
|
||
strm.zfree = Z_NULL;
|
||
strm.opaque = Z_NULL;
|
||
strm.avail_in = len;
|
||
strm.next_in = (Bytef*)source;
|
||
if (gzip)
|
||
ret = inflateInit2(&strm, 47);
|
||
else
|
||
ret = inflateInit(&strm);
|
||
|
||
if (ret != Z_OK)
|
||
return ret;
|
||
|
||
strm.avail_in = len;
|
||
strm.next_in = (Bytef*)source;
|
||
|
||
/* run inflate() on input until output buffer not full */
|
||
do {
|
||
strm.avail_out = 10000;
|
||
strm.next_out = out;
|
||
ret = inflate(&strm, Z_NO_FLUSH);
|
||
//assert(ret != Z_STREAM_ERROR); /* state not clobbered */
|
||
|
||
switch (ret) {
|
||
case Z_NEED_DICT:
|
||
ret = Z_DATA_ERROR; /* and fall through */
|
||
case Z_DATA_ERROR:
|
||
case Z_MEM_ERROR:
|
||
inflateEnd(&strm);
|
||
return ret;
|
||
}
|
||
|
||
have = 10000 - strm.avail_out;
|
||
totalsize += have;
|
||
*dest = (char*)realloc(*dest, totalsize);
|
||
iTotalRead = totalsize;
|
||
memcpy(*dest + totalsize - have, out, have);
|
||
} while (strm.avail_out == 0);
|
||
|
||
/* clean up and return */
|
||
(void)inflateEnd(&strm);
|
||
|
||
return ret == Z_STREAM_END ? Z_OK : Z_DATA_ERROR;
|
||
}
|
||
|
||
#define segment_size 1460//largest tcp data segment 1460
|
||
int ungzip(char* source, int len, char*des)
|
||
{
|
||
int ret, have;
|
||
int offset = 0;
|
||
z_stream d_stream;
|
||
Byte compr[segment_size] = { 0 }, uncompr[segment_size * 4] = { 0 };
|
||
memcpy(compr, (Byte*)source, len);
|
||
uLong comprLen, uncomprLen;
|
||
comprLen = len;//一开始写成了comprlen=sizeof(compr)以及comprlen=strlen(compr),后来发现都不对。
|
||
//sizeof(compr)永远都是segment_size,显然不对,strlen(compr)也是不对的,因为strlen只算到\0之前,
|
||
//但是gzip或者zlib数据里\0很多。
|
||
uncomprLen = segment_size * 4;
|
||
strcpy((char*)uncompr, "garbage");
|
||
d_stream.zalloc = Z_NULL;
|
||
d_stream.zfree = Z_NULL;
|
||
d_stream.opaque = Z_NULL;
|
||
d_stream.next_in = Z_NULL;//inflateInit和inflateInit2都必须初始化next_in和avail_in
|
||
d_stream.avail_in = 0;//deflateInit和deflateInit2则不用
|
||
ret = inflateInit2(&d_stream, 47);
|
||
if (ret != Z_OK)
|
||
{
|
||
printf("inflateInit2 error:%d", ret);
|
||
return ret;
|
||
}
|
||
d_stream.next_in = compr;
|
||
d_stream.avail_in = comprLen;
|
||
do
|
||
{
|
||
d_stream.next_out = uncompr;
|
||
d_stream.avail_out = uncomprLen;
|
||
ret = inflate(&d_stream, Z_NO_FLUSH);
|
||
assert(ret != Z_STREAM_ERROR);
|
||
switch (ret)
|
||
{
|
||
case Z_NEED_DICT:
|
||
ret = Z_DATA_ERROR;
|
||
case Z_DATA_ERROR:
|
||
case Z_MEM_ERROR:
|
||
(void)inflateEnd(&d_stream);
|
||
return ret;
|
||
}
|
||
have = uncomprLen - d_stream.avail_out;
|
||
memcpy(des + offset, uncompr, have);//这里一开始我写成了memcpy(des+offset,d_stream.next_out,have);
|
||
//后来发现这是不对的,因为next_out指向的下次的输出,现在指向的是无有意义数据的内存。见下图
|
||
offset += have;
|
||
} while (d_stream.avail_out == 0);
|
||
inflateEnd(&d_stream);
|
||
memcpy(des + offset, "\0", 1);
|
||
return ret;
|
||
}
|