Statistics
| Branch: | Tag: | Revision:

root / libsylph / uuencode.c @ aebfd4cc

History | View | Annotate | Download (2 KB)

1
/*
2
 * LibSylph -- E-Mail client library
3
 * Copyright (C) 1999-2011 Hiroyuki Yamamoto
4
 */
5

    
6
#include <ctype.h>
7

    
8
#define UUDECODE(c) (c=='`' ? 0 : c - ' ')
9
#define N64(i) (i & ~63)
10

    
11
const char uudigit[64] =
12
{
13
  '`', '!', '"', '#', '$', '%', '&', '\'',
14
  '(', ')', '*', '+', ',', '-', '.', '/',
15
  '0', '1', '2', '3', '4', '5', '6', '7',
16
  '8', '9', ':', ';', '<', '=', '>', '?',
17
  '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G',
18
  'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
19
  'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
20
  'X', 'Y', 'Z', '[', '\\', ']', '^', '_'
21
};
22

    
23
int touufrombits(unsigned char *out, const unsigned char *in, int inlen)
24
{
25
    int len;
26

    
27
    if (inlen > 45) return -1;
28
    len = (inlen * 4 + 2) / 3 + 1;
29
    *out++ = uudigit[inlen];
30

    
31
    for (; inlen >= 3; inlen -= 3) {
32
        *out++ = uudigit[in[0] >> 2];
33
        *out++ = uudigit[((in[0] << 4) & 0x30) | (in[1] >> 4)];
34
        *out++ = uudigit[((in[1] << 2) & 0x3c) | (in[2] >> 6)];
35
        *out++ = uudigit[in[2] & 0x3f];
36
        in += 3;
37
    }
38

    
39
    if (inlen > 0) {
40
        *out++ = uudigit[(in[0] >> 2)];
41
        if (inlen == 1) {
42
            *out++ = uudigit[((in[0] << 4) & 0x30)];
43
        } else {
44
            *out++ = uudigit[(((in[0] << 4) & 0x30) | (in[1] >> 4))] ;            
45
            *out++ = uudigit[((in[1] << 2) & 0x3c)];
46
        }
47
    }
48
    *out = '\0';
49

    
50
    return len;
51
}
52

    
53
int fromuutobits(char *out, const char *in)
54
{
55
    int len, outlen, inlen;
56
    register unsigned char digit1, digit2;
57

    
58
    outlen = UUDECODE(in[0]);
59
    in += 1;
60
    if(outlen < 0 || outlen > 45)
61
        return -2;
62
    if(outlen == 0)
63
        return 0;
64
    inlen = (outlen * 4 + 2) / 3;
65
    len = 0;
66

    
67
    for( ; inlen>0; inlen-=4) {
68
        digit1 = UUDECODE(in[0]);
69
        if (N64(digit1)) return -1;
70
        digit2 = UUDECODE(in[1]);
71
        if (N64(digit2)) return -1;
72
        out[len++] = (digit1 << 2) | (digit2 >> 4);
73
        if (inlen > 2) {
74
            digit1 = UUDECODE(in[2]);
75
            if (N64(digit1)) return -1;
76
            out[len++] = (digit2 << 4) | (digit1 >> 2);
77
            if (inlen > 3) {
78
                digit2 = UUDECODE(in[3]);
79
                if (N64(digit2)) return -1;
80
                out[len++] = (digit1 << 6) | digit2;
81
            }
82
        }
83
        in += 4;
84
    }
85

    
86
    return len == outlen ? len : -3;
87
}