home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 18 REXX
/
18-REXX.zip
/
rxendeco.zip
/
QUOTE.C
< prev
next >
Wrap
C/C++ Source or Header
|
2001-07-15
|
6KB
|
202 lines
/* +------------------------------------------------------------------------+
| Quoted-Printable encode/decode. 2001-07-14 Dave Lewis |
+------------------------------------------------------------------------+ */
#pragma strings(readonly)
#include <stdlib.h>
#include <stdio.h>
#include <memory.h>
#include <string.h>
#include <ctype.h>
/*-----------------------------------------------------------------------------
See RFC 1521 Section "5.1. Quoted-Printable Content-Transfer-Encoding"
This program assumes that the text being passed in is has already been
converted to canonical form. i.e. hard line breaks are CRLF sequences.
-----------------------------------------------------------------------------*/
static unsigned char AllwaysEncode[256] =
{
/* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, /* 0 */
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 1 */
0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 2 */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, /* 3 */
1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 4 */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, /* 5 */
1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 6 */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, /* 7 */
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 8 */
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 9 */
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* A */
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* B */
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* C */
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* D */
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* E */
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 /* F */
};
/*-----------------------------------------------------------------------------
-----------------------------------------------------------------------------*/
void utHexToBin ( unsigned char *target, unsigned char *source, int length );
/*-----------------------------------------------------------------------------
Convert 8bit character array to quoted-printable
-----------------------------------------------------------------------------*/
int utTxtToQuoted ( unsigned char **trget, unsigned char *source, int length )
{
int allocated = length * 3;
int retlen = 0;
int newline = 1;
int curlen = 0;
unsigned char *target = malloc( allocated );
while ( length-- )
{
int encode = 0;
if ( retlen + 8 > allocated )
target = realloc( target, allocated += 256 );
if ( newline ) /* These are problem strings */
{
if ( length >= 4 && !memicmp( source, "From ", 5 ) ||
length >= 2 && !memcmp ( source, ".\r\n", 3 ) ||
*source == '\n' )
encode = 1;
newline = 0;
}
if ( !encode && length >= 2 && source[1] == '\r' && source[2] == '\n' )
if ( *source == ' ' || *source == '\t' ) encode = 1; /* Trailing space */
if ( !encode && *source == '\r' && source[1] != '\n' ) encode = 1;
if ( !encode && *source == '\n' )
if ( source[-1] != '\r' ) encode = 1;
else newline = 1;
if ( encode || AllwaysEncode[ *source ] )
{
sprintf ( &target[retlen], "=%2.2X", *source );
curlen += 3;
retlen += 3;
}
else
{
target[retlen] = *source;
curlen++;
retlen++;
}
source++;
if ( newline ) curlen = 0;
else if ( curlen >= 70 && length > 1 )
{
if ( !encode && source[0] == '\n' ) continue;
if ( source[0] == '\r' && source[1] == '\n' ) continue;
if ( source[1] == '\r' && source[2] == '\n' ) continue;
memcpy( &target[retlen], "=\r\n", 3 ); /* Soft Break */
retlen += 3;
curlen = 0;
newline = 1;
}
}
*trget = target;
return ( retlen );
}
/*-----------------------------------------------------------------------------
Convert quoted-printable to 8bit character array
-----------------------------------------------------------------------------*/
int utQuotedToTxt ( unsigned char *target, unsigned char *source, int length )
{
int retlen = 0;
unsigned char *cp, *np;
cp = source;
while ( length > 0 )
{
if ( length >= 3 && ( np = memchr( cp, '=', length - 3 ) ) != NULL )
{
int fraction = np - cp;
if ( fraction )
{
memmove( target, cp, fraction );
target += fraction;
retlen += fraction;
length -= fraction;
}
if ( np[1] != '\r' && np[2] != '\n' )
{
utHexToBin ( target++, np + 1, 2 );
retlen++;
}
length -= 3;
cp = np + 3;
}
else
{
if ( target != cp ) memmove( target, cp, length );
retlen += length;
break;
}
}
return ( retlen );
}
/*-----------------------------------------------------------------------
utHexToAsc
-----------------
Convert every 2 HEX bytes to 1 binary piece of data
-----------------------------------------------------------------------*/
void utHexToBin ( unsigned char *target, unsigned char *source, int length )
{
static unsigned char hexDigits[] = "0123456789ABCDEF";
unsigned char workval;
int nibble;
if ( length & 1 ) length++;
memset ( target, 0, length >> 1 );
for ( nibble = 0; nibble < length; nibble++ )
{
workval = ( (unsigned char *)memchr( hexDigits, toupper(*source),
sizeof( hexDigits ) ) - hexDigits ) & 0x0F;
if ( !(nibble & 1) ) workval <<= 4;
target[ nibble >> 1 ] |= workval;
if ( !*(++source) ) break;
}
return;
}