/**************************************************************************
*** COPYRIGHT (c) 2002 by TransNexus, Inc. ***
*** ***
*** This software is property of TransNexus, Inc. ***
*** This software is freely available under license from TransNexus. ***
*** The license terms and conditions for free use of this software by ***
*** third parties are defined in the OSP Toolkit Software License ***
*** Agreement (LICENSE.txt). Any use of this software by third ***
*** parties, which does not comply with the terms and conditions of the ***
*** OSP Toolkit Software License Agreement is prohibited without ***
*** the prior, express, written consent of TransNexus, Inc. ***
*** ***
*** Thank you for using the OSP ToolKit(TM). Please report any bugs, ***
*** suggestions or feedback to support@transnexus.com ***
*** ***
**************************************************************************/
#include "osp/osp.h"
#include "osp/osperrno.h"
#include "osp/ospb64.h"
/*** Constants ***/
#define B64FILL '='
/*** Local data ***/
static unsigned const char B64CharTab[64+1]=
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"0123456789+/";
int OSPPBase64Encode(unsigned const char *in,size_t inSize,
unsigned char *out,size_t *outSize)
{
int Fretval;
size_t x;
size_t rem;
Fretval=OSPC_ERR_B64_ENCODE_FAILED;
if((*outSize>=inSize*2)&&(*outSize>=4)&&
(inSize>0)&&(in!=OSPC_OSNULL)&&(out!=OSPC_OSNULL))
{
*outSize=0;
Fretval=OSPC_ERR_NO_ERROR;
for(x=0;x<(inSize/3);x++)
{
*out++=B64CharTab[*in>>2];
*out++=B64CharTab[((*in&0x03)<<4)+((*(in+1))>>4)];
in++;
*out++=B64CharTab[((*in&0x0F)<<2)+(*(in+1)>>6)];
in++;
*out++=B64CharTab[(*in++&0x3F)];
(*outSize)+=4;
}
if((rem=inSize%3)==1)
{
*out++=B64CharTab[(*in>>2)];
*out++=B64CharTab[((*in&0x03)<<4)];
*out++=B64FILL;
*out=B64FILL;
(*outSize)+=4;
}
else if(rem==2)
{
*out++=B64CharTab[(*in>>2)];
*out++=B64CharTab[((*in&0x03)<<4)+(*(in+1)>>4)];
in++;
*out++=B64CharTab[(*in&0x0F)<<2];
*out=B64FILL;
(*outSize)+=4;
}
}
return(Fretval);
} /* OSPPBase64Encode */
/* Ignores embedded whitespace, terminates on first '=' regardless of its position */
int OSPPBase64Decode(const char *in,size_t inSize,unsigned char *out,size_t *outSize)
{
int Fretval;
int state;
char c;
unsigned char *ix64;
size_t x;
size_t b64;
Fretval=OSPC_ERR_B64_DECODE_FAILED;
for (x=inSize-1;in[x]=='=';x--);
b64=(x+1)-((x+1)/4);
if((in!=OSPC_OSNULL)&&(out!=OSPC_OSNULL)&&(inSize>0)&&
(outSize!=OSPC_OSNULL)&&(*outSize>=b64))
{
Fretval=OSPC_ERR_NO_ERROR;
*outSize=0;
state=0;
c=0;
for(x=0;(x<inSize)&&(Fretval==OSPC_ERR_NO_ERROR);x++)
{
c=in[x];
if(!isspace((int)c))
{
if((ix64=(unsigned char *)strchr((char *)B64CharTab,c))!=NULL)
{
if((ix64>=B64CharTab)&&(ix64<(B64CharTab+64)))
{
b64=ix64-B64CharTab;
switch(state)
{
case 0:
out[(*outSize)]=(unsigned char)(b64<<2);
state=1;
break;
case 1:
out[(*outSize)++]|=(unsigned char)(b64>>4);
out[(*outSize)]=(unsigned char)((b64&0x0F)<<4);
state=2;
break;
case 2:
out[(*outSize)++]|=(b64>>2);
out[(*outSize)]=(unsigned char)((b64&0x03)<<6);
state=3;
break;
case 3:
out[(*outSize)++]|=b64;
state=0;
break;
default:
Fretval=OSPC_ERR_B64_DECODE_FAILED;
break;
}
}
else
{ /* Unexpected condition */
Fretval=OSPC_ERR_B64_DECODE_FAILED;
}
}
else
{ /* '=' or garbage */
if(c!=B64FILL)
{
Fretval=OSPC_ERR_B64_DECODE_FAILED;
}
break;
}
} /* Else: ignore whitespace */
}
}
return(Fretval);
} /* OSPPBase64Decode */
/* End of file */