PageRenderTime 37ms CodeModel.GetById 8ms app.highlight 24ms RepoModel.GetById 1ms app.codeStats 0ms

/src/smtp/rfc2047.erl

https://code.google.com/p/zotonic/
Erlang | 65 lines | 48 code | 11 blank | 6 comment | 0 complexity | b6213150aeac844333ab788e708484b9 MD5 | raw file
 1%% Encode a string according to RFC 2047 using quoted-printable.
 2%% Assumes UTF-8 as the character set.
 3%%
 4%% @copyright 2009 Marc Worrell
 5
 6-module(rfc2047).
 7-author("Marc Worrell <marc@worrell.nl>").
 8
 9-export([encode/1, decode/1]).
10
11
12encode(B) when is_binary(B) ->
13	encode(binary_to_list(B));
14encode([]) -> 
15	[];
16encode(Text) ->
17    encode(Text, Text).
18
19    %% Don't escape when all characters are ASCII printable
20    encode([], Text) ->
21        Text;
22    encode([H|T], Text) when H >= 32 andalso H =< 126 andalso H /= $= ->
23        encode(T, Text);
24    encode(_, Text) ->
25        "=?UTF-8?Q?" ++ encode(Text, [], 0) ++ "?=".
26
27encode([], Acc, _WordLen) ->
28    lists:reverse(Acc);
29encode(T, Acc, WordLen) when WordLen >= 55 ->
30    %% Make sure that the individual encoded words are not longer than 76 chars (including charset etc)
31    encode(T, [$?,$Q,$?,$8,$-,$F,$T,$U,$?,$=,32,10,13,$=,$?|Acc], 0);
32encode([C|T], Acc, WordLen) when C > 32 andalso C < 127 andalso C /= 32 
33    andalso C /= $? andalso C /= $_ andalso C /= $= andalso C /= $. ->
34    encode(T, [C|Acc], WordLen+1);
35encode([C|T], Acc, WordLen) ->
36    encode(T, [hex(C rem 16), hex(C div 16), $= | Acc], WordLen+3).
37
38decode(B) when is_binary(B) ->
39    decode(binary_to_list(B));
40decode(Text) ->
41    decode(Text, in_text, []).
42
43decode([], _, Acc) ->
44    lists:reverse(Acc);    
45decode("=?UTF-8?Q?" ++ T, in_text, Acc) ->
46    decode(T, in_utf8, Acc);
47decode("?= \r\n" ++ T, in_utf8, Acc) ->
48    decode(T, in_text, Acc);
49decode("?=" ++ T, in_utf8, Acc) ->
50    decode(T, in_text, Acc);
51decode([$=,C1,C2|T], in_utf8, Acc) ->
52    decode(T, in_utf8, [unhex(C1)*16+unhex(C2)|Acc]);
53decode([H|T], State, Acc) ->
54    decode(T, State, [H|Acc]).
55
56hex(N) when N >= 10 -> N + $A - 10;
57hex(N) -> N + $0.
58
59unhex(C) when C >= $a ->
60    C - $a + 10;
61unhex(C) when C >= $A ->
62    C - $A + 10;
63unhex(C) ->
64    C - $0.
65