ICE 3.4.2
[php5-ice-freebsdport.git] / cpp / src / Ice / Base64.cpp
blobf7a64be9077fe5881cffabf2dc750acc684862dc
1 // **********************************************************************
2 //
3 // Copyright (c) 2003-2011 ZeroC, Inc. All rights reserved.
4 //
5 // This copy of Ice is licensed to you under the terms described in the
6 // ICE_LICENSE file included in this distribution.
7 //
8 // **********************************************************************
10 #include <Ice/Base64.h>
11 #include <iterator>
13 using namespace std;
15 string
16 IceInternal::Base64::encode(const vector<unsigned char>& plainSeq)
18 string retval;
20 if(plainSeq.size() == 0)
22 return retval;
25 // Reserve enough space for the returned base64 string
26 size_t base64Bytes = (((plainSeq.size() * 4) / 3) + 1);
27 size_t newlineBytes = (((base64Bytes * 2) / 76) + 1);
28 size_t totalBytes = base64Bytes + newlineBytes;
30 retval.reserve(totalBytes);
32 unsigned char by1 = 0;
33 unsigned char by2 = 0;
34 unsigned char by3 = 0;
35 unsigned char by4 = 0;
36 unsigned char by5 = 0;
37 unsigned char by6 = 0;
38 unsigned char by7 = 0;
40 for(size_t i = 0; i < plainSeq.size(); i += 3)
42 by1 = plainSeq[i];
43 by2 = 0;
44 by3 = 0;
46 if((i + 1) < plainSeq.size())
48 by2 = plainSeq[i+1];
51 if((i + 2) < plainSeq.size())
53 by3 = plainSeq[i+2];
56 by4 = by1 >> 2;
57 by5 = ((by1 & 0x3) << 4) | (by2 >> 4);
58 by6 = ((by2 & 0xf) << 2) | (by3 >> 6);
59 by7 = by3 & 0x3f;
61 retval += encode(by4);
62 retval += encode(by5);
64 if((i + 1) < plainSeq.size())
66 retval += encode(by6);
68 else
70 retval += "=";
73 if((i + 2) < plainSeq.size())
75 retval += encode(by7);
77 else
79 retval += "=";
83 string outString;
84 outString.reserve(totalBytes);
85 string::iterator iter = retval.begin();
87 while((retval.end() - iter) > 76)
89 copy(iter, iter+76, back_inserter(outString));
90 outString += "\r\n";
91 iter += 76;
94 copy(iter, retval.end(), back_inserter(outString));
96 return outString;
99 vector<unsigned char>
100 IceInternal::Base64::decode(const string& str)
102 string newStr;
104 newStr.reserve(str.length());
106 for(size_t j = 0; j < str.length(); j++)
108 if(isBase64(str[j]))
110 newStr += str[j];
114 vector<unsigned char> retval;
116 if(newStr.length() == 0)
118 return retval;
121 // Note: This is how we were previously computing the size of the return
122 // sequence. The method below is more efficient (and correct).
123 // size_t lines = str.size() / 78;
124 // size_t totalBytes = (lines * 76) + (((str.size() - (lines * 78)) * 3) / 4);
126 // Figure out how long the final sequence is going to be.
127 size_t totalBytes = (newStr.size() * 3 / 4) + 1;
129 retval.reserve(totalBytes);
131 unsigned char by1 = 0;
132 unsigned char by2 = 0;
133 unsigned char by3 = 0;
134 unsigned char by4 = 0;
136 char c1, c2, c3, c4;
138 for(size_t i = 0; i < newStr.length(); i += 4)
140 c1 = 'A';
141 c2 = 'A';
142 c3 = 'A';
143 c4 = 'A';
145 c1 = newStr[i];
147 if((i + 1) < newStr.length())
149 c2 = newStr[i + 1];
152 if((i + 2) < newStr.length())
154 c3 = newStr[i + 2];
157 if((i + 3) < newStr.length())
159 c4 = newStr[i + 3];
162 by1 = decode(c1);
163 by2 = decode(c2);
164 by3 = decode(c3);
165 by4 = decode(c4);
167 retval.push_back((by1 << 2) | (by2 >> 4));
169 if(c3 != '=')
171 retval.push_back(((by2 & 0xf) << 4) | (by3 >> 2));
174 if(c4 != '=')
176 retval.push_back(((by3 & 0x3) << 6) | by4);
180 return retval;
183 bool
184 IceInternal::Base64::isBase64(char c)
186 if(c >= 'A' && c <= 'Z')
188 return true;
191 if(c >= 'a' && c <= 'z')
193 return true;
196 if(c >= '0' && c <= '9')
198 return true;
201 if(c == '+')
203 return true;
206 if(c == '/')
208 return true;
211 if(c == '=')
213 return true;
216 return false;
219 char
220 IceInternal::Base64::encode(unsigned char uc)
222 if(uc < 26)
224 return 'A' + uc;
227 if(uc < 52)
229 return 'a' + (uc - 26);
232 if(uc < 62)
234 return '0' + (uc - 52);
237 if(uc == 62)
239 return '+';
242 return '/';
245 unsigned char
246 IceInternal::Base64::decode(char c)
248 if(c >= 'A' && c <= 'Z')
250 return c - 'A';
253 if(c >= 'a' && c <= 'z')
255 return c - 'a' + 26;
258 if(c >= '0' && c <= '9')
260 return c - '0' + 52;
263 if(c == '+')
265 return 62;
268 return 63;