This repository has been archived on 2021-11-25. You can view files and clone it, but cannot push or open issues/pull-requests.
JZFamily-HelloWorld/AuxFun.cpp

219 lines
5.5 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

/*
@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;
}
//----------------------------------------------
//Referencehttp://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;
}