1 //Written in the D programming language
2 /*
3  * MIME Quoted Printable Encoding.
4  *
5  * Copyright (C) 2013 Jaypha
6  *
7  * Distributed under the Boost Software License, Version 1.0.
8  * (See http://www.boost.org/LICENSE_1_0.txt)
9  *
10  * Authors: Jason den Dulk
11  */
12 
13 module jaypha.inet.mime.quotedprintable;
14 import jaypha.inet.mime.header;
15 
16 import jaypha.types;
17 
18 import std.ascii;
19 import std.array;
20 import std.string;
21 
22 //----------------------------------------------------------------------------
23 // input is an 8-bit code
24 // output is an ASCII string.
25 // See http://tools.ietf.org/html/rfc2045#section-6.7.
26 
27 string quotedPrintableEncode(ByteArray input, size_t maxLength = 76)
28 {
29   auto output = appender!(string[])();
30   auto lines = splitLines(cast(string)input);//lineSplitter(input);
31 
32   foreach (line;lines)
33   {
34     auto qLine = appender!string();
35     size_t lineLength = 0;
36     string append;
37 
38     foreach (i,c; line)
39     {
40       if (c == '=')
41         append = "=3D";
42       else if (c == ' ' && i == line.length-1)
43         append = "=20";
44       else if (isPrintable(c))
45         append = cast(string)[c];
46       else
47         append = format("=%02X",c);
48 
49       if ((lineLength + append.length > maxLength-1))
50       {
51         qLine.put("=");
52         qLine.put(MimeEoln);
53 
54         lineLength = 0;
55       }
56       qLine.put(append);
57       lineLength += append.length;
58     }
59     output.put(qLine.data);
60   }
61 
62   return output.data.join(MimeEoln);
63 }
64 
65 unittest
66 {
67   //import std.stdio;
68 
69   char c = 3;
70   auto str = cast(ByteArray)"abcde=fghi";
71 
72   auto qStr = quotedPrintableEncode(str);
73   assert(qStr == "abcde=3Dfghi");
74   str ~=c;
75   qStr = quotedPrintableEncode(str);
76   assert(qStr == "abcde=3Dfghi=03");
77 
78   str = cast(ByteArray)"abcde\nfghi\ngthy";
79   qStr = quotedPrintableEncode(str);
80   assert(qStr == "abcde\r\nfghi\r\ngthy");
81 
82   
83   str = cast(ByteArray)"12345678901234567890123456789012345678901234567890123456789012345678901234567890";
84   qStr = quotedPrintableEncode(str);
85   assert(qStr == "123456789012345678901234567890123456789012345678901234567890123456789012345=\r\n67890");
86 
87   str = cast(ByteArray)"1234567890123456789012 \n34567890";
88   qStr = quotedPrintableEncode(str);
89   assert(qStr == "1234567890123456789012=20\r\n34567890");
90 
91   str = cast(ByteArray)"123456789012345678901234567890123456789012345678901234567890123456789012345 \n67890";
92   qStr = quotedPrintableEncode(str);
93   assert(qStr == "123456789012345678901234567890123456789012345678901234567890123456789012345=\r\n=20\r\n67890");
94 }