/* * (c) Copyright Ascensio System SIA 2010-2014 * * This program is a free software product. You can redistribute it and/or * modify it under the terms of the GNU Affero General Public License (AGPL) * version 3 as published by the Free Software Foundation. In accordance with * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect * that Ascensio System SIA expressly excludes the warranty of non-infringement * of any third-party rights. * * This program is distributed WITHOUT ANY WARRANTY; without even the implied * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html * * You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia, * EU, LV-1021. * * The interactive user interfaces in modified source and object code versions * of the Program must display Appropriate Legal Notices, as required under * Section 5 of the GNU AGPL version 3. * * Pursuant to Section 7(b) of the License you must retain the original Product * logo when distributing the program. Pursuant to Section 7(e) we decline to * grant you any rights under trademark law for use of our trademarks. * * All the Product's GUI elements, including illustrations and icon sets, as * well as technical writing content are licensed under the terms of the * Creative Commons Attribution-ShareAlike 4.0 International. See the License * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode * */ #ifndef BASE64_H_DEFINE #define BASE64_H_DEFINE #if _MSC_VER >= 1000 #pragma once #endif #include #pragma pack(push, 8) namespace Base64 { const int B64_BASE64_FLAG_NONE = 0; const int B64_BASE64_FLAG_NOPAD = 1; const int B64_BASE64_FLAG_NOCRLF = 2; inline int Base64EncodeGetRequiredLength(int nSrcLen, DWORD dwFlags = B64_BASE64_FLAG_NONE) { __int64 nSrcLen4 = static_cast<__int64>(nSrcLen)*4; if (nSrcLen4 > INT_MAX) return -1; int nRet = static_cast(nSrcLen4/3); if ((dwFlags & B64_BASE64_FLAG_NOPAD) == 0) nRet += nSrcLen % 3; int nCRLFs = nRet / 76 + 1; int nOnLastLine = nRet % 76; if (nOnLastLine) { if (nOnLastLine % 4) nRet += 4-(nOnLastLine % 4); } nCRLFs *= 2; if ((dwFlags & B64_BASE64_FLAG_NOCRLF) == 0) nRet += nCRLFs; return nRet; } inline int Base64DecodeGetRequiredLength(int nSrcLen) throw() { return nSrcLen; } inline BOOL Base64Encode(const BYTE *pbSrcData, int nSrcLen, LPSTR szDest, int *pnDestLen, DWORD dwFlags = B64_BASE64_FLAG_NONE) throw() { static const char s_chBase64EncodingTable[64] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/' }; if (!pbSrcData || !szDest || !pnDestLen) return FALSE; if (*pnDestLen < Base64EncodeGetRequiredLength(nSrcLen, dwFlags)) return FALSE; int nWritten( 0 ); int nLen1( (nSrcLen/3)*4 ); int nLen2( nLen1/76 ); int nLen3( 19 ); for (int i=0; i<=nLen2; i++) { if (i==nLen2) nLen3 = (nLen1%76)/4; for (int j=0; j>26); *szDest++ = s_chBase64EncodingTable[b]; dwCurr <<= 6; } } nWritten+= nLen3*4; if ((dwFlags & B64_BASE64_FLAG_NOCRLF)==0) { *szDest++ = '\r'; *szDest++ = '\n'; nWritten+= 2; } } if (nWritten && (dwFlags & B64_BASE64_FLAG_NOCRLF)==0) { szDest-= 2; nWritten -= 2; } nLen2 = (nSrcLen%3) ? (nSrcLen%3 + 1) : 0; if (nLen2) { DWORD dwCurr(0); for (int n=0; n<3; n++) { if (n<(nSrcLen%3)) dwCurr |= *pbSrcData++; dwCurr <<= 8; } for (int k=0; k>26); *szDest++ = s_chBase64EncodingTable[b]; dwCurr <<= 6; } nWritten+= nLen2; if ((dwFlags & B64_BASE64_FLAG_NOPAD)==0) { nLen3 = nLen2 ? 4-nLen2 : 0; for (int j=0; j= 'A' && ch <= 'Z') return ch - 'A' + 0; if (ch >= 'a' && ch <= 'z') return ch - 'a' + 26; if (ch >= '0' && ch <= '9') return ch - '0' + 52; if (ch == '+') return 62; if (ch == '/') return 63; return -1; } inline BOOL Base64Decode(LPCSTR szSrc, int nSrcLen, BYTE *pbDest, int *pnDestLen) throw() { if (szSrc == NULL || pnDestLen == NULL) return FALSE; LPCSTR szSrcEnd = szSrc + nSrcLen; int nWritten = 0; BOOL bOverflow = (pbDest == NULL) ? TRUE : FALSE; while (szSrc < szSrcEnd &&(*szSrc) != 0) { DWORD dwCurr = 0; int i; int nBits = 0; for (i=0; i<4; i++) { if (szSrc >= szSrcEnd) break; int nCh = DecodeBase64Char(*szSrc); szSrc++; if (nCh == -1) { i--; continue; } dwCurr <<= 6; dwCurr |= nCh; nBits += 6; } if(!bOverflow && nWritten + (nBits/8) > (*pnDestLen)) bOverflow = TRUE; dwCurr <<= 24-nBits; for (i=0; i> 16); pbDest++; } dwCurr <<= 8; nWritten++; } } *pnDestLen = nWritten; if(bOverflow) { return FALSE; } return TRUE; } } #pragma pack(pop) #endif//BASE64_H_DEFINE