view b64_de.c @ 30:427e1aac0bd7

not run.
author koba <koba@cr.ie.u-ryukyu.ac.jp>
date Fri, 31 Dec 2010 15:50:44 +0900
parents 435ac1cdb64e
children
line wrap: on
line source

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

struct tagTT
{
  unsigned char buf;
  char *cont;
  int nlen;
};

unsigned char CtoNum( int c );
int GetNumB64( struct tagTT *pWork );

int decode(char *cont, FILE *outfile)
{
  int rw;
  struct tagTT work;
  
  work.buf = 0;
  work.nlen = 0;
  work.cont = cont;
  
  rw = GetNumB64( &work );
  while ( rw != -1 ) 
    {
      putc( rw, outfile );
      rw = GetNumB64( &work );
    }
  return 0;
}


int GetNumB64( struct tagTT *pWork )
{
  int wr;
  unsigned char w;
  unsigned char r;
  
  wr = *pWork->cont;
  pWork->cont++;
  if ( wr == '\0' || wr == '=' )
    return -1;
  
  while(wr == '\n' || wr == '\t')
    {
      wr = *pWork->cont;
      pWork->cont++;
    }

  w = CtoNum( wr );
  if ( pWork->nlen == 0 )
    {
      unsigned char w2;

      wr = *pWork->cont;
      pWork->cont++;
      if ( wr != '\0' && wr != '=' )
	w2 = CtoNum( wr );
      else
	w2 = 0;

      pWork->buf = w << 2;
      w = w2;
      pWork->nlen = 6;
    }

  pWork->nlen -= 2;	

  r = pWork->buf | ( w >> pWork->nlen );

  pWork->buf = ( w << ( 8 - pWork->nlen ) );
  return r;
}

unsigned char CtoNum( int 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;
  if ( c == '/' ) return 63;
  return -1;
}