Commit b0010996 authored by Marco Govoni's avatar Marco Govoni
Browse files

Added Base64 Library.

parent 22827ddb
/*
Copyright (C) 2015-2016 M. Govoni
This file is distributed under the terms of the
GNU General Public License. See the file `License'
in the root directory of the present distribution,
or http://www.gnu.org/copyleft/gpl.txt .
This file is part of WEST.
Contributors to this file:
Huihuo Zheng
*/
#include <iostream>
#include "Base64Transcoder.h"
#include <complex>
#include "Base64.h"
using namespace std;
void Base64::encode(double *a, int n, char *b) {
int nb = sizeof(double)*n;
bt.encode(nb, (unsigned char*) &a[0], b);
}
void Base64::encode(complex<double> *a, int n, char *b) {
int nb = sizeof(complex<double>)*n;
bt.encode(nb, (unsigned char*) &a[0], b);
}
void Base64::decode(char *b, int n, double *a) {
int nb = bt.nchars(sizeof(double)*n);
bt.decode(nb, b, (unsigned char*) &a[0]);
}
void Base64::decode(char *b, int n, complex<double> *a) {
int nb = bt.nchars(sizeof(complex<double>)*n);
bt.decode(nb, b, (unsigned char*) &a[0]);
}
void Base64::byteswap_double(int n, double* const x) {
bt.byteswap_double(n, x);
}
void Base64::byteswap_complex(int n, complex<double>* const x) {
bt.byteswap_double(n*2, (double*) x);
}
extern "C" {
#include "Base64.h"
Base64 *Base64__new() {
return new Base64();
}
void Base64__encode_double(Base64 *This, double *a, int n, char* to) {
This->encode(a, n, to);
}
void Base64__encode_complex(Base64 *This, complex<double> *a, int n, char* to) {
This->encode(a, n, to);
}
void Base64__decode_double(Base64 *This, char* from, int n, double *a) {
This->decode(from, n, a);
}
void Base64__decode_complex(Base64 *This, char* from, int n, complex<double> *a) {
This->decode(from, n, a);
}
void Base64__byteswap_double(Base64 *This, int n, double *x) {
This->byteswap_double(n, x);
}
void Base64__byteswap_complex(Base64 *This, int n, complex<double> *x) {
This->byteswap_complex(n, x);
}
}
/*
Copyright (C) 2015-2016 M. Govoni
This file is distributed under the terms of the
GNU General Public License. See the file `License'
in the root directory of the present distribution,
or http://www.gnu.org/copyleft/gpl.txt .
This file is part of WEST.
Contributors to this file:
Huihuo Zheng
*/
#ifndef BASE64__H__
#define BASE64__H__
#include <iostream>
#include "Base64Transcoder.h"
#include <complex>
using namespace std;
class Base64 {
Base64Transcoder bt;
public:
void encode(double *a, int n, char *b);
void decode(char *b, int n, double *);
void encode(complex<double> *a, int n, char *b);
void decode(char *b, int n, complex<double> *);
void byteswap_double(int n, double* const);
void byteswap_complex(int n, complex<double>* const);
};
#endif
!
! Copyright (C) 2015-2016 M. Govoni
! This file is distributed under the terms of the
! GNU General Public License. See the file `License'
! in the root directory of the present distribution,
! or http://www.gnu.org/copyleft/gpl.txt .
!
! This file is part of WEST.
!
! Contributors to this file:
! Huihuo Zheng
!
!-------------------------------------------------------------------
module Base64_module
!-------------------------------------------------------------------
!
USE, INTRINSIC :: ISO_C_Binding, ONLY : C_DOUBLE, C_DOUBLE_COMPLEX, C_CHAR, C_SIGNED_CHAR, C_PTR, C_NULL_PTR, C_INT
!
IMPLICIT NONE
!
TYPE Base64_type
TYPE(C_PTR) :: object = C_NULL_PTR
END TYPE Base64_type
!
INTERFACE
!
FUNCTION C_Base64__new() RESULT(this) BIND(C, NAME="Base64__new")
IMPORT
TYPE(C_PTR) :: this
END FUNCTION C_Base64__new
!
FUNCTION C_Base64__delete(this) BIND (C, NAME="Base64__delete")
IMPORT
TYPE(C_PTR), VALUE :: this
END FUNCTION C_Base64__delete
!
SUBROUTINE C_Base64__encode_double(this, from, n, to) BIND(C, NAME="Base64__encode_double")
IMPORT
INTEGER(C_INT), VALUE, INTENT(IN) :: n
REAL(C_DOUBLE), INTENT(IN) :: from(*)
CHARACTER(C_CHAR), INTENT(OUT) :: to(*)
TYPE(C_PTR), VALUE :: this
END SUBROUTINE C_Base64__encode_double
!
SUBROUTINE C_Base64__decode_double(this, from, n, to) BIND(C, NAME="Base64__decode_double")
IMPORT
INTEGER(C_int), VALUE, INTENT(IN) :: n
REAL(C_DOUBLE), INTENT(IN) :: to(*)
CHARACTER(C_CHAR), INTENT(OUT) :: from(*)
TYPE(C_PTR), VALUE :: this
END SUBROUTINE C_Base64__decode_double
!
SUBROUTINE C_Base64__encode_complex(this, from, n, to) BIND(C, NAME="Base64__encode_complex")
IMPORT
INTEGER(C_INT), VALUE, INTENT(IN) :: n
COMPLEX(C_DOUBLE_COMPLEX), INTENT(IN) :: from(*)
CHARACTER(C_CHAR), INTENT(OUT) :: to(*)
TYPE(C_PTR), VALUE :: this
END SUBROUTINE C_Base64__encode_complex
!
SUBROUTINE C_Base64__decode_complex(this, from, n, to) BIND(C, NAME="Base64__decode_complex")
IMPORT
INTEGER(C_INT), VALUE, INTENT(IN) :: n
COMPLEX(C_DOUBLE_COMPLEX), INTENT(IN) :: to(*)
CHARACTER(C_CHAR), INTENT(OUT) :: from(*)
TYPE(C_PTR), VALUE :: this
END SUBROUTINE C_Base64__decode_complex
!
SUBROUTINE C_Base64__byteswap_complex(this, n, to) BIND(C, NAME="Base64__byteswap_complex")
IMPORT
INTEGER(C_INT), VALUE, INTENT(IN) :: n
COMPLEX(C_DOUBLE_COMPLEX), INTENT(INOUT) :: to(*)
TYPE(C_PTR), VALUE :: this
END SUBROUTINE C_Base64__byteswap_complex
!
SUBROUTINE C_Base64__byteswap_double(this, n, to) BIND(C, NAME="Base64__byteswap_double")
IMPORT
INTEGER(C_INT), VALUE, INTENT(IN) :: n
REAL(C_DOUBLE), INTENT(INOUT) :: to(*)
TYPE(C_PTR), VALUE :: this
END SUBROUTINE C_Base64__byteswap_double
!
END INTERFACE
!
END MODULE
////////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2008 The Regents of the University of California
//
// This file is part of Qbox
//
// Qbox is distributed under the terms of the GNU General Public License
// as published by the Free Software Foundation, either version 2 of
// the License, or (at your option) any later version.
// See the file COPYING in the root directory of this distribution
// or <http://www.gnu.org/licenses/>.
//
////////////////////////////////////////////////////////////////////////////////
//
// Base64Transcoder.C
//
////////////////////////////////////////////////////////////////////////////////
#include "Base64Transcoder.h"
#include <iostream>
#include <cstdio>
#include <string>
#include <cstring> // memcpy
#include <cassert>
using namespace std;
////////////////////////////////////////////////////////////////////////////////
Base64Transcoder::Base64Transcoder()
{
// initialize encoding/decoding tables
for (int i = 0; i < 26; i++)
{
etable[i] = 'A' + i;
etable[26 + i] = 'a' + i;
}
for (int i = 0; i < 10; i++)
{
etable[52 + i] = '0' + i;
}
etable[62] = '+';
etable[63] = '/';
for (int i = 0; i < 255; i++)
{
dtable[i] = 0x80;
}
for (int i = 'A'; i <= 'Z'; i++)
{
dtable[i] = 0 + (i - 'A');
}
for (int i = 'a'; i <= 'z'; i++)
{
dtable[i] = 26 + (i - 'a');
}
for (int i = '0'; i <= '9'; i++)
{
dtable[i] = 52 + (i - '0');
}
dtable['+'] = 62;
dtable['/'] = 63;
dtable['='] = 0;
}
////////////////////////////////////////////////////////////////////////////////
int Base64Transcoder::encode(int nbytes, const byte* const from, char* const to)
{
const byte* fptr = from;
char* tptr = to;
int n3 = nbytes / 3; // number of groups of three bytes
while ( n3-- > 0 )
{
byte ig0 = *fptr++;
byte ig1 = *fptr++;
byte ig2 = *fptr++;
*tptr++ = etable[ig0 >> 2];
*tptr++ = etable[((ig0 & 3) << 4) | (ig1 >> 4)];
*tptr++ = etable[((ig1 & 0xF) << 2) | (ig2 >> 6)];
*tptr++ = etable[ig2 & 0x3F];
}
int nr = nbytes % 3; // remaining bytes
if ( nr == 2 )
{
byte ig0 = *fptr++;
byte ig1 = *fptr++;
byte ig2 = 0;
*tptr++ = etable[ig0 >> 2];
*tptr++ = etable[((ig0 & 3) << 4) | (ig1 >> 4)];
*tptr++ = etable[((ig1 & 0xF) << 2) | (ig2 >> 6)];
*tptr++ = '=';
}
else if ( nr == 1 )
{
byte ig0 = *fptr++;
byte ig1 = 0;
*tptr++ = etable[ig0 >> 2];
*tptr++ = etable[((ig0 & 3) << 4) | (ig1 >> 4)];
*tptr++ = '=';
*tptr++ = '=';
}
return 0;
}
////////////////////////////////////////////////////////////////////////////////
int Base64Transcoder::decode(const int nchars, const char* const from,
byte* const to)
{
// Decode Base64 chars in array "from" into bytes in array "to"
// White space and new lines are skipped
// extra characters at end that do not form a valid group of 4 chars are
// ignored.
// nchars: number of chars in array "from"
// the number of bytes successfully translated is returned
byte a0,a1,a2,a3,b0,b1,b2,b3;
int c;
const char* fptr = from;
const char* const fptr_end = from+nchars+1;
byte* tptr = to;
while ( fptr < fptr_end-4 )
{
// get 4 valid characters from input string
do
{
c = *fptr++;
}
while ( (c <= ' ') && (fptr < fptr_end) );
if ( fptr >= fptr_end )
{
#ifdef DEBUG
cerr << " Base64Transcoder::decode: end of string reached reading c0 "
<< endl;
#endif
break;
}
a0 = (byte) c;
b0 = (byte) dtable[c];
do
{
c = *fptr++;
}
while ( (c <= ' ') && (fptr < fptr_end) );
if ( fptr >= fptr_end )
{
#ifdef DEBUG
cerr << " Base64Transcoder::decode: end of string reached reading c1 "
<< endl;
#endif
break;
}
a1 = (byte) c;
b1 = (byte) dtable[c];
do
{
c = *fptr++;
}
while ( (c <= ' ') && (fptr < fptr_end) );
if ( fptr >= fptr_end )
{
#ifdef DEBUG
cerr << " Base64Transcoder::decode: end of string reached reading c2 "
<< endl;
#endif
break;
}
a2 = (byte) c;
b2 = (byte) dtable[c];
do
{
c = *fptr++;
}
while ( (c <= ' ') && (fptr < fptr_end) );
if ( (c <= ' ') && fptr >= fptr_end )
{
#ifdef DEBUG
cerr << " Base64Transcoder::decode: end of string reached reading c3\n"
<< " (without reading a valid c3) " << endl;
#endif
break;
}
a3 = (byte) c;
b3 = (byte) dtable[c];
if ((b0|b1|b2|b3) & 0x80)
{
#ifdef DEBUG
cerr << " Base64Transcoder::decode: Illegal character in input: "
<< endl;
#endif
return tptr - to;
}
if ( a3 == '=' )
{
if ( a2 == '=' )
{
// write 1 byte only
*tptr++ = (b0 << 2) | (b1 >> 4);
}
else
{
// write 2 bytes only
*tptr++ = (b0 << 2) | (b1 >> 4);
*tptr++ = (b1 << 4) | (b2 >> 2);
}
}
else
{
// write 3 bytes
*tptr++ = (b0 << 2) | (b1 >> 4);
*tptr++ = (b1 << 4) | (b2 >> 2);
*tptr++ = (b2 << 6) | b3;
}
}
#ifdef DEBUG
if ( fptr >= fptr_end )
{
cerr << " Base64Transcoder::decode: end of string reached in input: "
<< endl;
}
#endif
return tptr - to;
}
////////////////////////////////////////////////////////////////////////////////
void Base64Transcoder::byteswap_double(size_t n, double* const x)
{
if (n==0) return;
unsigned char* c = (unsigned char*) x;
while ( n-- > 0 )
{
unsigned char tmp;
tmp = c[7]; c[7] = c[0]; c[0] = tmp;
tmp = c[6]; c[6] = c[1]; c[1] = tmp;
tmp = c[5]; c[5] = c[2]; c[2] = tmp;
tmp = c[4]; c[4] = c[3]; c[3] = tmp;
c+=8;
}
}
////////////////////////////////////////////////////////////////////////////////
void Base64Transcoder::byteswap_int(size_t n, int* const x)
{
if (n==0) return;
unsigned char* c = (unsigned char*) x;
while ( n-- > 0 )
{
unsigned char tmp;
tmp = c[3]; c[3] = c[0]; c[0] = tmp;
tmp = c[2]; c[2] = c[1]; c[1] = tmp;
c+=4;
}
}
////////////////////////////////////////////////////////////////////////////////
int Base64Transcoder::print(const string buf, ostream& o)
{
return print(buf.size(),buf.c_str(),o);
}
////////////////////////////////////////////////////////////////////////////////
int Base64Transcoder::print(int nchars, const char* const buf, ostream& o)
{
const char* b = buf;
int nl = nchars / 72;
// compute total size of output string including newline chars
int outstr_size = nchars + nl;
if ( nchars%72 != 0 )
outstr_size++;
char* outstr = new char[outstr_size];
char* p = outstr;
// assemble output string
for ( int i = 0; i < nl; i++ )
{
memcpy(p,b,72*sizeof(char));
p[72] = '\n';
b += 72;
p += 73;
}
if ( nchars%72 != 0 )
{
int size = nchars%72;
memcpy(p,b,size*sizeof(char));
p[size] = '\n';
}
o.write(outstr,outstr_size);
delete [] outstr;
return 0;
}
////////////////////////////////////////////////////////////////////////////////
int Base64Transcoder::print(const string buf, FILE* outfile)
{
return print(buf.size(),buf.c_str(),outfile);
}
////////////////////////////////////////////////////////////////////////////////
int Base64Transcoder::print(int nchars, const char* const buf, FILE* outfile)
{
const char* b = buf;
int nl = nchars / 72;
// compute total size of output string including newline chars
int outstr_size = nchars + nl;
if ( nchars%72 != 0 )
outstr_size++;
char* outstr = new char[outstr_size];
char* p = outstr;
// assemble output string
for ( int i = 0; i < nl; i++ )
{
memcpy(p,b,72*sizeof(char));
p[72] = '\n';
b += 72;
p += 73;
}
if ( nchars%72 != 0 )
{
int size = nchars%72;
memcpy(p,b,size*sizeof(char));
p[size] = '\n';
}
fwrite(outstr,sizeof(char),outstr_size,outfile);
delete [] outstr;
return 0;
}
////////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2008 The Regents of the University of California
//
// This file is part of Qbox
//
// Qbox is distributed under the terms of the GNU General Public License
// as published by the Free Software Foundation, either version 2 of
// the License, or (at your option) any later version.
// See the file COPYING in the root directory of this distribution
// or <http://www.gnu.org/licenses/>.
//
////////////////////////////////////////////////////////////////////////////////
//
// Base64Transcoder.h
//
////////////////////////////////////////////////////////////////////////////////
// $Id: Base64Transcoder.h,v 1.7 2008-09-08 15:56:18 fgygi Exp $
#ifndef BASE64TRANSCODER_H
#define BASE64TRANSCODER_H
#include <iostream>
#include <cstdio>
#include <string>
typedef unsigned char byte;
class Base64Transcoder
{
char etable[64]; // encode table
byte dtable[256]; // decode table
public:
Base64Transcoder();
int encode(int nbytes, const byte* const from, char* const to);
int decode(int nchars, const char* const from, byte* const to);
void byteswap_double(size_t n, double* const x);
void byteswap_int(size_t n, int* const x);
int print(int nchars, const char* const buf, std::ostream& o);
int print(const std::string buf, std::ostream& o);
int print(int nchars, const char* const buf, FILE* outfile);
int print(const std::string buf, FILE* outfile);
// number of chars needed to encode nbytes bytes
int nchars(int nbytes) { return 4 * ( ( nbytes + 2 ) / 3 ); }
// number of bytes needed to decode nchars chars
int nbytes(int nchars) { return 3 * ( nchars / 4 ); }
};
#endif
# Makefile for Base64
include ../../../make.inc
# location of needed modules
MODFLAGS= $(MOD_FLAG).