(file) Return to Base64.cpp CVS log (file) (dir) Up to [Pegasus] / pegasus / src / Pegasus / Common

  1 karl  1.1 //%/////////////////////////////////////////////////////////////////////////////
  2           //
  3           // Copyright (c) 2000, 2001 BMC Software, Hewlett-Packard Company, IBM, 
  4           // The Open Group, Tivoli Systems
  5           //
  6           // Permission is hereby granted, free of charge, to any person obtaining a copy
  7           // of this software and associated documentation files (the "Software"), to 
  8           // deal in the Software without restriction, including without limitation the 
  9           // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 
 10           // sell copies of the Software, and to permit persons to whom the Software is
 11           // furnished to do so, subject to the following conditions:
 12           // 
 13           // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN 
 14           // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
 15           // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
 16           // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR 
 17           // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 
 18           // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 
 19           // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 20           // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 21           //
 22 karl  1.1 //==============================================================================
 23           //
 24           // Author: Karl Schopmeyer (k.schopmeyer@opengroup.org)
 25           //
 26           // Modified By:
 27           //
 28           //%/////////////////////////////////////////////////////////////////////////////
 29           
 30           #include "Base64.h"
 31           #include <cassert>
 32           #include <strstream>
 33 kumpf 1.3 #include <string>
 34 karl  1.1 #include <Pegasus/Common/String.h>
 35           #include <Pegasus/Common/Base64.h>
 36           #include <Pegasus/Common/Array.h>
 37           
 38           PEGASUS_NAMESPACE_BEGIN
 39           PEGASUS_USING_STD;
 40           
 41           //*************************************************************
 42           /*  Encode static method takes an array of 8-bit values and
 43               returns a base-64 stream.
 44 karl  1.2     ATTN: KS feb 2002 - This is probably a very slow an inefficient
 45               implementation and could be improved if it is required for
 46               production.  Today it is only for test programs.
 47 karl  1.1 */
 48 kumpf 1.4 Array<Sint8> Base64::encode(const Array<Uint8>& vby)
 49 karl  1.1 {
 50 karl  1.2     Array<Sint8> retArray;
 51 karl  1.1     // If nothing in input string, return empty string
 52               if (vby.size() == 0)
 53 karl  1.2         return retArray;
 54 karl  1.1     // for every character in the input array taken 3 bytes at a time
 55           
 56               for (Uint32 i=0; i < vby.size(); i+=3)
 57               {
 58                   
 59                   // Create from 3 8 bit values to 4 6 bit values
 60                   Uint8 by1=0,by2=0,by3=0;
 61                   by1 = vby[i];
 62                   if (i+1<vby.size())
 63                   {
 64                       by2 = vby[i+1];
 65                   };
 66                   if (i+2<vby.size())
 67                   {
 68                       by3 = vby[i+2];
 69                   }
 70           
 71                   Uint8 by4=0,by5=0,by6=0,by7=0;
 72                   by4 = by1>>2;
 73                   by5 = ((by1&0x3)<<4)|(by2>>4);
 74                   by6 = ((by2&0xf)<<2)|(by3>>6);
 75 karl  1.1         by7 = by3&0x3f;
 76           
 77 karl  1.2         retArray.append(_Encode(by4));
 78                   retArray.append(_Encode(by5));
 79 karl  1.1 
 80                   if (i+1<vby.size())
 81 karl  1.2             retArray.append( _Encode(by6));
 82 karl  1.1         else
 83 karl  1.2             retArray.append('=');
 84 karl  1.1 
 85                   if (i+2<vby.size())
 86 karl  1.2             retArray.append( _Encode(by7));
 87 karl  1.1         else
 88 karl  1.2             retArray.append('=');
 89 karl  1.1 
 90                   if (i % (76/4*3) == 0)
 91                   {
 92 karl  1.2             retArray.append( '\r');
 93                       retArray.append( '\n');
 94 karl  1.1         }
 95               };
 96           
 97 karl  1.2     return retArray;
 98 karl  1.1 };
 99           /*I checked for the zero length. The algorithm would also work for zero length input stream, but I’m pretty adamant about handling border conditions. They are often the culprits of run-time production failures.
100           The algorithm goes thru each three bytes of data at a time. The first thing I do is to shift the bits around from three 8-bit values to four 6-bit values. Then I encode the 6-bit values and add then one at a time to the output stream. This is actually quite inefficient. The STL character array is being allocated one byte at a time. The algorithm would be much faster, if I pre-allocated that array. I’ll leave that as an optimization practical exercise for the reader.
101           
102           
103           /*  The decode static method takes a base-64 stream and converts it 
104               to an array of 8-bit values.
105           */
106 kumpf 1.4 Array<Uint8> Base64::decode(const Array<Sint8> strInput)
107 karl  1.1 {
108               //Strip any non-base64 characters from the input
109 kumpf 1.3     PEGASUS_STD(string) str;
110 karl  1.1     for (Uint32 j=0;j<strInput.size();j++)
111               {
112                   if (_IsBase64(strInput[j]))
113                       str += strInput[j];
114               }
115 karl  1.2 
116               Array<Uint8> retArray;
117 karl  1.1 
118               // Return if the input is zero length
119               if (str.length() == 0)
120 karl  1.2         return retArray;
121 karl  1.1 
122               //  comment
123               for (int i=0; i < str.length();i+=4)
124               {
125                   char c1='A',c2='A',c3='A',c4='A';
126           
127                   c1 = str[i];
128                   if (i+1<str.length())
129                       c2 = str[i+1];
130                   if (i+2<str.length())
131                       c3 = str[i+2];
132                   if (i+3<str.length())
133                       c4 = str[i+3];
134           
135                   Uint8 by1=0,by2=0,by3=0,by4=0;
136                   by1 = _Decode(c1);
137                   by2 = _Decode(c2);
138                   by3 = _Decode(c3);
139                   by4 = _Decode(c4);
140                   //cout << "base::64decode bytes" <<
141                   //      " 1 " << c1 << " " << by1 <<
142 karl  1.1         //      " 2 " << c2 << " " << by2 <<
143                   //      " 3 " << c3 << " " << by3 <<
144                   //      " 4 " << c4 << " " << by4 << endl;
145                   
146                   // append first byte by shifting
147 karl  1.2         retArray.append( (by1<<2)|(by2>>4) );
148 karl  1.1 
149                   // append second byte if not padding
150                   if (c3 != '=')
151 karl  1.2             retArray.append( ((by2&0xf)<<4)|(by3>>2) );
152 karl  1.1 
153                   if (c4 != '=')
154 karl  1.2             retArray.append( ((by3&0x3)<<6)|by4 );
155 karl  1.1     }
156           
157 karl  1.2     return retArray;
158 karl  1.1 };
159           
160           //**********************************************************
161           /*  Encode thanslates one six-bit pattern into a base-64 character.
162               Unsigned char is used to represent a six-bit stream of date.
163               
164           */
165           inline PEGASUS_COMMON_LINKAGE char Base64::_Encode(Uint8 uc)
166           {
167               if (uc < 26)
168                   return 'A'+uc;
169           
170               if (uc < 52)
171                   return 'a'+(uc-26);
172           
173               if (uc < 62)
174                   return '0'+(uc-52);
175           
176               if (uc == 62)
177                   return '+';
178           
179 karl  1.1     return '/';
180           };
181           
182            //Helper function returns true is a character is a valid base-64 character and false otherwise.
183           
184           inline Boolean Base64::_IsBase64(char c)
185           {
186           
187               if (c >= 'A' && c <= 'Z')
188                   return true;
189           
190               if (c >= 'a' && c <= 'z')
191                   return true;
192           
193               if (c >= '0' && c <= '9')
194                   return true;
195           
196               if (c == '+')
197                   return true;
198           
199               if (c == '/')
200 karl  1.1         return true;
201           
202               if (c == '=')
203                   return true;
204           
205               return false;
206           };
207            
208            // Translate one base-64 character into a six bit pattern
209           inline Uint8 Base64::_Decode(char c)
210           {
211               if (c >= 'A' && c <= 'Z')
212                   return c - 'A';
213               if (c >= 'a' && c <= 'z')
214                   return c - 'a' + 26;
215           
216               if (c >= '0' && c <= '9')
217                   return c - '0' + 52;
218           
219               if (c == '+')
220                   return 62;
221 karl  1.1 
222               return 63;
223           };
224           
225           
226           PEGASUS_NAMESPACE_END

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2