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

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2