/* -----------------------------------------------------------------------------
* encoding.c
*
* This file implements a number of filters for encoding and decoding data
* in various formats including URL encoding and Base 64.
*
* Author(s) : David Beazley (beazley@cs.uchicago.edu)
* Mike Sliczniak (mzsliczn@midway.uchicago.edu)
*
* Copyright (C) 1999-2000. The University of Chicago
* See the file LICENSE for information on usage and redistribution.
* ----------------------------------------------------------------------------- */
static char cvsroot[] = "$Header: /home/pastacvs/cvs-rep/vermicelli/tot/src/SWILL-0.1/Source/SWILL/encoding.c,v 1.1 2005/01/27 08:46:25 dillema Exp $";
#include "swillint.h"
/* -----------------------------------------------------------------------------
* swill_url_decode()
*
* Decodes a url-encoded string. '+' characters are converted into spaces
* and '%xx' sequences are converted into their character equivalent.
*
* in Is any file-like object supporting a Getc method.
* out Is any file-like object supporting a Putc method.
*
* ----------------------------------------------------------------------------- */
void
swill_url_decode(DOH *in, DOH *out) {
int ch, nch;
int state,i;
while (1) {
ch = Getc(in);
if (ch == EOF) return;
if (ch == '+') {
Putc(' ',out);
} else {
if (ch == '%') {
nch = 0;
for (i = 0; i < 2; i++) {
nch = nch << 4;
ch = Getc(in);
if (ch == EOF) {
Putc(ch,out);
return;
}
if (isxdigit(ch)) {
if (isdigit(ch)) {
nch += (ch - '0');
} else {
nch += (tolower(ch) - 'a') + 10;
}
}
}
Putc(nch,out);
} else {
Putc(ch,out);
}
}
}
}
/* -----------------------------------------------------------------------------
* swill_url_encode()
*
* Encodes a string. Spaces are converted into '+' and all other non-valid
* characters are converted into a '%xx' sequence.
* ----------------------------------------------------------------------------- */
void
swill_url_encode(DOH *in, DOH *out) {
int ch, nch;
int state,i;
char *trans = "0123456789abcdef";
while (1) {
ch = Getc(in);
if (ch == EOF) return;
if (ch == ' ') {
Putc('+',out);
} else if (isalnum(ch) || (ch == '_')) {
Putc(ch,out);
} else {
int i;
Putc('%',out);
i = (ch & 0xf0) >> 4;
Putc(trans[i],out);
i = (ch & 0x0f);
Putc(trans[i],out);
}
}
}
/* -----------------------------------------------------------------------------
* swill_url_encoder()
*
* Function given to DohEncoder for printf conversions.
* ----------------------------------------------------------------------------- */
DOH *
swill_url_encoder(DOH *s) {
DOH *ns = NewString("");
swill_url_encode(s,ns);
return ns;
}
/* -----------------------------------------------------------------------------
* swill_pre_encode()
*
* Take a piece of text and perform a few character substitutions for HTML.
* ----------------------------------------------------------------------------- */
void
swill_pre_encode(DOH *in, DOH *out) {
int ch;
while (1) {
ch = Getc(in);
if (ch == EOF) return;
else if (ch == '<') Write(out,"<",4);
else if (ch == '>') Write(out,">",4);
else if (ch == '&') Write(out,"&",5);
else Putc(ch,out);
}
}
/* -----------------------------------------------------------------------------
* swill_pre_encoder()
*
* Encoder function registered with Printf
* ----------------------------------------------------------------------------- */
DOH *
swill_pre_encoder(DOH *s) {
DOH *ns = NewString("");
int ch;
while (1) {
ch = Getc(s);
if (ch == EOF) return ns;
else if (ch == '<') Write(ns,"<",4);
else if (ch == '>') Write(ns,">",4);
else if (ch == '&') Write(ns,"&",5);
else Putc(ch,ns);
}
}
/* -----------------------------------------------------------------------------
* Base64 decoding
* ----------------------------------------------------------------------------- */
static char *base64chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
static unsigned char base64map[256];
static int base64init = 0;
static void init_base64() {
int i;
for (i = 0; i < 256; i++) {
base64map[i] = 255;
}
for (i = 0; i < strlen(base64chars); i++) {
base64map[base64chars[i]] = i;
}
}
/* -----------------------------------------------------------------------------
* swill_base64_decode()
*
* Decode a base64 encoded data stream.
*
* in - Any file-like object with a Getc method. The base64 input stream.
* out - Any file-like object with a Putc method. The base64 output stream.
*
* This function is primarily used to decode passwords.
* ----------------------------------------------------------------------------- */
void
swill_base64_decode(DOH *in, DOH *out) {
char group[4], decode[3];
int grpi;
int i,ch;
int nbytes;
if (!base64init) {
init_base64();
base64init = 1;
}
while (1) {
/* Read in a triplet */
for (i = 0; i < 4; i++) {
l1:
ch = Getc(in);
if (ch == EOF) break;
if (base64map[ch] == 255) goto l1;
group[i] = ch;
}
/* Pad out to a multiple of four */
while (i < 4) {
group[i] = '=';
i++;
}
/* Figure out how many bytes are to be read */
nbytes = 3;
for (i = 4; i > 0; i--) {
if (group[i-1] != '=') break;
nbytes--;
}
/* Decode the string */
grpi = 0;
for (i = 0; i < 4; i++) {
grpi = grpi << 6;
grpi = grpi + ((base64map[group[i]]) & 63);
}
if (nbytes >= 1) {
Putc((grpi >> 16) & 0xff, out);
}
if (nbytes >= 2) {
Putc((grpi >> 8) & 0xff, out);
}
if (nbytes >= 3) {
Putc(grpi & 0xff, out);
}
if ((ch == EOF) || (nbytes < 3)) return;
}
}
syntax highlighted by Code2HTML, v. 0.9.1