OSDN Git Service

Fix create socket error and add retry when send fail.
[tortoisegit/TortoiseGitJp.git] / src / Utils / CBase64.cpp
1 // Base64.cpp: implementation of the CBase64 class.\r
2 //\r
3 //////////////////////////////////////////////////////////////////////\r
4 \r
5 #include "stdafx.h"\r
6 #include "CBase64.h"\r
7 \r
8 #ifdef _DEBUG\r
9 #undef THIS_FILE\r
10 static char THIS_FILE[]=__FILE__;\r
11 #define new DEBUG_NEW\r
12 #endif\r
13 \r
14 //////////////////////////////////////////////////////////////////////\r
15 // CBase64\r
16 //////////////////////////////////////////////////////////////////////\r
17 // Static Member Initializers\r
18 //\r
19 \r
20 // The 7-bit alphabet used to encode binary information\r
21 const char m_sBase64Alphabet[] =  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";\r
22 \r
23 const int f_nMask[] = { 0, 1, 3, 7, 15, 31, 63, 127, 255 };\r
24 \r
25 CBase64::CBase64()\r
26 {\r
27         m_lBitStorage = 0;\r
28         m_nBitsRemaining = 0;\r
29         m_nInputSize = 0;\r
30         m_szInput = NULL;\r
31 }\r
32 \r
33 CBase64::~CBase64()\r
34 {\r
35 }\r
36 \r
37 CStringA CBase64::Encode( IN const char* szEncoding, IN int nSize )\r
38 {\r
39         CStringA sOutput = "";\r
40         int nNumBits = 6;\r
41         UINT nDigit;\r
42         int lp = 0;\r
43 \r
44         ASSERT( szEncoding != NULL );\r
45         if( szEncoding == NULL )\r
46                 return sOutput;\r
47         m_szInput = szEncoding;\r
48         m_nInputSize = nSize;\r
49 \r
50         m_nBitsRemaining = 0;\r
51         nDigit = read_bits( nNumBits, &nNumBits, lp );\r
52         while( nNumBits > 0 )\r
53         {\r
54                 sOutput += m_sBase64Alphabet[ (int)nDigit ];\r
55                 nDigit = read_bits( nNumBits, &nNumBits, lp );\r
56         }\r
57         // Pad with '=' as per RFC 1521\r
58         while( sOutput.GetLength() % 4 != 0 )\r
59         {\r
60                 sOutput += '=';\r
61         }\r
62         return sOutput;\r
63 }\r
64 \r
65 // The size of the output buffer must not be less than\r
66 // 3/4 the size of the input buffer. For simplicity,\r
67 // make them the same size.\r
68 // return : ½âÂëºóÊý¾Ý³¤¶È\r
69 int CBase64::Decode ( IN const char* szDecoding, char* szOutput )\r
70 {\r
71         CString sInput;\r
72     int c, lp =0;\r
73         int nDigit;\r
74     int nDecode[ 256 ];\r
75 \r
76         ASSERT( szDecoding != NULL );\r
77         ASSERT( szOutput != NULL );\r
78         if( szOutput == NULL )\r
79                 return 0;\r
80         if( szDecoding == NULL )\r
81                 return 0;\r
82         sInput = szDecoding;\r
83         if( sInput.GetLength() == 0 )\r
84                 return 0;\r
85 \r
86         // Build Decode Table\r
87         //\r
88         int i;\r
89         for( i = 0; i < 256; i++ ) \r
90                 nDecode[i] = -2; // Illegal digit\r
91         for( i=0; i < 64; i++ )\r
92         {\r
93                 nDecode[ m_sBase64Alphabet[ i ] ] = i;\r
94                 nDecode[ m_sBase64Alphabet[ i ] | 0x80 ] = i; // Ignore 8th bit\r
95                 nDecode[ '=' ] = -1; \r
96                 nDecode[ '=' | 0x80 ] = -1; // Ignore MIME padding char\r
97     }\r
98 \r
99         // Clear the output buffer\r
100         memset( szOutput, 0, sInput.GetLength() + 1 );\r
101 \r
102         // Decode the Input\r
103         //\r
104         for( lp = 0, i = 0; lp < sInput.GetLength(); lp++ )\r
105         {\r
106                 c = sInput[ lp ];\r
107                 nDigit = nDecode[ c & 0x7F ];\r
108                 if( nDigit < -1 ) \r
109                 {\r
110                         return 0;\r
111                 } \r
112                 else if( nDigit >= 0 ) \r
113                         // i (index into output) is incremented by write_bits()\r
114                         write_bits( nDigit & 0x3F, 6, szOutput, i );\r
115     }   \r
116         return i;\r
117 }\r
118 \r
119 UINT CBase64::read_bits(int nNumBits, int * pBitsRead, int& lp)\r
120 {\r
121     ULONG lScratch;\r
122     while( ( m_nBitsRemaining < nNumBits ) && \r
123                    ( lp < m_nInputSize ) ) \r
124         {\r
125                 int c = m_szInput[ lp++ ];\r
126         m_lBitStorage <<= 8;\r
127         m_lBitStorage |= (c & 0xff);\r
128                 m_nBitsRemaining += 8;\r
129     }\r
130     if( m_nBitsRemaining < nNumBits ) \r
131         {\r
132                 lScratch = m_lBitStorage << ( nNumBits - m_nBitsRemaining );\r
133                 *pBitsRead = m_nBitsRemaining;\r
134                 m_nBitsRemaining = 0;\r
135     } \r
136         else \r
137         {\r
138                 lScratch = m_lBitStorage >> ( m_nBitsRemaining - nNumBits );\r
139                 *pBitsRead = nNumBits;\r
140                 m_nBitsRemaining -= nNumBits;\r
141     }\r
142     return (UINT)lScratch & f_nMask[nNumBits];\r
143 }\r
144 \r
145 \r
146 void CBase64::write_bits(UINT nBits,\r
147                                                  int nNumBits,\r
148                                                  LPSTR szOutput,\r
149                                                  int& i)\r
150 {\r
151         UINT nScratch;\r
152 \r
153         m_lBitStorage = (m_lBitStorage << nNumBits) | nBits;\r
154         m_nBitsRemaining += nNumBits;\r
155         while( m_nBitsRemaining > 7 ) \r
156         {\r
157                 nScratch = m_lBitStorage >> (m_nBitsRemaining - 8);\r
158                 szOutput[ i++ ] = nScratch & 0xFF;\r
159                 m_nBitsRemaining -= 8;\r
160         }\r
161 }