File: decodeQ.c

package info (click to toggle)
ezmlm 0.53-3.1
  • links: PTS
  • area: non-free
  • in suites: potato
  • size: 2,472 kB
  • ctags: 1,514
  • sloc: ansic: 12,040; makefile: 1,224; sh: 1,217; perl: 743
file content (77 lines) | stat: -rw-r--r-- 2,309 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
/*$Id: decodeQ.c,v 1.3 1998/10/29 21:48:24 lindberg Exp $*/
/*$Name: ezmlm-idx-0313 $*/

#include "stralloc.h"
#include "strerr.h"
#include "errtxt.h"
#include "mime.h"

/* takes a string pointed to by cpfrom and adds the next 'n' bytes to        */
/* outdata, replacing any Quoted-Printable codes with the real characters.   */
/* NUL and LF in the input are allowed, but anything that decodes to these   */
/* values is ignored. */

static char char16table[128] = {
    -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
    -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
    -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
     0, 1, 2, 3,  4, 5, 6, 7,  8, 9,-1,-1, -1,-1,-1,-1,
    -1,10,11,12, 13,14,15,-1, -1,-1,-1,-1, -1,-1,-1,-1,
    -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
    -1,10,11,12, 13,14,15,-1, -1,-1,-1,-1, -1,-1,-1,-1,
    -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1
};

#define char16enc(c)  (((c) & 0x80) ? -1 : char16table[(c)])

static void die_nomem(fatal)
  char *fatal;
{
  strerr_die2x(111,fatal,ERR_NOMEM);
}

void decodeQ(cpfrom,n,outdata,fatal)
char *cpfrom;
unsigned int n;
stralloc *outdata;
char *fatal;
/* does Q decoding of the string pointed to by cpfrom up to the character */
/* before the one pointed to by cpnext, and appends the results to mimeline*/
{
  char *cp,*cpnext,*cpmore;
  char holdch[2];
  char ch1,ch2;		/* need to be signed */

  cpmore = cpfrom;
  cp = cpfrom;
  cpnext = cp + n;
  if (!stralloc_readyplus(outdata,n)) die_nomem(fatal);

  while (cp < cpnext) {
    if (*cp == '_') *cp = ' ';		/* '_' -> space */
    else if (*cp == '=') {		/* "=F8" -> '\xF8' */
					/* copy stuff before */
      if (!stralloc_catb(outdata,cpmore,cp-cpmore)) die_nomem(fatal);
      cpmore = cp;
      ++cp;
      if (*cp == '\n') {		/* skip soft line break */
        ++cp;
        cpmore = cp;
        continue;
      }
      ch1 = char16enc(*cp);
      if (++cp >= cpnext)
        break;
      ch2 = char16enc(*cp);
      if (ch1 >= 0 && ch2 >= 0) {	/* ignore illegals */
        holdch[0] = (ch1 << 4 | ch2) & 0xff;
        if (!stralloc_catb(outdata,holdch,1)) die_nomem(fatal);
        cpmore += 3;
      }
    }
    ++cp;
  }					/* copy stuff after */
  if (!stralloc_catb(outdata,cpmore,cpnext-cpmore)) die_nomem(fatal);
}