This repository has been archived on 2024-04-08. You can view files and clone it, but cannot push or open issues or pull requests.
deb-goldedplus/goldlib/gall/gutlcode.cpp
2005-10-20 21:41:32 +00:00

292 lines
6.9 KiB
C++

// This may look like C code, but it is really -*- C++ -*-
// ------------------------------------------------------------------
// The Goldware Library
// Copyright (C) 1990-1999 Odinn Sorensen
// Copyright (C) 1999-2000 Alexander S. Aganichev
// ------------------------------------------------------------------
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public
// License along with this program; if not, write to the Free
// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
// MA 02111-1307, USA
// ------------------------------------------------------------------
// $Id$
// ------------------------------------------------------------------
// Decoder/encoders.
// ------------------------------------------------------------------
#ifdef __GNUG__
#pragma implementation "gutlcode.h"
#endif
// ------------------------------------------------------------------
#include <gstrall.h>
#include <gutlmisc.h>
#include <gutlcode.h>
// ------------------------------------------------------------------
uucode_engine::uucode_engine() {
initialized = false;
}
// ------------------------------------------------------------------
void uucode_engine::initialize() {
// Set up the default translation table.
int i, j;
for(i=0; i<' '; i++)
table.ch[i] = -1;
for(i=' ',j=0; i<' '+64; i++,j++)
table.ch[i] = j;
for(i=' '+64; i<256; i++)
table.ch[i] = -1;
table.ch['`' & 0xff] = table.ch[' ' & 0xff]; // A common mutation
table.ch['~' & 0xff] = table.ch['^' & 0xff]; // Another common mutation
table.blank = ' ';
// Set up the line length table, to avoid computing lotsa * and / ...
table.len[0] = 1;
for(i=1,j=5; i<=60; i+=3, j+=4)
table.len[i] = (table.len[i+1] = (table.len[i+2] = j));
initialized = true;
complete = false;
}
// ------------------------------------------------------------------
char* uucode_engine::decode(char* outputbuffer, const char* inputbuffer) {
char buf[80];
char* o = outputbuffer;
int len = strlen(strcpy(buf, inputbuffer));
if(not initialized)
initialize();
if(strnieql(buf, "begin ", 6)) {
return o;
}
else if(strieql(buf, "end")) {
initialized = false;
complete = true;
return o;
}
else if(strieql(buf, "table")) {
defining_table = true;
for(int c=0; c<256; c++)
table.ch[c] = -1;
table_index = 0;
return o;
}
if(defining_table) {
char* p = buf + len - 1;
*p = ' ';
while(*p == ' ')
*p-- = 0;
p = buf;
char c;
while((c = *p) != 0) {
if(table_index == 0)
table.blank = c;
table.ch[c & 0xff] = table_index++;
if(table_index >= 64) {
defining_table = false;
break;
}
p++;
}
return o;
}
// Get the binary line length.
int n = table.ch[*buf & 0xff];
if(n > 0) {
// Pad with blanks.
int c = len;
char* i = buf + c;
int rlen = table.len[n];
while(c < rlen) {
*i++ = table.blank;
c++;
}
// Output a group of 3 bytes (4 input characters).
i = buf + 1;
while(n > 0) {
*(o++) = (char)((table.ch[*i & 0xff] << 2) | (table.ch[i[1] & 0xff] >> 4));
n--;
if(n) {
*(o++) = (char)((table.ch[i[1] & 0xff] << 4) | (table.ch[i[2] & 0xff] >> 2));
n--;
}
if(n) {
*(o++) = (char)((table.ch[i[2] & 0xff] << 6) | table.ch[i[3] & 0xff]);
n--;
}
i += 4;
}
}
*o = NUL;
return o;
}
// ------------------------------------------------------------------
char* quoted_printable_engine::decode(char* outputbuffer, const char* inputbuffer) {
char c;
char* o = outputbuffer;
const char* i = inputbuffer;
while((c = *i) != NUL) {
if(c == '=') {
char c1 = i[1];
char c2 = i[2];
if(isxdigit(c1) and isxdigit(c2)) {
// Decode the character
c = (char)((xtoi(c1) << 4) | xtoi(c2));
i += 2;
}
}
//else if(c == '_') {
// c = ' ';
//}
*o++ = c;
i++;
}
*o = NUL;
return o;
}
// ------------------------------------------------------------------
char* base64_engine::decode(char* outputbuffer, const char* inputbuffer) {
char* o = outputbuffer;
const char* i = inputbuffer;
int shift = 0;
uint32_t accum = 0;
while(*i) {
char c = *i;
uint value = (uint)-1;
if((c >= 'A') and (c <= 'Z')) value = c - 'A';
else if((c >= 'a') and (c <= 'z')) value = 26 + c - 'a';
else if((c >= '0') and (c <= '9')) value = 52 + c - '0';
else if(c == '+') value = 62;
else if(c == '/') value = 63;
else if(c == '=') value = (uint)-2;
if(value >= 64)
break;
else {
accum <<= 6;
shift += 6;
accum |= value;
if(shift >= 8) {
shift -= 8;
value = (uint)(accum >> shift);
c = (byte)(value & 0xFF);
*o++ = c;
}
}
i++;
}
*o = NUL;
return o;
}
// ------------------------------------------------------------------
char base64_engine::table[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* base64_engine::encode(char* outputbuffer, const char* inputbuffer, uint length, bool padding) {
uint l = length;
char* o = outputbuffer;
const char* i = inputbuffer;
while(l > 0) {
char c1 = i[0];
char c2 = l > 1 ? i[1] : '\0';
char c3 = l > 2 ? i[2] : '\0';
int pads = l > 2 ? 0 : (3 - l);
o[0] = table[c1 >> 2];
o[1] = table[((c1 & 0x03) << 4) | ((c2 & 0xF0) >> 4)];
if(pads == 2) {
if(padding) {
o[2] = '=';
o[3] = '=';
}
else {
o[2] = NUL;
o[3] = NUL;
}
}
else if(pads == 1) {
o[2] = table[((c2 & 0x0F) << 2) | ((c3 & 0xC0) >> 6)];
if(padding) {
o[3] = '=';
}
else {
o[3] = NUL;
}
}
else {
o[2] = table[((c2 & 0x0F) << 2) | ((c3 & 0xC0) >> 6)];
o[3] = table[c3 & 0x3F];
}
o += 4;
if(l < 3)
break;
l -= 3;
i += 3;
}
*o = NUL;
return o;
}
// ------------------------------------------------------------------