Files
rdkit/Code/DataStructs/base64.cpp
2010-09-26 17:04:37 +00:00

141 lines
4.6 KiB
C++
Executable File

// $Id$
//
// Copyright (c) 2002-2008 greg landrum and rational discovery llc
//
// @@ All Rights Reserved @@
// This file is part of the RDKit.
// The contents are covered by the terms of the BSD license
// which is included in the file license.txt, found at the root
// of the RDKit source tree.
//
#include <iostream>
#include <cstring>
#include "base64.h"
// Encoding table from RFC 2045
//
// Value Encoding Value Encoding Value Encoding Value Encoding
// 0 A 17 R 34 i 51 z
// 1 B 18 S 35 j 52 0
// 2 C 19 T 36 k 53 1
// 3 D 20 U 37 l 54 2
// 4 E 21 V 38 m 55 3
// 5 F 22 W 39 n 56 4
// 6 G 23 X 40 o 57 5
// 7 H 24 Y 41 p 58 6
// 8 I 25 Z 42 q 59 7
// 9 J 26 a 43 r 60 8
// 10 K 27 b 44 s 61 9
// 11 L 28 c 45 t 62 +
// 12 M 29 d 46 u 63 /
// 13 N 30 e 47 v
// 14 O 31 f 48 w (pad) =
// 15 P 32 g 49 x
// 16 Q 33 h 50 y
const int MaxLineLength=72;
char *Base64Encode(const char *inText,const unsigned int inLen){
return Base64Encode((const unsigned char *)inText,inLen);
}
char *Base64Encode(const unsigned char *inText,const unsigned int inLen){
// Notes:
// - whoever calls us is responsible for free'ing the result we return
// - we cheat and don't worry about breaking lines
static unsigned char transTable[64]={'A','B','C','D','E','F','G','H',
'I','J','K','L','M','N','O','P',
'Q','R','S','T','U','V','W','X',
'Y','Z','a','b','c','d','e','f',
'g','h','i','j','k','l','m','n',
'o','p','q','r','s','t','u','v',
'w','x','y','z','0','1','2','3',
'4','5','6','7','8','9','+','/'};
char *res;
int resSize;
resSize = (4*inLen)/3;
while(resSize % 4) resSize++;
res = new char[resSize+1];
unsigned int i = 0;
int pos = 0;
while(i < inLen){
res[pos++]= transTable[inText[i]>>2];
if( i+1 < inLen){
res[pos++]= transTable[((inText[i]&3)<<4)|(inText[i+1]>>4)];
if(i+2 < inLen){
res[pos++] = transTable[((inText[i+1]&0xF)<<2)|(inText[i+2]>>6)];
res[pos++] = transTable[inText[i+2]&0x3F];
} else {
// single padding
res[pos++] = transTable[((inText[i+1]&0xF)<<2)];
res[pos++] = '=';
}
} else {
// double padding
res[pos++] = transTable[((inText[i]&3)<<4)];
res[pos++] = '=';
res[pos++] = '=';
}
i += 3;
}
res[resSize] = 0;
return res;
}
char *Base64Decode(const char *inText,unsigned int *size){
// Notes:
// - whoever calls us is responsible for free'ing the result we return
unsigned char transTable[256];
int inLen = strlen(inText);
int i;
// FIX: we don't really need to build this table here
for(i= 0;i<255;i++){
transTable[i]= 0x80;
}
for(i='A';i<='Z';i++) transTable[i] = (unsigned char)i-'A';
for(i='a';i<='z';i++) transTable[i] = (unsigned char)i-'a'+26;
for(i='0';i<='9';i++) transTable[i] = (unsigned char)i-'0'+52;
transTable[static_cast<int>('+')]=62;
transTable[static_cast<int>('/')]=63;
int outLen = 3*inLen/4;
char *res = new char[outLen];
res[outLen-1]=0;
int pos = 0;
i = 0;
// decode 4 bytes at a time
unsigned char block[4];
int nInBlock=0;
while(i < inLen){
unsigned char c = inText[i];
// above we set 0x80 as the junk marker in the translation table
if ( !(transTable[c]&0x80) ){
block[nInBlock++] = transTable[c];
if( nInBlock == 4 ) {
// finished a block
res[pos++] = (block[0]<<2)|(block[1]>>4);
res[pos++] = (block[1]<<4)|(block[2]>>2);
res[pos++] = (block[2]<<6)|block[3];
nInBlock = 0;
}
}
i++;
}
// okay, now there can be 2 or 3 chars remaining to be processed
// (before the padding)
if(nInBlock>1){
res[pos++] = (block[0]<<2)|(block[1]>>4);
if(nInBlock > 2){
res[pos++] = (block[1]<<4)|(block[2]>>2);
res[pos] = (block[2]<<6);
}
}
*size = pos;
return res;
}