SocketHelper.cpp 40 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669
  1. /*
  2. * Copyright: JessMA Open Source (ldcsaa@gmail.com)
  3. *
  4. * Author : Bruce Liang
  5. * Website : https://github.com/ldcsaa
  6. * Project : https://github.com/ldcsaa/HP-Socket
  7. * Blog : http://www.cnblogs.com/ldcsaa
  8. * Wiki : http://www.oschina.net/p/hp-socket
  9. * QQ Group : 44636872, 75375912
  10. *
  11. * Licensed under the Apache License, Version 2.0 (the "License");
  12. * you may not use this file except in compliance with the License.
  13. * You may obtain a copy of the License at
  14. *
  15. * http://www.apache.org/licenses/LICENSE-2.0
  16. *
  17. * Unless required by applicable law or agreed to in writing, software
  18. * distributed under the License is distributed on an "AS IS" BASIS,
  19. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  20. * See the License for the specific language governing permissions and
  21. * limitations under the License.
  22. */
  23. #include "SocketHelper.h"
  24. #include <sys/ioctl.h>
  25. #include <arpa/inet.h>
  26. #include <netinet/tcp.h>
  27. #include <netinet/udp.h>
  28. #ifdef _ICONV_SUPPORT
  29. #include <iconv.h>
  30. #endif
  31. #ifndef SO_REUSEPORT
  32. #define SO_REUSEPORT 15
  33. #endif
  34. ///////////////////////////////////////////////////////////////////////////////////////////////////////
  35. ///////////////////////////////////////////////////////////////////////////////////////////////////////
  36. static const BYTE s_szUdpCloseNotify[] = {0xBE, 0xB6, 0x1F, 0xEB, 0xDA, 0x52, 0x46, 0xBA, 0x92, 0x33, 0x59, 0xDB, 0xBF, 0xE6, 0xC8, 0xE4};
  37. static const int s_iUdpCloseNotifySize = ARRAY_SIZE(s_szUdpCloseNotify);
  38. const hp_addr hp_addr::ANY_ADDR4(AF_INET, TRUE);
  39. const hp_addr hp_addr::ANY_ADDR6(AF_INET6, TRUE);
  40. BOOL SetCurrentWorkerThreadName()
  41. {
  42. return SetWorkerThreadDefaultName(0);
  43. }
  44. BOOL SetWorkerThreadDefaultName(THR_ID tid)
  45. {
  46. static volatile UINT _s_uiSeq = MAXUINT;
  47. return ::SetSequenceThreadName(tid, DEFAULT_WORKER_THREAD_PREFIX, _s_uiSeq);
  48. }
  49. LPCTSTR GetSocketErrorDesc(EnSocketError enCode)
  50. {
  51. switch(enCode)
  52. {
  53. case SE_OK: return _T("SUCCESS");
  54. case SE_ILLEGAL_STATE: return _T("Illegal State");
  55. case SE_INVALID_PARAM: return _T("Invalid Parameter");
  56. case SE_SOCKET_CREATE: return _T("Create SOCKET Fail");
  57. case SE_SOCKET_BIND: return _T("Bind SOCKET Fail");
  58. case SE_SOCKET_PREPARE: return _T("Prepare SOCKET Fail");
  59. case SE_SOCKET_LISTEN: return _T("Listen SOCKET Fail");
  60. case SE_CP_CREATE: return _T("Create IOCP Fail");
  61. case SE_WORKER_THREAD_CREATE: return _T("Create Worker Thread Fail");
  62. case SE_DETECT_THREAD_CREATE: return _T("Create Detector Thread Fail");
  63. case SE_SOCKE_ATTACH_TO_CP: return _T("Attach SOCKET to IOCP Fail");
  64. case SE_CONNECT_SERVER: return _T("Connect to Server Fail");
  65. case SE_NETWORK: return _T("Network Error");
  66. case SE_DATA_PROC: return _T("Process Data Error");
  67. case SE_DATA_SEND: return _T("Send Data Fail");
  68. case SE_GC_START: return _T("Start GC Fail");
  69. case SE_SSL_ENV_NOT_READY: return _T("SSL environment not ready");
  70. default: ASSERT(FALSE); return _T("UNKNOWN ERROR");
  71. }
  72. }
  73. ADDRESS_FAMILY DetermineAddrFamily(LPCTSTR lpszAddress)
  74. {
  75. if (!lpszAddress || lpszAddress[0] == 0)
  76. return AF_UNSPEC;
  77. if(::StrChr(lpszAddress, IPV6_ADDR_SEPARATOR_CHAR))
  78. return AF_INET6;
  79. TCHAR c;
  80. int arr[4];
  81. if(stscanf(lpszAddress, _T("%d.%d.%d.%d%c"), &arr[0], &arr[1], &arr[2], &arr[3], &c) != 4)
  82. return AF_UNSPEC;
  83. for(int i = 0; i < 4; i++)
  84. {
  85. if(arr[i] < 0 || arr[i] > 255)
  86. return AF_UNSPEC;
  87. }
  88. return AF_INET;
  89. }
  90. BOOL GetInAddr(LPCTSTR lpszAddress, HP_ADDR& addr)
  91. {
  92. addr.family = DetermineAddrFamily(lpszAddress);
  93. if (addr.family == AF_UNSPEC)
  94. return FALSE;
  95. return (::InetPton(addr.family, lpszAddress, addr.Addr()) == TRUE);
  96. }
  97. BOOL GetSockAddr(LPCTSTR lpszAddress, USHORT usPort, HP_SOCKADDR& addr)
  98. {
  99. if(addr.family != AF_INET && addr.family != AF_INET6)
  100. {
  101. ::WSASetLastError(ERROR_ADDRNOTAVAIL);
  102. return FALSE;
  103. }
  104. if(addr.family == AF_INET6 && StrChr(lpszAddress, IPV6_ZONE_INDEX_CHAR))
  105. return GetSockAddrByHostNameDirectly(lpszAddress, usPort, addr);
  106. addr.ZeroAddr();
  107. int rs = ::InetPton(addr.family, lpszAddress, addr.SinAddr());
  108. if(rs != 1)
  109. {
  110. if(rs == 0) ::WSASetLastError(ERROR_INVALID_PARAMETER);
  111. return FALSE;
  112. }
  113. if(usPort != 0)
  114. addr.SetPort(usPort);
  115. return TRUE;
  116. }
  117. BOOL IsIPAddress(LPCTSTR lpszAddress, EnIPAddrType* penType)
  118. {
  119. HP_ADDR addr;
  120. BOOL isOK = GetInAddr(lpszAddress, addr);
  121. if(isOK && penType)
  122. *penType = addr.IsIPv4() ? IPT_IPV4 : IPT_IPV6;
  123. return isOK;
  124. }
  125. BOOL GetIPAddress(LPCTSTR lpszHost, LPTSTR lpszIP, int& iIPLen, EnIPAddrType& enType)
  126. {
  127. HP_SOCKADDR addr;
  128. if(!GetSockAddrByHostName(lpszHost, 0, addr))
  129. return FALSE;
  130. enType = addr.IsIPv4() ? IPT_IPV4 : IPT_IPV6;
  131. USHORT usPort;
  132. ADDRESS_FAMILY usFamily;
  133. return sockaddr_IN_2_A(addr, usFamily, lpszIP, iIPLen, usPort);
  134. }
  135. BOOL GetSockAddrByHostName(LPCTSTR lpszHost, USHORT usPort, HP_SOCKADDR& addr)
  136. {
  137. addr.family = DetermineAddrFamily(lpszHost);
  138. if(addr.family != AF_UNSPEC)
  139. return GetSockAddr(lpszHost, usPort, addr);
  140. return GetSockAddrByHostNameDirectly(lpszHost, usPort, addr);
  141. }
  142. BOOL GetSockAddrByHostNameDirectly(LPCTSTR lpszHost, USHORT usPort, HP_SOCKADDR& addr)
  143. {
  144. addr.ZeroAddr();
  145. addrinfo* pInfo = nullptr;
  146. addrinfo hints = {0};
  147. #if defined(__ANDROID__)
  148. hints.ai_flags = 0;
  149. #else
  150. hints.ai_flags = (AI_V4MAPPED | AI_ADDRCONFIG);
  151. #endif
  152. hints.ai_family = addr.family;
  153. hints.ai_socktype = SOCK_STREAM;
  154. int rs = ::getaddrinfo(CT2A(lpszHost), nullptr, &hints, &pInfo);
  155. if(!IS_NO_ERROR(rs))
  156. {
  157. ::WSASetLastError(ERROR_HOSTUNREACH);
  158. return FALSE;
  159. }
  160. BOOL isOK = FALSE;
  161. for(addrinfo* pCur = pInfo; pCur != nullptr; pCur = pCur->ai_next)
  162. {
  163. if(pCur->ai_family == AF_INET || pCur->ai_family == AF_INET6)
  164. {
  165. memcpy(addr.Addr(), pCur->ai_addr, pCur->ai_addrlen);
  166. isOK = TRUE;
  167. break;
  168. }
  169. }
  170. EXECUTE_RESTORE_ERROR(::freeaddrinfo(pInfo));
  171. if(isOK)
  172. addr.SetPort(usPort);
  173. else
  174. ::WSASetLastError(ERROR_HOSTUNREACH);
  175. return isOK;
  176. }
  177. BOOL EnumHostIPAddresses(LPCTSTR lpszHost, EnIPAddrType enType, LPTIPAddr** lpppIPAddr, int& iIPAddrCount)
  178. {
  179. *lpppIPAddr = nullptr;
  180. iIPAddrCount = 0;
  181. ADDRESS_FAMILY usFamily = (enType == IPT_ALL ?
  182. AF_UNSPEC : (enType == IPT_IPV4 ?
  183. AF_INET : (enType == IPT_IPV6 ?
  184. AF_INET6 : 0xFF)));
  185. if(usFamily == 0xFF)
  186. {
  187. ::WSASetLastError(ERROR_AFNOSUPPORT);
  188. return FALSE;
  189. }
  190. vector<HP_PSOCKADDR> vt;
  191. ADDRESS_FAMILY usFamily2 = DetermineAddrFamily(lpszHost);
  192. if(usFamily2 != AF_UNSPEC)
  193. {
  194. if(usFamily != AF_UNSPEC && usFamily != usFamily2)
  195. {
  196. ::WSASetLastError(ERROR_HOSTUNREACH);
  197. return FALSE;
  198. }
  199. HP_SOCKADDR addr(usFamily2);
  200. if(!GetSockAddr(lpszHost, 0, addr))
  201. return FALSE;
  202. vt.emplace_back(&addr);
  203. return RetrieveSockAddrIPAddresses(vt, lpppIPAddr, iIPAddrCount);
  204. }
  205. addrinfo* pInfo = nullptr;
  206. addrinfo hints = {0};
  207. #if defined(__ANDROID__)
  208. hints.ai_flags = 0;
  209. #else
  210. hints.ai_flags = AI_ALL;
  211. #endif
  212. hints.ai_family = usFamily;
  213. hints.ai_socktype = SOCK_STREAM;
  214. int rs = ::getaddrinfo(CT2A(lpszHost), nullptr, &hints, &pInfo);
  215. if(rs != NO_ERROR)
  216. {
  217. ::WSASetLastError(rs);
  218. return FALSE;
  219. }
  220. for(addrinfo* pCur = pInfo; pCur != nullptr; pCur = pCur->ai_next)
  221. {
  222. if(pCur->ai_family == AF_INET || pCur->ai_family == AF_INET6)
  223. vt.emplace_back((HP_PSOCKADDR)pCur->ai_addr);
  224. }
  225. BOOL isOK = RetrieveSockAddrIPAddresses(vt, lpppIPAddr, iIPAddrCount);
  226. ::freeaddrinfo(pInfo);
  227. if(!isOK) ::WSASetLastError(EHOSTUNREACH);
  228. return isOK;
  229. }
  230. BOOL RetrieveSockAddrIPAddresses(const vector<HP_PSOCKADDR>& vt, LPTIPAddr** lpppIPAddr, int& iIPAddrCount)
  231. {
  232. iIPAddrCount = (int)vt.size();
  233. if(iIPAddrCount == 0) return FALSE;
  234. HP_PSOCKADDR pSockAddr;
  235. ADDRESS_FAMILY usFamily;
  236. USHORT usPort;
  237. int iAddrLength;
  238. LPTSTR lpszAddr;
  239. LPTIPAddr lpItem;
  240. (*lpppIPAddr) = new LPTIPAddr[iIPAddrCount + 1];
  241. (*lpppIPAddr)[iIPAddrCount] = nullptr;
  242. for(int i = 0; i < iIPAddrCount; i++)
  243. {
  244. pSockAddr = vt[i];
  245. iAddrLength = HP_SOCKADDR::AddrMinStrLength(pSockAddr->family);
  246. lpszAddr = new TCHAR[iAddrLength];
  247. VERIFY(sockaddr_IN_2_A(*vt[i], usFamily, lpszAddr, iAddrLength, usPort));
  248. lpItem = new TIPAddr;
  249. lpItem->type = pSockAddr->IsIPv4() ? IPT_IPV4 : IPT_IPV6;
  250. lpItem->address = lpszAddr;
  251. (*lpppIPAddr)[i] = lpItem;
  252. }
  253. return TRUE;
  254. }
  255. BOOL FreeHostIPAddresses(LPTIPAddr* lppIPAddr)
  256. {
  257. if(!lppIPAddr) return FALSE;
  258. LPTIPAddr p;
  259. LPTIPAddr* lppCur = lppIPAddr;
  260. while((p = *lppCur++) != nullptr)
  261. {
  262. delete[] p->address;
  263. delete p;
  264. }
  265. delete[] lppIPAddr;
  266. return TRUE;
  267. }
  268. BOOL sockaddr_IN_2_A(const HP_SOCKADDR& addr, ADDRESS_FAMILY& usFamily, LPTSTR lpszAddress, int& iAddressLen, USHORT& usPort)
  269. {
  270. BOOL isOK = FALSE;
  271. usFamily = addr.family;
  272. usPort = addr.Port();
  273. if(::InetNtop(addr.family, addr.SinAddr(), lpszAddress, iAddressLen))
  274. {
  275. iAddressLen = (int)lstrlen(lpszAddress) + 1;
  276. isOK = TRUE;
  277. }
  278. else
  279. {
  280. if(::WSAGetLastError() == ENOSPC)
  281. iAddressLen = HP_SOCKADDR::AddrMinStrLength(usFamily);
  282. }
  283. return isOK;
  284. }
  285. BOOL sockaddr_A_2_IN(LPCTSTR lpszAddress, USHORT usPort, HP_SOCKADDR& addr)
  286. {
  287. addr.family = DetermineAddrFamily(lpszAddress);
  288. return GetSockAddr(lpszAddress, usPort, addr);
  289. }
  290. BOOL GetSocketAddress(SOCKET socket, LPTSTR lpszAddress, int& iAddressLen, USHORT& usPort, BOOL bLocal)
  291. {
  292. HP_SOCKADDR addr;
  293. int addr_len = addr.AddrSize();
  294. int result = bLocal ? getsockname(socket, addr.Addr(), (socklen_t*)&addr_len) : getpeername(socket, addr.Addr(), (socklen_t*)&addr_len);
  295. if(result != NO_ERROR)
  296. return FALSE;
  297. ADDRESS_FAMILY usFamily;
  298. return sockaddr_IN_2_A(addr, usFamily, lpszAddress, iAddressLen, usPort);
  299. }
  300. BOOL GetSocketLocalAddress(SOCKET socket, LPTSTR lpszAddress, int& iAddressLen, USHORT& usPort)
  301. {
  302. return GetSocketAddress(socket, lpszAddress, iAddressLen, usPort, TRUE);
  303. }
  304. BOOL GetSocketRemoteAddress(SOCKET socket, LPTSTR lpszAddress, int& iAddressLen, USHORT& usPort)
  305. {
  306. return GetSocketAddress(socket, lpszAddress, iAddressLen, usPort, FALSE);
  307. }
  308. BOOL SetMultiCastSocketOptions(SOCKET sock, const HP_SOCKADDR& bindAddr, const HP_SOCKADDR& castAddr, int iMCTtl, BOOL bMCLoop)
  309. {
  310. if(castAddr.IsIPv4())
  311. {
  312. BYTE ttl = (BYTE)iMCTtl;
  313. BYTE loop = (BYTE)bMCLoop;
  314. VERIFY(::SSO_SetSocketOption(sock, IPPROTO_IP, IP_MULTICAST_TTL, &ttl, sizeof(ttl)) != SOCKET_ERROR);
  315. VERIFY(::SSO_SetSocketOption(sock, IPPROTO_IP, IP_MULTICAST_LOOP, &loop, sizeof(loop)) != SOCKET_ERROR);
  316. ip_mreq mcast;
  317. ::ZeroMemory(&mcast, sizeof(mcast));
  318. mcast.imr_multiaddr = castAddr.addr4.sin_addr;
  319. mcast.imr_interface = bindAddr.addr4.sin_addr;
  320. if(::SSO_SetSocketOption(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mcast, sizeof(mcast)) == SOCKET_ERROR)
  321. return FALSE;
  322. if(::SSO_SetSocketOption(sock, IPPROTO_IP, IP_MULTICAST_IF, bindAddr.SinAddr(), sizeof(IN_ADDR)) == SOCKET_ERROR)
  323. return FALSE;
  324. }
  325. else
  326. {
  327. INT ttl = (INT)iMCTtl;
  328. UINT loop = (UINT)bMCLoop;
  329. VERIFY(::SSO_SetSocketOption(sock, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &ttl, sizeof(ttl)) != SOCKET_ERROR);
  330. VERIFY(::SSO_SetSocketOption(sock, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &loop, sizeof(loop)) != SOCKET_ERROR);
  331. ipv6_mreq mcast;
  332. ::ZeroMemory(&mcast, sizeof(mcast));
  333. mcast.ipv6mr_multiaddr = castAddr.addr6.sin6_addr;
  334. mcast.ipv6mr_interface = bindAddr.addr6.sin6_scope_id;
  335. if(::SSO_SetSocketOption(sock, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, &mcast, sizeof(mcast)) == SOCKET_ERROR)
  336. return FALSE;
  337. if(::SSO_SetSocketOption(sock, IPPROTO_IPV6, IPV6_MULTICAST_IF, (PVOID)(&bindAddr.addr6.sin6_scope_id), sizeof(UINT)) == SOCKET_ERROR)
  338. return FALSE;
  339. }
  340. return TRUE;
  341. }
  342. int WaitForSocketWrite(SOCKET sock, DWORD dwTimeout)
  343. {
  344. timeval tv = {(__time_t)(dwTimeout / 1000), (__suseconds_t)((dwTimeout % 1000) * 1000)};
  345. fd_set wfds, efds;
  346. FD_ZERO(&wfds);
  347. FD_ZERO(&efds);
  348. FD_SET(sock, &wfds);
  349. FD_SET(sock, &efds);
  350. int rs = NO_EINTR_INT(select(sock + 1, nullptr, &wfds, &efds, &tv));
  351. if(rs <= 0) return ((rs == 0) ? ERROR_TIMEOUT : ENSURE_ERROR(ERROR_CANT_WAIT));
  352. if(FD_ISSET(sock, &efds))
  353. {
  354. rs = SSO_GetError(sock);
  355. return ((rs != NO_ERROR && rs != SOCKET_ERROR) ? rs : ENSURE_ERROR(ERROR_CANT_WAIT));
  356. }
  357. VERIFY(FD_ISSET(sock, &wfds));
  358. rs = SSO_GetError(sock);
  359. if(!IS_NO_ERROR(rs))
  360. return ((rs != SOCKET_ERROR) ? rs : ENSURE_ERROR(ERROR_CANT_WAIT));
  361. return NO_ERROR;
  362. }
  363. ULONGLONG NToH64(ULONGLONG value)
  364. {
  365. return (((ULONGLONG)ntohl((UINT)((value << 32) >> 32))) << 32) | ntohl((UINT)(value >> 32));
  366. }
  367. ULONGLONG HToN64(ULONGLONG value)
  368. {
  369. return (((ULONGLONG)htonl((UINT)((value << 32) >> 32))) << 32) | htonl((UINT)(value >> 32));
  370. }
  371. BOOL IsLittleEndian()
  372. {
  373. static const USHORT _s_endian_test_value = 0x0102;
  374. static const BOOL _s_bLE = (*((BYTE*)&_s_endian_test_value) == 0x02);
  375. return _s_bLE;
  376. }
  377. USHORT HToLE16(USHORT value)
  378. {
  379. return IsLittleEndian() ? value : ENDIAN_SWAP_16(value);
  380. }
  381. USHORT HToBE16(USHORT value)
  382. {
  383. return IsLittleEndian() ? ENDIAN_SWAP_16(value) : value;
  384. }
  385. DWORD HToLE32(DWORD value)
  386. {
  387. return IsLittleEndian() ? value : ENDIAN_SWAP_32(value);
  388. }
  389. DWORD HToBE32(DWORD value)
  390. {
  391. return IsLittleEndian() ? ENDIAN_SWAP_32(value) : value;
  392. }
  393. HRESULT ReadSmallFile(LPCTSTR lpszFileName, CFile& file, CFileMapping& fmap, DWORD dwMaxFileSize)
  394. {
  395. ASSERT(lpszFileName != nullptr);
  396. if(file.Open(lpszFileName, O_RDONLY))
  397. {
  398. SIZE_T dwSize;
  399. if(file.GetSize(dwSize))
  400. {
  401. if(dwSize > 0 && dwSize <= dwMaxFileSize)
  402. {
  403. if(fmap.Map(file, dwSize))
  404. return NO_ERROR;
  405. }
  406. else if(dwSize == 0)
  407. ::SetLastError(ERROR_EMPTY);
  408. else
  409. ::SetLastError(ERROR_FILE_TOO_LARGE);
  410. }
  411. }
  412. HRESULT rs = ::GetLastError();
  413. return (!IS_NO_ERROR(rs) ? rs : ERROR_UNKNOWN);
  414. }
  415. HRESULT MakeSmallFilePackage(LPCTSTR lpszFileName, CFile& file, CFileMapping& fmap, WSABUF szBuf[3], const LPWSABUF pHead, const LPWSABUF pTail)
  416. {
  417. DWORD dwMaxFileSize = MAX_SMALL_FILE_SIZE - (pHead ? pHead->len : 0) - (pTail ? pTail->len : 0);
  418. ASSERT(dwMaxFileSize <= MAX_SMALL_FILE_SIZE);
  419. HRESULT hr = ReadSmallFile(lpszFileName, file, fmap, dwMaxFileSize);
  420. if(IS_NO_ERROR(hr))
  421. {
  422. szBuf[1].len = (UINT)fmap.Size();
  423. szBuf[1].buf = fmap;
  424. if(pHead) memcpy(&szBuf[0], pHead, sizeof(WSABUF));
  425. else memset(&szBuf[0], 0, sizeof(WSABUF));
  426. if(pTail) memcpy(&szBuf[2], pTail, sizeof(WSABUF));
  427. else memset(&szBuf[2], 0, sizeof(WSABUF));
  428. }
  429. return hr;
  430. }
  431. ///////////////////////////////////////////////////////////////////////////////////////////////////////
  432. int SSO_SetSocketOption(SOCKET sock, int level, int name, LPVOID val, int len)
  433. {
  434. return setsockopt(sock, level, name, val, (socklen_t)len);
  435. }
  436. int SSO_GetSocketOption(SOCKET sock, int level, int name, LPVOID val, int* len)
  437. {
  438. return getsockopt(sock, level, name, val, (socklen_t*)len);
  439. }
  440. int SSO_IoctlSocket(SOCKET sock, long cmd, PVOID arg)
  441. {
  442. return ioctl(sock, cmd, arg);
  443. }
  444. int SSO_NoBlock(SOCKET sock, BOOL bNoBlock)
  445. {
  446. return fcntl_SETFL(sock, O_NONBLOCK, bNoBlock) ? NO_ERROR : SOCKET_ERROR;
  447. }
  448. int SSO_NoDelay(SOCKET sock, BOOL bNoDelay)
  449. {
  450. int val = bNoDelay ? 1 : 0;
  451. return setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, &val, sizeof(int));
  452. }
  453. int SSO_DontLinger(SOCKET sock, BOOL bDont)
  454. {
  455. return SSO_Linger(sock, 0, 0);
  456. }
  457. int SSO_Linger(SOCKET sock, int l_onoff, int l_linger)
  458. {
  459. linger ln = {l_onoff, l_linger};
  460. return setsockopt(sock, SOL_SOCKET, SO_LINGER, &ln, sizeof(linger));
  461. }
  462. int SSO_KeepAlive(SOCKET sock, BOOL bKeepAlive)
  463. {
  464. int val = bKeepAlive ? 1 : 0;
  465. return setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, &val, sizeof(int));
  466. }
  467. int SSO_KeepAliveVals(SOCKET sock, BOOL bOnOff, DWORD dwIdle, DWORD dwInterval, DWORD dwCount)
  468. {
  469. if(bOnOff)
  470. {
  471. dwIdle /= 1000;
  472. dwInterval /= 1000;
  473. if(dwIdle == 0 || dwInterval == 0 || dwCount == 0)
  474. {
  475. ::WSASetLastError(ERROR_INVALID_PARAMETER);
  476. return SOCKET_ERROR;
  477. }
  478. }
  479. BOOL isOK = IS_NO_ERROR(SSO_KeepAlive(sock, bOnOff));
  480. if(isOK && bOnOff)
  481. {
  482. isOK &= IS_NO_ERROR(setsockopt(sock, SOL_TCP, TCP_KEEPIDLE, &dwIdle, sizeof(DWORD)));
  483. isOK &= IS_NO_ERROR(setsockopt(sock, SOL_TCP, TCP_KEEPINTVL, &dwInterval, sizeof(DWORD)));
  484. isOK &= IS_NO_ERROR(setsockopt(sock, SOL_TCP, TCP_KEEPCNT, &dwCount, sizeof(DWORD)));
  485. }
  486. return isOK ? NO_ERROR : SOCKET_ERROR;
  487. }
  488. int SSO_ReuseAddress(SOCKET sock, EnReuseAddressPolicy opt)
  489. {
  490. int iSet = 1;
  491. int iUnSet = 0;
  492. int rs = NO_ERROR;
  493. BOOL bReusePortSupported =
  494. #if defined(__linux) || defined(__linux__)
  495. ::IsKernelVersionAbove(2, 6, 32);
  496. #elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__bsdi__) || defined(__APPLE__) || defined(__MACH__)
  497. TRUE;
  498. #else
  499. FALSE;
  500. #endif
  501. if(opt == RAP_NONE)
  502. {
  503. rs = setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &iUnSet, sizeof(int));
  504. if(bReusePortSupported)
  505. rs |= setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, &iUnSet, sizeof(int));
  506. }
  507. else if(opt == RAP_ADDR_ONLY)
  508. {
  509. rs = setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &iSet, sizeof(int));
  510. if(bReusePortSupported)
  511. rs |= setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, &iUnSet, sizeof(int));
  512. }
  513. else if(opt == RAP_ADDR_AND_PORT)
  514. {
  515. rs = setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &iSet, sizeof(int));
  516. if(bReusePortSupported)
  517. rs |= setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, &iSet, sizeof(int));
  518. }
  519. else
  520. {
  521. ::SetLastError(ERROR_INVALID_PARAMETER);
  522. rs = -1;
  523. }
  524. return rs;
  525. }
  526. int SSO_RecvBuffSize(SOCKET sock, int size)
  527. {
  528. return setsockopt(sock, SOL_SOCKET, SO_RCVBUF, &size, sizeof(int));
  529. }
  530. int SSO_SendBuffSize(SOCKET sock, int size)
  531. {
  532. return setsockopt(sock, SOL_SOCKET, SO_SNDBUF, &size, sizeof(int));
  533. }
  534. int SSO_RecvTimeOut(SOCKET sock, int ms)
  535. {
  536. timeval tv;
  537. ::MillisecondToTimeval(ms, tv);
  538. return setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(timeval));
  539. }
  540. int SSO_SendTimeOut(SOCKET sock, int ms)
  541. {
  542. timeval tv;
  543. ::MillisecondToTimeval(ms, tv);
  544. return setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(timeval));
  545. }
  546. int SSO_GetError(SOCKET sock)
  547. {
  548. int e;
  549. socklen_t len = sizeof(e);
  550. if(IS_NO_ERROR(getsockopt(sock, SOL_SOCKET, SO_ERROR, &e, &len)))
  551. return e;
  552. return SOCKET_ERROR;
  553. }
  554. ///////////////////////////////////////////////////////////////////////////////////////////////////////
  555. CONNID GenerateConnectionID()
  556. {
  557. static volatile CONNID s_dwConnID = 0;
  558. CONNID dwConnID = ::InterlockedIncrement(&s_dwConnID);
  559. if(dwConnID == 0)
  560. dwConnID = ::InterlockedIncrement(&s_dwConnID);
  561. return dwConnID;
  562. }
  563. int IsUdpCloseNotify(const BYTE* pData, int iLength)
  564. {
  565. return (iLength == s_iUdpCloseNotifySize &&
  566. memcmp(pData, s_szUdpCloseNotify, s_iUdpCloseNotifySize) == 0) ;
  567. }
  568. int SendUdpCloseNotify(SOCKET sock)
  569. {
  570. return (int)send(sock, (LPCSTR)s_szUdpCloseNotify, s_iUdpCloseNotifySize, 0);
  571. }
  572. int SendUdpCloseNotify(SOCKET sock, const HP_SOCKADDR& remoteAddr)
  573. {
  574. return (int)sendto(sock, (LPCSTR)s_szUdpCloseNotify, s_iUdpCloseNotifySize, 0, remoteAddr.Addr(), remoteAddr.AddrSize());
  575. }
  576. int ManualCloseSocket(SOCKET sock, int iShutdownFlag, BOOL bGraceful)
  577. {
  578. if(!bGraceful)
  579. SSO_Linger(sock, 1, 0);
  580. if(iShutdownFlag != 0xFF)
  581. shutdown(sock, iShutdownFlag);
  582. return closesocket(sock);
  583. }
  584. DWORD GuessBase64EncodeBound(DWORD dwSrcLen)
  585. {
  586. return 4 * ((dwSrcLen + 2) / 3);
  587. }
  588. DWORD GuessBase64DecodeBound(const BYTE* lpszSrc, DWORD dwSrcLen)
  589. {
  590. if(dwSrcLen < 2)
  591. return 0;
  592. if(lpszSrc[dwSrcLen - 2] == '=')
  593. dwSrcLen -= 2;
  594. else if(lpszSrc[dwSrcLen - 1] == '=')
  595. --dwSrcLen;
  596. DWORD dwMod = dwSrcLen % 4;
  597. DWORD dwAdd = dwMod == 2 ? 1 : (dwMod == 3 ? 2 : 0);
  598. return 3 * (dwSrcLen / 4) + dwAdd;
  599. }
  600. int Base64Encode(const BYTE* lpszSrc, DWORD dwSrcLen, BYTE* lpszDest, DWORD& dwDestLen)
  601. {
  602. static const BYTE CODES[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
  603. DWORD dwRealLen = GuessBase64EncodeBound(dwSrcLen);
  604. if(lpszDest == nullptr || dwDestLen < dwRealLen)
  605. {
  606. dwDestLen = dwRealLen;
  607. return -5;
  608. }
  609. BYTE* p = lpszDest;
  610. DWORD leven = 3 * (dwSrcLen / 3);
  611. DWORD i = 0;
  612. for (; i < leven; i += 3)
  613. {
  614. *p++ = CODES[lpszSrc[0] >> 2];
  615. *p++ = CODES[((lpszSrc[0] & 3) << 4) + (lpszSrc[1] >> 4)];
  616. *p++ = CODES[((lpszSrc[1] & 0xf) << 2) + (lpszSrc[2] >> 6)];
  617. *p++ = CODES[lpszSrc[2] & 0x3f];
  618. lpszSrc += 3;
  619. }
  620. if(i < dwSrcLen)
  621. {
  622. BYTE a = lpszSrc[0];
  623. BYTE b = (i + 1 < dwSrcLen) ? lpszSrc[1] : 0;
  624. *p++ = CODES[a >> 2];
  625. *p++ = CODES[((a & 3) << 4) + (b >> 4)];
  626. *p++ = (i + 1 < dwSrcLen) ? CODES[((b & 0xf) << 2)] : '=';
  627. *p++ = '=';
  628. }
  629. ASSERT(dwRealLen == (DWORD)(p - lpszDest));
  630. if(dwDestLen > dwRealLen)
  631. {
  632. *p = 0;
  633. dwDestLen = dwRealLen;
  634. }
  635. return 0;
  636. }
  637. int Base64Decode(const BYTE* lpszSrc, DWORD dwSrcLen, BYTE* lpszDest, DWORD& dwDestLen)
  638. {
  639. static const BYTE MAP[256] =
  640. {
  641. 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 253, 255,
  642. 255, 253, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
  643. 255, 255, 255, 255, 255, 255, 255, 255, 253, 255, 255, 255,
  644. 255, 255, 255, 255, 255, 255, 255, 62, 255, 255, 255, 63,
  645. 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 255, 255,
  646. 255, 254, 255, 255, 255, 0, 1, 2, 3, 4, 5, 6,
  647. 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
  648. 19, 20, 21, 22, 23, 24, 25, 255, 255, 255, 255, 255,
  649. 255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
  650. 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
  651. 49, 50, 51, 255, 255, 255, 255, 255, 255, 255, 255, 255,
  652. 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
  653. 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
  654. 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
  655. 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
  656. 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
  657. 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
  658. 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
  659. 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
  660. 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
  661. 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
  662. 255, 255, 255, 255
  663. };
  664. DWORD dwRealLen = GuessBase64DecodeBound(lpszSrc, dwSrcLen);
  665. if(lpszDest == nullptr || dwDestLen < dwRealLen)
  666. {
  667. dwDestLen = dwRealLen;
  668. return -5;
  669. }
  670. BYTE c;
  671. int g = 3;
  672. DWORD i, x, y, z;
  673. for(i = x = y = z = 0; i < dwSrcLen || x != 0;)
  674. {
  675. c = i < dwSrcLen ? MAP[lpszSrc[i++]] : 254;
  676. if(c == 255) {dwDestLen = 0; return -3;}
  677. else if(c == 254) {c = 0; g--;}
  678. else if(c == 253) continue;
  679. z = (z << 6) | c;
  680. if(++x == 4)
  681. {
  682. lpszDest[y++] = (BYTE)((z >> 16) & 255);
  683. if (g > 1) lpszDest[y++] = (BYTE)((z >> 8) & 255);
  684. if (g > 2) lpszDest[y++] = (BYTE)(z & 255);
  685. x = z = 0;
  686. }
  687. }
  688. BOOL isOK = (y == dwRealLen);
  689. if(!isOK)
  690. dwDestLen = 0;
  691. else
  692. {
  693. if(dwDestLen > dwRealLen)
  694. {
  695. lpszDest[dwRealLen] = 0;
  696. dwDestLen = dwRealLen;
  697. }
  698. }
  699. return isOK ? 0 : -3;
  700. }
  701. DWORD GuessUrlEncodeBound(const BYTE* lpszSrc, DWORD dwSrcLen)
  702. {
  703. DWORD dwAdd = 0;
  704. for(DWORD i = 0; i < dwSrcLen; i++)
  705. {
  706. BYTE c = lpszSrc[i];
  707. if(!(isalnum(c) || c == ' ' || c == '.' || c == '-' || c == '_' || c == '*'))
  708. dwAdd += 2;
  709. }
  710. return dwSrcLen + dwAdd;
  711. }
  712. DWORD GuessUrlDecodeBound(const BYTE* lpszSrc, DWORD dwSrcLen)
  713. {
  714. DWORD dwPercent = 0;
  715. for(DWORD i = 0; i < dwSrcLen; i++)
  716. {
  717. if(lpszSrc[i] == '%')
  718. {
  719. ++dwPercent;
  720. i += 2;
  721. }
  722. }
  723. DWORD dwSub = dwPercent * 2;
  724. if(dwSrcLen < dwSub)
  725. return 0;
  726. return dwSrcLen - dwSub;
  727. }
  728. int UrlEncode(BYTE* lpszSrc, DWORD dwSrcLen, BYTE* lpszDest, DWORD& dwDestLen)
  729. {
  730. BYTE c;
  731. DWORD j = 0;
  732. if(lpszDest == nullptr || dwDestLen == 0)
  733. goto ERROR_DEST_LEN;
  734. for(DWORD i = 0; i < dwSrcLen; i++)
  735. {
  736. if(j >= dwDestLen)
  737. goto ERROR_DEST_LEN;
  738. c = lpszSrc[i];
  739. if (isalnum(c) || c == '.' || c == '-' || c == '_' || c == '*')
  740. lpszDest[j++] = c;
  741. else if(c == ' ')
  742. lpszDest[j++] = '+';
  743. else
  744. {
  745. if(j + 3 >= dwDestLen)
  746. goto ERROR_DEST_LEN;
  747. lpszDest[j++] = '%';
  748. HEX_VALUE_TO_DOUBLE_CHAR(lpszDest + j, c);
  749. j += 2;
  750. }
  751. }
  752. if(dwDestLen > j)
  753. {
  754. lpszDest[j] = 0;
  755. dwDestLen = j;
  756. }
  757. return 0;
  758. ERROR_DEST_LEN:
  759. dwDestLen = GuessUrlEncodeBound(lpszSrc, dwSrcLen);
  760. return -5;
  761. }
  762. int UrlDecode(BYTE* lpszSrc, DWORD dwSrcLen, BYTE* lpszDest, DWORD& dwDestLen)
  763. {
  764. char c;
  765. DWORD j = 0;
  766. if(lpszDest == nullptr || dwDestLen == 0)
  767. goto ERROR_DEST_LEN;
  768. for(DWORD i = 0; i < dwSrcLen; i++)
  769. {
  770. if(j >= dwDestLen)
  771. goto ERROR_DEST_LEN;
  772. c = lpszSrc[i];
  773. if(c == '+')
  774. lpszDest[j++] = ' ';
  775. else if(c != '%')
  776. lpszDest[j++] = c;
  777. else
  778. {
  779. if(i + 2 >= dwSrcLen)
  780. goto ERROR_SRC_DATA;
  781. lpszDest[j++] = HEX_DOUBLE_CHAR_TO_VALUE(lpszSrc + i + 1);
  782. i += 2;
  783. }
  784. }
  785. if(dwDestLen > j)
  786. {
  787. lpszDest[j] = 0;
  788. dwDestLen = j;
  789. }
  790. return 0;
  791. ERROR_SRC_DATA:
  792. dwDestLen = 0;
  793. return -3;
  794. ERROR_DEST_LEN:
  795. dwDestLen = GuessUrlDecodeBound(lpszSrc, dwSrcLen);
  796. return -5;
  797. }
  798. void DestroyCompressor(IHPCompressor* pCompressor)
  799. {
  800. delete pCompressor;
  801. }
  802. void DestroyDecompressor(IHPDecompressor* pDecompressor)
  803. {
  804. delete pDecompressor;
  805. }
  806. #ifdef _ZLIB_SUPPORT
  807. CHPZLibCompressor::CHPZLibCompressor(Fn_CompressDataCallback fnCallback, int iWindowBits, int iLevel, int iMethod, int iMemLevel, int iStrategy, DWORD dwBuffSize)
  808. : m_fnCallback (fnCallback)
  809. , m_dwBuffSize (dwBuffSize)
  810. , m_bValid (FALSE)
  811. {
  812. ASSERT(m_fnCallback != nullptr);
  813. ::ZeroObject(m_Stream);
  814. m_bValid = (::deflateInit2(&m_Stream, iLevel, iMethod, iWindowBits, iMemLevel, iStrategy) == Z_OK);
  815. }
  816. CHPZLibCompressor::~CHPZLibCompressor()
  817. {
  818. if(m_bValid) ::deflateEnd(&m_Stream);
  819. }
  820. BOOL CHPZLibCompressor::Reset()
  821. {
  822. return (m_bValid = (::deflateReset(&m_Stream) == Z_OK));
  823. }
  824. BOOL CHPZLibCompressor::Process(const BYTE* pData, int iLength, BOOL bLast, PVOID pContext)
  825. {
  826. return ProcessEx(pData, iLength, bLast, FALSE, pContext);
  827. }
  828. BOOL CHPZLibCompressor::ProcessEx(const BYTE* pData, int iLength, BOOL bLast, BOOL bFlush, PVOID pContext)
  829. {
  830. ASSERT(IsValid() && iLength > 0);
  831. if(!IsValid())
  832. {
  833. ::SetLastError(ERROR_INVALID_STATE);
  834. return FALSE;
  835. }
  836. unique_ptr<BYTE[]> szBuff = make_unique<BYTE[]>(m_dwBuffSize);
  837. m_Stream.next_in = (z_const Bytef*)pData;
  838. m_Stream.avail_in = iLength;
  839. BOOL isOK = TRUE;
  840. int rs = Z_OK;
  841. int flush = bLast ? Z_FINISH : (bFlush ? Z_SYNC_FLUSH : Z_NO_FLUSH);
  842. while(m_Stream.avail_in > 0)
  843. {
  844. do
  845. {
  846. m_Stream.next_out = szBuff.get();
  847. m_Stream.avail_out = m_dwBuffSize;
  848. rs = ::deflate(&m_Stream, flush);
  849. if(rs == Z_STREAM_ERROR)
  850. {
  851. ::SetLastError(ERROR_INVALID_DATA);
  852. isOK = FALSE;
  853. goto ZLIB_COMPRESS_END;
  854. }
  855. int iRead = (int)(m_dwBuffSize - m_Stream.avail_out);
  856. if(iRead == 0)
  857. break;
  858. if(!m_fnCallback(szBuff.get(), iRead, pContext))
  859. {
  860. ::SetLastError(ERROR_CANCELLED);
  861. isOK = FALSE;
  862. goto ZLIB_COMPRESS_END;
  863. }
  864. } while(m_Stream.avail_out == 0);
  865. }
  866. ZLIB_COMPRESS_END:
  867. ASSERT(!isOK || (rs == Z_OK && !bLast) || (rs == Z_STREAM_END && bLast));
  868. if(!isOK || bLast) Reset();
  869. return isOK;
  870. }
  871. CHPZLibDecompressor::CHPZLibDecompressor(Fn_DecompressDataCallback fnCallback, int iWindowBits, DWORD dwBuffSize)
  872. : m_fnCallback (fnCallback)
  873. , m_dwBuffSize (dwBuffSize)
  874. , m_bValid (FALSE)
  875. {
  876. ASSERT(m_fnCallback != nullptr);
  877. ::ZeroObject(m_Stream);
  878. m_bValid = (::inflateInit2(&m_Stream, iWindowBits) == Z_OK);
  879. }
  880. CHPZLibDecompressor::~CHPZLibDecompressor()
  881. {
  882. if(m_bValid) ::inflateEnd(&m_Stream);
  883. }
  884. BOOL CHPZLibDecompressor::Reset()
  885. {
  886. return (m_bValid = (::inflateReset(&m_Stream) == Z_OK));
  887. }
  888. BOOL CHPZLibDecompressor::Process(const BYTE* pData, int iLength, PVOID pContext)
  889. {
  890. ASSERT(IsValid() && iLength > 0);
  891. if(!IsValid())
  892. {
  893. ::SetLastError(ERROR_INVALID_STATE);
  894. return FALSE;
  895. }
  896. unique_ptr<BYTE[]> szBuff = make_unique<BYTE[]>(m_dwBuffSize);
  897. m_Stream.next_in = (z_const Bytef*)pData;
  898. m_Stream.avail_in = iLength;
  899. BOOL isOK = TRUE;
  900. int rs = Z_OK;
  901. while(m_Stream.avail_in > 0)
  902. {
  903. do
  904. {
  905. m_Stream.next_out = szBuff.get();
  906. m_Stream.avail_out = m_dwBuffSize;
  907. rs = ::inflate(&m_Stream, Z_NO_FLUSH);
  908. if(rs != Z_OK && rs != Z_STREAM_END)
  909. {
  910. ::SetLastError(ERROR_INVALID_DATA);
  911. isOK = FALSE;
  912. goto ZLIB_DECOMPRESS_END;
  913. }
  914. int iRead = (int)(m_dwBuffSize - m_Stream.avail_out);
  915. if(iRead == 0)
  916. break;
  917. if(!m_fnCallback(szBuff.get(), iRead, pContext))
  918. {
  919. ::SetLastError(ERROR_CANCELLED);
  920. isOK = FALSE;
  921. goto ZLIB_DECOMPRESS_END;
  922. }
  923. } while(m_Stream.avail_out == 0);
  924. if(rs == Z_STREAM_END)
  925. break;
  926. }
  927. ZLIB_DECOMPRESS_END:
  928. ASSERT(!isOK || rs == Z_OK || rs == Z_STREAM_END);
  929. if(!isOK || rs == Z_STREAM_END) Reset();
  930. return isOK;
  931. }
  932. IHPCompressor* CreateZLibCompressor(Fn_CompressDataCallback fnCallback, int iWindowBits, int iLevel, int iMethod, int iMemLevel, int iStrategy, DWORD dwBuffSize)
  933. {
  934. return new CHPZLibCompressor(fnCallback, iWindowBits, iLevel, iMethod, iMemLevel, iStrategy, dwBuffSize);
  935. }
  936. IHPCompressor* CreateGZipCompressor(Fn_CompressDataCallback fnCallback, int iLevel, int iMethod, int iMemLevel, int iStrategy, DWORD dwBuffSize)
  937. {
  938. return new CHPZLibCompressor(fnCallback, MAX_WBITS + 16, iLevel, iMethod, iMemLevel, iStrategy, dwBuffSize);
  939. }
  940. IHPDecompressor* CreateZLibDecompressor(Fn_DecompressDataCallback fnCallback, int iWindowBits, DWORD dwBuffSize)
  941. {
  942. return new CHPZLibDecompressor(fnCallback, iWindowBits, dwBuffSize);
  943. }
  944. IHPDecompressor* CreateGZipDecompressor(Fn_DecompressDataCallback fnCallback, DWORD dwBuffSize)
  945. {
  946. return new CHPZLibDecompressor(fnCallback, MAX_WBITS + 32, dwBuffSize);
  947. }
  948. int Compress(const BYTE* lpszSrc, DWORD dwSrcLen, BYTE* lpszDest, DWORD& dwDestLen)
  949. {
  950. return CompressEx(lpszSrc, dwSrcLen, lpszDest, dwDestLen);
  951. }
  952. int CompressEx(const BYTE* lpszSrc, DWORD dwSrcLen, BYTE* lpszDest, DWORD& dwDestLen, int iLevel, int iMethod, int iWindowBits, int iMemLevel, int iStrategy)
  953. {
  954. z_stream stream;
  955. stream.next_in = (z_const Bytef*)lpszSrc;
  956. stream.avail_in = dwSrcLen;
  957. stream.next_out = lpszDest;
  958. stream.avail_out = dwDestLen;
  959. stream.zalloc = nullptr;
  960. stream.zfree = nullptr;
  961. stream.opaque = nullptr;
  962. int err = ::deflateInit2(&stream, iLevel, iMethod, iWindowBits, iMemLevel, iStrategy);
  963. if(err != Z_OK) return err;
  964. err = ::deflate(&stream, Z_FINISH);
  965. if(err != Z_STREAM_END)
  966. {
  967. ::deflateEnd(&stream);
  968. return err == Z_OK ? Z_BUF_ERROR : err;
  969. }
  970. if(dwDestLen > stream.total_out)
  971. {
  972. lpszDest[stream.total_out] = 0;
  973. dwDestLen = (DWORD)stream.total_out;
  974. }
  975. return ::deflateEnd(&stream);
  976. }
  977. int Uncompress(const BYTE* lpszSrc, DWORD dwSrcLen, BYTE* lpszDest, DWORD& dwDestLen)
  978. {
  979. return UncompressEx(lpszSrc, dwSrcLen, lpszDest, dwDestLen);
  980. }
  981. int UncompressEx(const BYTE* lpszSrc, DWORD dwSrcLen, BYTE* lpszDest, DWORD& dwDestLen, int iWindowBits)
  982. {
  983. z_stream stream;
  984. stream.next_in = (z_const Bytef*)lpszSrc;
  985. stream.avail_in = (uInt)dwSrcLen;
  986. stream.next_out = lpszDest;
  987. stream.avail_out = dwDestLen;
  988. stream.zalloc = nullptr;
  989. stream.zfree = nullptr;
  990. int err = ::inflateInit2(&stream, iWindowBits);
  991. if(err != Z_OK) return err;
  992. err = ::inflate(&stream, Z_FINISH);
  993. if(err != Z_STREAM_END)
  994. {
  995. ::inflateEnd(&stream);
  996. return (err == Z_NEED_DICT || (err == Z_BUF_ERROR && stream.avail_in == 0)) ? Z_DATA_ERROR : err;
  997. }
  998. if(dwDestLen > stream.total_out)
  999. {
  1000. lpszDest[stream.total_out] = 0;
  1001. dwDestLen = (DWORD)stream.total_out;
  1002. }
  1003. return inflateEnd(&stream);
  1004. }
  1005. DWORD GuessCompressBound(DWORD dwSrcLen, BOOL bGZip)
  1006. {
  1007. DWORD dwBound = (DWORD)::compressBound(dwSrcLen);
  1008. if(bGZip) dwBound += 16;
  1009. return dwBound;
  1010. }
  1011. int GZipCompress(const BYTE* lpszSrc, DWORD dwSrcLen, BYTE* lpszDest, DWORD& dwDestLen)
  1012. {
  1013. return CompressEx(lpszSrc, dwSrcLen, lpszDest, dwDestLen, Z_DEFAULT_COMPRESSION, Z_DEFLATED, MAX_WBITS + 16);
  1014. }
  1015. int GZipUncompress(const BYTE* lpszSrc, DWORD dwSrcLen, BYTE* lpszDest, DWORD& dwDestLen)
  1016. {
  1017. return UncompressEx(lpszSrc, dwSrcLen, lpszDest, dwDestLen, MAX_WBITS + 32);
  1018. }
  1019. DWORD GZipGuessUncompressBound(const BYTE* lpszSrc, DWORD dwSrcLen)
  1020. {
  1021. if(dwSrcLen < 20 || *(USHORT*)lpszSrc != 0x8B1F)
  1022. return 0;
  1023. return *(DWORD*)(lpszSrc + dwSrcLen - 4);
  1024. }
  1025. #endif
  1026. #ifdef _BROTLI_SUPPORT
  1027. CHPBrotliCompressor::CHPBrotliCompressor(Fn_CompressDataCallback fnCallback, int iQuality, int iWindow, int iMode, DWORD dwBuffSize)
  1028. : m_fnCallback (fnCallback)
  1029. , m_iQuality (iQuality)
  1030. , m_iWindow (iWindow)
  1031. , m_iMode (iMode)
  1032. , m_dwBuffSize (dwBuffSize)
  1033. , m_bValid (FALSE)
  1034. {
  1035. ASSERT(m_fnCallback != nullptr);
  1036. Reset();
  1037. }
  1038. CHPBrotliCompressor::~CHPBrotliCompressor()
  1039. {
  1040. if(m_bValid) ::BrotliEncoderDestroyInstance(m_pState);
  1041. }
  1042. BOOL CHPBrotliCompressor::Reset()
  1043. {
  1044. if(m_bValid) ::BrotliEncoderDestroyInstance(m_pState);
  1045. m_pState = ::BrotliEncoderCreateInstance(nullptr, nullptr, nullptr);
  1046. if(m_pState != nullptr)
  1047. {
  1048. ::BrotliEncoderSetParameter(m_pState, BROTLI_PARAM_QUALITY , (UINT)m_iQuality);
  1049. ::BrotliEncoderSetParameter(m_pState, BROTLI_PARAM_LGWIN , (UINT)m_iWindow);
  1050. ::BrotliEncoderSetParameter(m_pState, BROTLI_PARAM_MODE , (UINT)m_iMode);
  1051. if (m_iWindow > BROTLI_MAX_WINDOW_BITS)
  1052. ::BrotliEncoderSetParameter(m_pState, BROTLI_PARAM_LARGE_WINDOW, BROTLI_TRUE);
  1053. }
  1054. return (m_bValid = (m_pState != nullptr));
  1055. }
  1056. BOOL CHPBrotliCompressor::Process(const BYTE* pData, int iLength, BOOL bLast, PVOID pContext)
  1057. {
  1058. return ProcessEx(pData, iLength, bLast, FALSE, pContext);
  1059. }
  1060. BOOL CHPBrotliCompressor::ProcessEx(const BYTE* pData, int iLength, BOOL bLast, BOOL bFlush, PVOID pContext)
  1061. {
  1062. ASSERT(IsValid() && iLength > 0);
  1063. if(!IsValid())
  1064. {
  1065. ::SetLastError(ERROR_INVALID_STATE);
  1066. return FALSE;
  1067. }
  1068. unique_ptr<BYTE[]> szBuff = make_unique<BYTE[]>(m_dwBuffSize);
  1069. const BYTE* pNextInData = pData;
  1070. size_t iAvlInLen = (SIZE_T)iLength;
  1071. BYTE* pNextOutData = nullptr;
  1072. size_t iAvlOutLen = 0;
  1073. BOOL isOK = TRUE;
  1074. BrotliEncoderOperation op = bLast ? BROTLI_OPERATION_FINISH : (bFlush ? BROTLI_OPERATION_FLUSH : BROTLI_OPERATION_PROCESS);
  1075. while(iAvlInLen > 0)
  1076. {
  1077. do
  1078. {
  1079. pNextOutData = szBuff.get();
  1080. iAvlOutLen = m_dwBuffSize;
  1081. if(!::BrotliEncoderCompressStream(m_pState, op, &iAvlInLen, &pNextInData, &iAvlOutLen, &pNextOutData, nullptr))
  1082. {
  1083. ::SetLastError(ERROR_INVALID_DATA);
  1084. isOK = FALSE;
  1085. goto BROTLI_COMPRESS_END;
  1086. }
  1087. int iRead = (int)(m_dwBuffSize - iAvlOutLen);
  1088. if(iRead == 0)
  1089. break;
  1090. if(!m_fnCallback(szBuff.get(), iRead, pContext))
  1091. {
  1092. ::SetLastError(ERROR_CANCELLED);
  1093. isOK = FALSE;
  1094. goto BROTLI_COMPRESS_END;
  1095. }
  1096. } while (iAvlOutLen == 0);
  1097. }
  1098. BROTLI_COMPRESS_END:
  1099. if(!isOK || bLast) Reset();
  1100. return isOK;
  1101. }
  1102. CHPBrotliDecompressor::CHPBrotliDecompressor(Fn_DecompressDataCallback fnCallback, DWORD dwBuffSize)
  1103. : m_fnCallback (fnCallback)
  1104. , m_dwBuffSize (dwBuffSize)
  1105. , m_bValid (FALSE)
  1106. {
  1107. ASSERT(m_fnCallback != nullptr);
  1108. Reset();
  1109. }
  1110. CHPBrotliDecompressor::~CHPBrotliDecompressor()
  1111. {
  1112. if(m_bValid) ::BrotliDecoderDestroyInstance(m_pState);
  1113. }
  1114. BOOL CHPBrotliDecompressor::Reset()
  1115. {
  1116. if(m_bValid) ::BrotliDecoderDestroyInstance(m_pState);
  1117. m_pState = ::BrotliDecoderCreateInstance(nullptr, nullptr, nullptr);
  1118. return (m_bValid = (m_pState != nullptr));
  1119. }
  1120. BOOL CHPBrotliDecompressor::Process(const BYTE* pData, int iLength, PVOID pContext)
  1121. {
  1122. ASSERT(IsValid() && iLength > 0);
  1123. if(!IsValid())
  1124. {
  1125. ::SetLastError(ERROR_INVALID_STATE);
  1126. return FALSE;
  1127. }
  1128. unique_ptr<BYTE[]> szBuff = make_unique<BYTE[]>(m_dwBuffSize);
  1129. const BYTE* pNextInData = pData;
  1130. size_t iAvlInLen = (SIZE_T)iLength;
  1131. BYTE* pNextOutData = nullptr;
  1132. size_t iAvlOutLen = 0;
  1133. BOOL isOK = TRUE;
  1134. BrotliDecoderResult rs = BROTLI_DECODER_RESULT_NEEDS_MORE_OUTPUT;
  1135. do
  1136. {
  1137. do
  1138. {
  1139. pNextOutData = szBuff.get();
  1140. iAvlOutLen = m_dwBuffSize;
  1141. rs = ::BrotliDecoderDecompressStream(m_pState, &iAvlInLen, &pNextInData, &iAvlOutLen, &pNextOutData, nullptr);
  1142. if(rs == BROTLI_DECODER_RESULT_ERROR)
  1143. {
  1144. ::SetLastError(ERROR_INVALID_DATA);
  1145. isOK = FALSE;
  1146. goto BROTLI_DECOMPRESS_END;
  1147. }
  1148. int iRead = (int)(m_dwBuffSize - iAvlOutLen);
  1149. if(iRead == 0)
  1150. break;
  1151. if(!m_fnCallback(szBuff.get(), iRead, pContext))
  1152. {
  1153. ::SetLastError(ERROR_CANCELLED);
  1154. isOK = FALSE;
  1155. goto BROTLI_DECOMPRESS_END;
  1156. }
  1157. } while (iAvlOutLen == 0);
  1158. if(rs == BROTLI_DECODER_RESULT_SUCCESS)
  1159. break;
  1160. } while(rs == BROTLI_DECODER_RESULT_NEEDS_MORE_OUTPUT);
  1161. BROTLI_DECOMPRESS_END:
  1162. if(!isOK || rs == BROTLI_DECODER_RESULT_SUCCESS) Reset();
  1163. return isOK;
  1164. }
  1165. IHPCompressor* CreateBrotliCompressor(Fn_CompressDataCallback fnCallback, int iQuality, int iWindow, int iMode, DWORD dwBuffSize)
  1166. {
  1167. return new CHPBrotliCompressor(fnCallback, iQuality, iWindow, iMode, dwBuffSize);
  1168. }
  1169. IHPDecompressor* CreateBrotliDecompressor(Fn_DecompressDataCallback fnCallback, DWORD dwBuffSize)
  1170. {
  1171. return new CHPBrotliDecompressor(fnCallback, dwBuffSize);
  1172. }
  1173. int BrotliCompress(const BYTE* lpszSrc, DWORD dwSrcLen, BYTE* lpszDest, DWORD& dwDestLen)
  1174. {
  1175. return BrotliCompressEx(lpszSrc, dwSrcLen, lpszDest, dwDestLen, BROTLI_DEFAULT_QUALITY, BROTLI_DEFAULT_WINDOW, BROTLI_DEFAULT_MODE);
  1176. }
  1177. int BrotliCompressEx(const BYTE* lpszSrc, DWORD dwSrcLen, BYTE* lpszDest, DWORD& dwDestLen, int iQuality, int iWindow, int iMode)
  1178. {
  1179. size_t stDestLen = (size_t)dwDestLen;
  1180. int rs = ::BrotliEncoderCompress(iQuality, iWindow, (BrotliEncoderMode)iMode, (size_t)dwSrcLen, lpszSrc, &stDestLen, lpszDest);
  1181. dwDestLen = (DWORD)stDestLen;
  1182. return (rs == 1) ? 0 : ((rs == 3) ? -5 : -3);
  1183. }
  1184. int BrotliUncompress(const BYTE* lpszSrc, DWORD dwSrcLen, BYTE* lpszDest, DWORD& dwDestLen)
  1185. {
  1186. size_t stDestLen = (size_t)dwDestLen;
  1187. BrotliDecoderResult rs = ::BrotliDecoderDecompress((size_t)dwSrcLen, lpszSrc, &stDestLen, lpszDest);
  1188. dwDestLen = (DWORD)stDestLen;
  1189. return (rs == BROTLI_DECODER_RESULT_SUCCESS) ? 0 : ((rs == BROTLI_DECODER_RESULT_NEEDS_MORE_OUTPUT) ? -5 : -3);
  1190. }
  1191. DWORD BrotliGuessCompressBound(DWORD dwSrcLen)
  1192. {
  1193. return (DWORD)::BrotliEncoderMaxCompressedSize((size_t)dwSrcLen);
  1194. }
  1195. #endif
  1196. #ifdef _ICONV_SUPPORT
  1197. BOOL CharsetConvert(LPCSTR lpszFromCharset, LPCSTR lpszToCharset, LPCSTR lpszInBuf, int iInBufLen, LPSTR lpszOutBuf, int& iOutBufLen)
  1198. {
  1199. ASSERT(lpszInBuf != nullptr);
  1200. SIZE_T nInBufLeft = iInBufLen;
  1201. SIZE_T nOutBufLeft = iOutBufLen;
  1202. int iOutBufSize = iOutBufLen;
  1203. iOutBufLen = 0;
  1204. if(lpszInBuf == nullptr)
  1205. {
  1206. SetLastError(ERROR_INVALID_PARAMETER);
  1207. return FALSE;
  1208. }
  1209. iconv_t ic = iconv_open(lpszToCharset, lpszFromCharset);
  1210. if(IS_INVALID_PVOID(ic))
  1211. return FALSE;
  1212. SIZE_T rs = iconv(ic, (LPSTR*)&lpszInBuf, &nInBufLeft, &lpszOutBuf, &nOutBufLeft);
  1213. iOutBufLen = iOutBufSize - (int)nOutBufLeft;
  1214. EXECUTE_RESTORE_ERROR(iconv_close(ic));
  1215. return !IS_HAS_ERROR(rs);
  1216. }
  1217. BOOL GbkToUnicodeEx(const char szSrc[], int iSrcLength, WCHAR szDest[], int& iDestLength)
  1218. {
  1219. int iInBufLen = (int)((iSrcLength > 0) ? iSrcLength : ((szSrc != nullptr) ? strlen(szSrc) + 1 : 0));
  1220. int iOutBufLen = (int)(iDestLength * sizeof(WCHAR));
  1221. BOOL isOK = CharsetConvert(CHARSET_GBK, SYSTEM_CHARSET_UNICODE, szSrc, iInBufLen, (char*)szDest, iOutBufLen);
  1222. iDestLength = (int)(iOutBufLen / sizeof(WCHAR));
  1223. return isOK;
  1224. }
  1225. BOOL UnicodeToGbkEx(const WCHAR szSrc[], int iSrcLength, char szDest[], int& iDestLength)
  1226. {
  1227. int iInBufLen = (int)(((iSrcLength > 0) ? iSrcLength : ((szSrc != nullptr) ? wcslen(szSrc) + 1 : 0)) * sizeof(WCHAR));
  1228. return CharsetConvert(SYSTEM_CHARSET_UNICODE, CHARSET_GBK, (LPCSTR)szSrc, iInBufLen, szDest, iDestLength);
  1229. }
  1230. BOOL Utf8ToUnicodeEx(const char szSrc[], int iSrcLength, WCHAR szDest[], int& iDestLength)
  1231. {
  1232. int iInBufLen = (int)((iSrcLength > 0) ? iSrcLength : ((szSrc != nullptr) ? strlen(szSrc) + 1 : 0));
  1233. int iOutBufLen = (int)(iDestLength * sizeof(WCHAR));
  1234. BOOL isOK = CharsetConvert(CHARSET_UTF_8, SYSTEM_CHARSET_UNICODE, szSrc, iInBufLen, (char*)szDest, iOutBufLen);
  1235. iDestLength = (int)(iOutBufLen / sizeof(WCHAR));
  1236. return isOK;
  1237. }
  1238. BOOL UnicodeToUtf8Ex(const WCHAR szSrc[], int iSrcLength, char szDest[], int& iDestLength)
  1239. {
  1240. int iInBufLen = (int)(((iSrcLength > 0) ? iSrcLength : ((szSrc != nullptr) ? wcslen(szSrc) + 1 : 0)) * sizeof(WCHAR));
  1241. return CharsetConvert(SYSTEM_CHARSET_UNICODE, CHARSET_UTF_8, (LPCSTR)szSrc, iInBufLen, szDest, iDestLength);
  1242. }
  1243. BOOL GbkToUtf8Ex(const char szSrc[], int iSrcLength, char szDest[], int& iDestLength)
  1244. {
  1245. int iInBufLen = (int)((iSrcLength > 0) ? iSrcLength : ((szSrc != nullptr) ? strlen(szSrc) + 1 : 0));
  1246. return CharsetConvert(CHARSET_GBK, CHARSET_UTF_8, szSrc, iInBufLen, szDest, iDestLength);
  1247. }
  1248. BOOL Utf8ToGbkEx(const char szSrc[], int iSrcLength, char szDest[], int& iDestLength)
  1249. {
  1250. int iInBufLen = (int)((iSrcLength > 0) ? iSrcLength : ((szSrc != nullptr) ? strlen(szSrc) + 1 : 0));
  1251. return CharsetConvert(CHARSET_UTF_8, CHARSET_GBK, szSrc, iInBufLen, szDest, iDestLength);
  1252. }
  1253. BOOL GbkToUnicode(const char szSrc[], WCHAR szDest[], int& iDestLength)
  1254. {
  1255. return GbkToUnicodeEx(szSrc, -1, szDest, iDestLength);
  1256. }
  1257. BOOL UnicodeToGbk(const WCHAR szSrc[], char szDest[], int& iDestLength)
  1258. {
  1259. return UnicodeToGbkEx(szSrc, -1, szDest, iDestLength);
  1260. }
  1261. BOOL Utf8ToUnicode(const char szSrc[], WCHAR szDest[], int& iDestLength)
  1262. {
  1263. return Utf8ToUnicodeEx(szSrc, -1, szDest, iDestLength);
  1264. }
  1265. BOOL UnicodeToUtf8(const WCHAR szSrc[], char szDest[], int& iDestLength)
  1266. {
  1267. return UnicodeToUtf8Ex(szSrc, -1, szDest, iDestLength);
  1268. }
  1269. BOOL GbkToUtf8(const char szSrc[], char szDest[], int& iDestLength)
  1270. {
  1271. return GbkToUtf8Ex(szSrc, -1, szDest, iDestLength);
  1272. }
  1273. BOOL Utf8ToGbk(const char szSrc[], char szDest[], int& iDestLength)
  1274. {
  1275. return Utf8ToGbkEx(szSrc, -1, szDest, iDestLength);
  1276. }
  1277. #endif