// Base64Encoder.cpp
//
// Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005 Matthew Flood
// See file AUTHORS for contact information
//
// This file is part of RudeConfig.
//
// RudeConfig is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2, or (at your option)
// any later version.
//
// RudeConfig is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with RudeConfig; (see COPYING) if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
// 02111-1307, USA.
//------------------------------------------------------------------------
#include "Base64Encoder.h"
#ifndef INCLUDED_CSTRING
#include <string.h>
#define INCLUDED_CSTRING
#endif
namespace rude{
namespace config{
// translates a 6 bit char into a base-64 character
//
inline char Base64Encoder::c_encode(char uc)
{
if (uc < 26)
{
return 'A'+uc;
}
if (uc < 52)
{
return 'a'+(uc-26);
}
if (uc < 62)
{
return '0'+(uc-52);
}
if (uc == 62)
{
return '+';
}
return '/';
}
// translates one base-64 character into a six-bit pattern
//
inline unsigned char Base64Encoder::c_decode(char c)
{
if (c >= 'A' && c <= 'Z')
{
return c - 'A';
}
if (c >= 'a' && c <= 'z')
{
return c - 'a' + 26;
}
if (c >= '0' && c <= '9')
{
return c - '0' + 52;
}
if (c == '+')
{
return 62;
};
return 63;
}
char * Base64Encoder::encode(const char *data, int datalength, int &outlength)
{
int linelength=0;
outlength=0;
if (data == (char*) 0 || datalength == 0)
{
return (char*) 0;
};
char *retval=new char[datalength * 2];
const char *crlf="\n";
int crlflength=strlen(crlf);
int maxlinelength=76;
for (int i=0; i<datalength; i+=3)
{
unsigned char by1, by2, by3, by4, by5, by6, by7;
by1 = data[i];
if (i+1 < datalength)
{
by2 = data[i+1];
}
else
{
by2=0;
}
if (i+2 < datalength)
{
by3 = data[i+2];
}
else
{
by3=0;
}
by4 = by1>>2;
by5 = ((by1 & 0x3)<<4)|( by2>>4 );
by6 = ((by2 & 0xf)<<2)|( by3>>6 );
by7 = by3 & 0x3f;
retval[outlength++] = c_encode(by4);
linelength++;
retval[outlength++] = c_encode(by5);
linelength++;
if (i+1 < datalength)
{
retval[outlength++]= c_encode(by6);
linelength++;
}
else
{
retval[outlength++]= '=';
linelength++;
}
if (i+2<datalength)
{
retval[outlength++]= c_encode(by7);
linelength++;
}
else
{
retval[outlength++]= '=';
linelength++;
};
// only set linelength if maxlinelength > 0
//
if (maxlinelength != 0 && linelength >= maxlinelength)
{
for(int y=0; y< crlflength; y++)
{
retval[outlength++]= crlf[y];
}
// we just created a line - reset current linelength
//
linelength=0;
}
};
retval[outlength]=(char) NULL;
return retval;
}
char * Base64Encoder::decode(const char *data, int datalength, int &outlength)
{
// Error if incoming data is NULL
// Error if nothing to decode
//
if(data == (char *) 0 || datalength == 0)
{
return (char*) 0;
}
outlength=0;
// rawlength is the length of the encoded data excluding
// any non-base64 characters
//
int rawlength=0;
// create return buffer
//
char *outbuffer=new char[datalength];
// copy all base64 characters into outbuffer,
// in other words, strip away CRLF's and non-b64 characters...
//
for (int j=0;j < datalength; j++)
{
if (IsBase64(data[j]))
{
outbuffer[rawlength++]= data[j];
}
}
// there's no base64 characters to decode
//
if (rawlength == 0 || datalength == 0)
{
delete [] outbuffer;
return (char*) NULL;
}
for (int i=0; i<rawlength; i+=4)
{
char c1 = outbuffer[i];
char c2='A',c3='A',c4='A';
if (i+1 < rawlength)
{
c2 = outbuffer[i+1];
};
if (i+2 < rawlength)
{
c3 = outbuffer[i+2];
};
if (i+3 < rawlength)
{
c4 = outbuffer[i+3];
};
unsigned char by1,by2,by3,by4;
by1 = c_decode(c1);
by2 = c_decode(c2);
by3 = c_decode(c3);
by4 = c_decode(c4);
outbuffer[outlength]=( (by1<<2)|(by2>>4) );
outlength++;
if (c3 != '=')
{
outbuffer[outlength]=( ((by2&0xf)<<4)|(by3>>2) );
outlength++;
}
if (c4 != '=')
{
outbuffer[outlength]=( ((by3&0x3)<<6)|by4 );
outlength++;
};
};
// NULL terminate decoded data
// in case caller ignores outlength
// for text data
//
outbuffer[outlength]=(char) 0;
return outbuffer;
}
//The last helper function returns true is a character is a valid
//base-64 character and false otherwise.
inline bool Base64Encoder::IsBase64(char c)
{
if (c >= 'A' && c <= 'Z')
{
return true;
}
if (c >= 'a' && c <= 'z')
{
return true;
}
if (c >= '0' && c <= '9')
{
return true;
}
if (c == '+')
{
return true;
};
if (c == '/')
{
return true;
};
if (c == '=')
{
return true;
};
return false;
}
}}
syntax highlighted by Code2HTML, v. 0.9.1