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

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

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2