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

  1 karl  1.1 //%/////////////////////////////////////////////////////////////////////////////
  2           //
  3 kumpf 1.10 // Copyright (c) 2000, 2001, 2002 BMC Software, Hewlett-Packard Company, IBM,
  4 karl  1.1  // The Open Group, Tivoli Systems
  5            //
  6            // Permission is hereby granted, free of charge, to any person obtaining a copy
  7 kumpf 1.10 // 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 karl  1.1  // 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 kumpf 1.10 // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
 14 karl  1.1  // 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 kumpf 1.10 // 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 karl  1.1  // 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            //==============================================================================
 23            //
 24            // Author: Karl Schopmeyer (k.schopmeyer@opengroup.org)
 25            //
 26            // Modified By:
 27            //
 28            //%/////////////////////////////////////////////////////////////////////////////
 29            
 30            #include <strstream>
 31 kumpf 1.3  #include <string>
 32 kumpf 1.7  #include "Base64.h"
 33 karl  1.1  #include <Pegasus/Common/Array.h>
 34            
 35            PEGASUS_NAMESPACE_BEGIN
 36            PEGASUS_USING_STD;
 37            
 38 sage  1.5  #ifdef PEGASUS_PLATFORM_AIX_RS_IBMCXX
 39            #define inline
 40            #endif
 41            
 42 karl  1.1  //*************************************************************
 43            /*  Encode static method takes an array of 8-bit values and
 44                returns a base-64 stream.
 45 karl  1.2      ATTN: KS feb 2002 - This is probably a very slow an inefficient
 46                implementation and could be improved if it is required for
 47                production.  Today it is only for test programs.
 48 karl  1.1  */
 49 kumpf 1.4  Array<Sint8> Base64::encode(const Array<Uint8>& vby)
 50 karl  1.1  {
 51 karl  1.2      Array<Sint8> retArray;
 52 karl  1.1      // If nothing in input string, return empty string
 53                if (vby.size() == 0)
 54 karl  1.2          return retArray;
 55 karl  1.1      // for every character in the input array taken 3 bytes at a time
 56            
 57                for (Uint32 i=0; i < vby.size(); i+=3)
 58                {
 59                    
 60                    // Create from 3 8 bit values to 4 6 bit values
 61                    Uint8 by1=0,by2=0,by3=0;
 62                    by1 = vby[i];
 63                    if (i+1<vby.size())
 64                    {
 65                        by2 = vby[i+1];
 66                    };
 67                    if (i+2<vby.size())
 68                    {
 69                        by3 = vby[i+2];
 70                    }
 71            
 72                    Uint8 by4=0,by5=0,by6=0,by7=0;
 73                    by4 = by1>>2;
 74                    by5 = ((by1&0x3)<<4)|(by2>>4);
 75                    by6 = ((by2&0xf)<<2)|(by3>>6);
 76 karl  1.1          by7 = by3&0x3f;
 77            
 78 karl  1.2          retArray.append(_Encode(by4));
 79                    retArray.append(_Encode(by5));
 80 karl  1.1  
 81                    if (i+1<vby.size())
 82 karl  1.2              retArray.append( _Encode(by6));
 83 karl  1.1          else
 84 karl  1.2              retArray.append('=');
 85 karl  1.1  
 86                    if (i+2<vby.size())
 87 karl  1.2              retArray.append( _Encode(by7));
 88 karl  1.1          else
 89 karl  1.2              retArray.append('=');
 90 karl  1.1  
 91 kumpf 1.6          /* ATTN: Need to fix this. It adds unwanted cr-lf after 4 chars.
 92            
 93 karl  1.1          if (i % (76/4*3) == 0)
 94                    {
 95 karl  1.2              retArray.append( '\r');
 96                        retArray.append( '\n');
 97 karl  1.1          }
 98 kumpf 1.6          */
 99 karl  1.1      };
100            
101 karl  1.2      return retArray;
102 karl  1.1  };
103            /*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.
104            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.
105 kumpf 1.9  */
106 karl  1.1  
107            /*  The decode static method takes a base-64 stream and converts it 
108                to an array of 8-bit values.
109            */
110 kumpf 1.4  Array<Uint8> Base64::decode(const Array<Sint8> strInput)
111 karl  1.1  {
112                //Strip any non-base64 characters from the input
113 kumpf 1.3      PEGASUS_STD(string) str;
114 karl  1.1      for (Uint32 j=0;j<strInput.size();j++)
115                {
116                    if (_IsBase64(strInput[j]))
117                        str += strInput[j];
118                }
119 karl  1.2  
120                Array<Uint8> retArray;
121 karl  1.1  
122                // Return if the input is zero length
123                if (str.length() == 0)
124 karl  1.2          return retArray;
125 karl  1.1  
126                //  comment
127 kumpf 1.8      for (size_t i=0; i < str.length();i+=4)
128 karl  1.1      {
129                    char c1='A',c2='A',c3='A',c4='A';
130            
131                    c1 = str[i];
132                    if (i+1<str.length())
133                        c2 = str[i+1];
134                    if (i+2<str.length())
135                        c3 = str[i+2];
136                    if (i+3<str.length())
137                        c4 = str[i+3];
138            
139                    Uint8 by1=0,by2=0,by3=0,by4=0;
140                    by1 = _Decode(c1);
141                    by2 = _Decode(c2);
142                    by3 = _Decode(c3);
143                    by4 = _Decode(c4);
144                    //cout << "base::64decode bytes" <<
145                    //      " 1 " << c1 << " " << by1 <<
146                    //      " 2 " << c2 << " " << by2 <<
147                    //      " 3 " << c3 << " " << by3 <<
148                    //      " 4 " << c4 << " " << by4 << endl;
149 karl  1.1          
150                    // append first byte by shifting
151 karl  1.2          retArray.append( (by1<<2)|(by2>>4) );
152 karl  1.1  
153                    // append second byte if not padding
154                    if (c3 != '=')
155 karl  1.2              retArray.append( ((by2&0xf)<<4)|(by3>>2) );
156 karl  1.1  
157                    if (c4 != '=')
158 karl  1.2              retArray.append( ((by3&0x3)<<6)|by4 );
159 karl  1.1      }
160            
161 karl  1.2      return retArray;
162 karl  1.1  };
163            
164            //**********************************************************
165            /*  Encode thanslates one six-bit pattern into a base-64 character.
166                Unsigned char is used to represent a six-bit stream of date.
167                
168            */
169            inline PEGASUS_COMMON_LINKAGE char Base64::_Encode(Uint8 uc)
170            {
171                if (uc < 26)
172                    return 'A'+uc;
173            
174                if (uc < 52)
175                    return 'a'+(uc-26);
176            
177                if (uc < 62)
178                    return '0'+(uc-52);
179            
180                if (uc == 62)
181                    return '+';
182            
183 karl  1.1      return '/';
184            };
185            
186             //Helper function returns true is a character is a valid base-64 character and false otherwise.
187            
188            inline Boolean Base64::_IsBase64(char c)
189            {
190            
191                if (c >= 'A' && c <= 'Z')
192                    return true;
193            
194                if (c >= 'a' && c <= 'z')
195                    return true;
196            
197                if (c >= '0' && c <= '9')
198                    return true;
199            
200                if (c == '+')
201                    return true;
202            
203                if (c == '/')
204 karl  1.1          return true;
205            
206                if (c == '=')
207                    return true;
208            
209                return false;
210            };
211             
212             // Translate one base-64 character into a six bit pattern
213            inline Uint8 Base64::_Decode(char c)
214            {
215                if (c >= 'A' && c <= 'Z')
216                    return c - 'A';
217                if (c >= 'a' && c <= 'z')
218                    return c - 'a' + 26;
219            
220                if (c >= '0' && c <= '9')
221                    return c - '0' + 52;
222            
223                if (c == '+')
224                    return 62;
225 karl  1.1  
226                return 63;
227            };
228            
229            
230            PEGASUS_NAMESPACE_END

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2