172 |
172 |
173 rDestString.SetLength((TInt)(destStringPtr-destStringPtrBase)); |
173 rDestString.SetLength((TInt)(destStringPtr-destStringPtrBase)); |
174 |
174 |
175 return maskShift<ESix; |
175 return maskShift<ESix; |
176 } |
176 } |
|
177 |
|
178 |
|
179 /** |
|
180 Encodes an ASCII string to Base64 string. |
|
181 |
|
182 @param aSrcString The source string in ASCII. |
|
183 @param aDestString The destination string with converted base64 values. |
|
184 @param aLineLength The maximum line length of the encoded base64 values. |
|
185 A CR/LF sequence will be added after these many characters. |
|
186 The default value is -1, which means no CR/LF is added to output. The encoding is compliant with RFC 4648 |
|
187 @return Number of characters in the source string that were not encoded. |
|
188 */ |
|
189 EXPORT_C TInt TBase64::PortableEncode(const TDesC8& aSrcString, TDes8& aDestString, TInt aLineLength) |
|
190 { |
|
191 // Clears the destination string |
|
192 aDestString.Zero(); |
|
193 // Initialise variables |
|
194 const TUint8* srcStringPtr=aSrcString.Ptr(); |
|
195 const TUint8* srcStringEnd=aSrcString.Length()+srcStringPtr; |
|
196 TUint8* destStringPtr=(TUint8*)aDestString.Ptr(); |
|
197 TUint8* destStringPtrBase=destStringPtr; |
|
198 TInt character=0; |
|
199 TUint8 encodedChar=0; |
|
200 TInt charStorage=0; |
|
201 TInt maskShift=EZero; |
|
202 TInt destStringCharNum = 0; |
|
203 |
|
204 while(srcStringPtr<=srcStringEnd) |
|
205 { |
|
206 // maskShift is used as a char read counter |
|
207 if(maskShift==ESix) |
|
208 { |
|
209 // If the 3rd char read is also the last char then the while loop |
|
210 // is broken on the next check. |
|
211 if(srcStringPtr==srcStringEnd) |
|
212 srcStringPtr++; |
|
213 maskShift=EZero; |
|
214 character=0; |
|
215 } |
|
216 else |
|
217 { |
|
218 if(srcStringPtr==srcStringEnd) |
|
219 character=0; |
|
220 else |
|
221 character=*srcStringPtr; |
|
222 |
|
223 srcStringPtr++; |
|
224 // Shifts charStorage ready for the next char |
|
225 charStorage=charStorage<<8; |
|
226 maskShift+=ETwo; |
|
227 } |
|
228 charStorage=charStorage|character; |
|
229 // Shifts the mask to the correct bit location |
|
230 // Masks (AND's) the valid bits from charStorage |
|
231 // Shifts the valid bits into the low order 8bits |
|
232 // Converts to BASE64 char, Casts the result to an unsigned char (which it should be ?....I hope) |
|
233 encodedChar=(TUint8)Base64ToAscii[((charStorage>>maskShift)&ESixBitMask)]; |
|
234 |
|
235 *destStringPtr++=encodedChar; |
|
236 destStringCharNum++; |
|
237 |
|
238 // Add a CRLF every aLineLength number of characters |
|
239 if (destStringCharNum == aLineLength) |
|
240 { |
|
241 destStringCharNum = 0; |
|
242 *destStringPtr++ = '\r'; |
|
243 *destStringPtr++ = '\n'; |
|
244 } |
|
245 } |
|
246 |
|
247 // Check for not enough chars and pad if required |
|
248 if (maskShift==EFour) |
|
249 { |
|
250 *destStringPtr++=KImcvConvEquals; |
|
251 *destStringPtr++=KImcvConvEquals; |
|
252 } |
|
253 else |
|
254 if(maskShift==ESix) |
|
255 *destStringPtr++=KImcvConvEquals; |
|
256 |
|
257 aDestString.SetLength((TInt)(destStringPtr-destStringPtrBase)); |
|
258 return ((TInt)(srcStringPtr-srcStringEnd)); |
|
259 } |