"Fossies" - the Fresh Open Source Software archive 
Member "fhist-1.21/common/input/quotprinenco.c" of archive fhist-1.21.D001.tar.gz:
/*
* fhist - file history and comparison tools
* Copyright (C) 2000, 2002, 2008, 2010, 2012 Peter Miller
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or (at
* your option) any later version.
*
* This program 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
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <common/error.h>
#include <common/input/quotprinenco.h>
#include <common/input/private.h>
#include <common/trace.h>
typedef struct input_quoted_printable_encode_ty
input_quoted_printable_encode_ty;
struct input_quoted_printable_encode_ty
{
input_ty inherited;
input_ty *fp;
int state;
int c1;
int column;
int delete_on_close;
};
static void
destruct(input_ty *p)
{
input_quoted_printable_encode_ty *this;
trace(("input_quoted_printable_encode::destruct()\n{\n"));
this = (input_quoted_printable_encode_ty *)p;
input_pushback_transfer(this->fp, p);
if (this->delete_on_close)
input_delete(this->fp);
this->fp = 0; /* paranoia */
trace(("}\n"));
}
static int
hex(int n)
{
return "0123456789ABCDEF"[n & 15];
}
static int
get(input_ty *p)
{
input_quoted_printable_encode_ty *this;
int c;
trace(("input_quoted_printable_encode::get()\n{\n"));
this = (input_quoted_printable_encode_ty *)p;
switch (this->state)
{
case 1:
/*
* we have given half of a '=' '\n' sequence.
* Give the secoind byte, and resume normal
*/
c = '\n';
this->column = 0;
this->state = 0;
break;
case 3:
/*
* we have seen end of file without a newline
* we have sent '=', now send '\n'
*/
c = '\n';
this->state = 4;
break;
case 4:
/*
* we have seen end of file
*/
c = -1;
break;
case 5:
/*
* we have seen a newline
* following end of file does NOT need a '=' '\n' sequence
*/
c = input_getc(this->fp);
if (c < 0)
{
this->state = 4;
break;
}
this->state = 0;
goto normal;
case 6:
/*
* we have seen an unprintable character
* we have sent the '=' synbol
* now send the first hex byte
*/
c = hex(this->c1 >> 4);
this->state = 7;
break;
case 7:
/*
* we have seen an unprintable character
* we have sent the '=' synbol
* we have sent the first hex byte
* now send the second hex byte
* and the resume normal processing
*/
c = hex(this->c1);
this->state = 0;
break;
default:
/*
* Normal processing.
* Actually case 0, but this cobvers a multitude of sins.
*/
if (this->column >= 500)
{
c = '=';
this->state = 1;
break;
}
c = input_getc(this->fp);
if (c < 0)
{
this->state = 3;
this->column = 0;
c = '=';
break;
}
normal:
if (c == '\n')
{
this->column = 0;
this->state = 5;
break;
}
if (c == '\t')
{
this->column = (this->column + 8) & 7;
break;
}
if (c == 0 || c == '=' || c == '\r')
{
this->column += 3;
this->c1 = c;
this->state = 6;
c = '=';
break;
}
this->column++;
break;
}
trace(("}\n"));
return c;
}
static long
itell(input_ty *fp)
{
input_quoted_printable_encode_ty *this;
this = (input_quoted_printable_encode_ty *)fp;
return input_ftell(this->fp);
}
static const char *
name(input_ty *p)
{
input_quoted_printable_encode_ty *this;
trace(("input_quoted_printable_encode::name\n"));
this = (input_quoted_printable_encode_ty *)p;
return input_name(this->fp);
}
static long
length(input_ty *p)
{
(void)p;
trace(("input_quoted_printable_encode::length => -1\n"));
return -1;
}
static input_vtbl_ty vtbl =
{
sizeof(input_quoted_printable_encode_ty),
destruct,
input_generic_read,
get,
itell,
name,
length,
};
input_ty *
input_quoted_printable_encode(input_ty *fp, int delete_on_close)
{
input_ty *result;
input_quoted_printable_encode_ty *this;
trace(("input_quoted_printable_encode(fp = %08lX)\n{\n", (long)fp));
result = input_new(&vtbl);
this = (input_quoted_printable_encode_ty *)result;
this->fp = fp;
this->column = 0;
this->state = 0;
this->c1 = 0;
this->delete_on_close = delete_on_close;
trace(("return %08lX\n", (long)result));
trace(("}\n"));
return result;
}
/* vim: set ts=8 sw=4 et : */