source: Network/synapse/mimeinln.pas

Last change on this file was 300, checked in by chronos, 13 years ago
  • Added: Synapse library with package file. Cryptlib units are not included in package file list.
File size: 9.1 KB
Line 
1{==============================================================================|
2| Project : Ararat Synapse | 001.001.011 |
3|==============================================================================|
4| Content: Inline MIME support procedures and functions |
5|==============================================================================|
6| Copyright (c)1999-2006, Lukas Gebauer |
7| All rights reserved. |
8| |
9| Redistribution and use in source and binary forms, with or without |
10| modification, are permitted provided that the following conditions are met: |
11| |
12| Redistributions of source code must retain the above copyright notice, this |
13| list of conditions and the following disclaimer. |
14| |
15| Redistributions in binary form must reproduce the above copyright notice, |
16| this list of conditions and the following disclaimer in the documentation |
17| and/or other materials provided with the distribution. |
18| |
19| Neither the name of Lukas Gebauer nor the names of its contributors may |
20| be used to endorse or promote products derived from this software without |
21| specific prior written permission. |
22| |
23| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
24| AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
25| IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
26| ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR |
27| ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
28| DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR |
29| SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER |
30| CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
31| LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
32| OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH |
33| DAMAGE. |
34|==============================================================================|
35| The Initial Developer of the Original Code is Lukas Gebauer (Czech Republic).|
36| Portions created by Lukas Gebauer are Copyright (c)2000-2006. |
37| All Rights Reserved. |
38|==============================================================================|
39| Contributor(s): |
40|==============================================================================|
41| History: see HISTORY.HTM from distribution package |
42| (Found at URL: http://www.ararat.cz/synapse/) |
43|==============================================================================}
44
45{:@abstract(Utilities for inline MIME)
46Support for Inline MIME encoding and decoding.
47
48Used RFC: RFC-2047, RFC-2231
49}
50
51{$IFDEF FPC}
52 {$MODE DELPHI}
53{$ENDIF}
54{$H+}
55
56unit mimeinln;
57
58interface
59
60uses
61 SysUtils, Classes,
62 synachar, synacode, synautil;
63
64{:Decodes mime inline encoding (i.e. in headers) uses target characterset "CP".}
65function InlineDecode(const Value: string; CP: TMimeChar): string;
66
67{:Encodes string to MIME inline encoding. The source characterset is "CP", and
68 the target charset is "MimeP".}
69function InlineEncode(const Value: string; CP, MimeP: TMimeChar): string;
70
71{:Returns @true, if "Value" contains characters needed for inline coding.}
72function NeedInline(const Value: AnsiString): boolean;
73
74{:Inline mime encoding similar to @link(InlineEncode), but you can specify
75 source charset, and the target characterset is automatically assigned.}
76function InlineCodeEx(const Value: string; FromCP: TMimeChar): string;
77
78{:Inline MIME encoding similar to @link(InlineEncode), but the source charset
79 is automatically set to the system default charset, and the target charset is
80 automatically assigned from set of allowed encoding for MIME.}
81function InlineCode(const Value: string): string;
82
83{:Converts e-mail address to canonical mime form. You can specify source charset.}
84function InlineEmailEx(const Value: string; FromCP: TMimeChar): string;
85
86{:Converts e-mail address to canonical mime form. Source charser it system
87 default charset.}
88function InlineEmail(const Value: string): string;
89
90implementation
91
92{==============================================================================}
93
94function InlineDecode(const Value: string; CP: TMimeChar): string;
95var
96 s, su, v: string;
97 x, y, z, n: Integer;
98 ichar: TMimeChar;
99 c: Char;
100
101 function SearchEndInline(const Value: string; be: Integer): Integer;
102 var
103 n, q: Integer;
104 begin
105 q := 0;
106 Result := 0;
107 for n := be + 2 to Length(Value) - 1 do
108 if Value[n] = '?' then
109 begin
110 Inc(q);
111 if (q > 2) and (Value[n + 1] = '=') then
112 begin
113 Result := n;
114 Break;
115 end;
116 end;
117 end;
118
119begin
120 Result := '';
121 v := Value;
122 x := Pos('=?', v);
123 y := SearchEndInline(v, x);
124 //fix for broken coding with begin, but not with end.
125 if (x > 0) and (y <= 0) then
126 y := Length(Result);
127 while (y > x) and (x > 0) do
128 begin
129 s := Copy(v, 1, x - 1);
130 if Trim(s) <> '' then
131 Result := Result + s;
132 s := Copy(v, x, y - x + 2);
133 Delete(v, 1, y + 1);
134 su := Copy(s, 3, Length(s) - 4);
135 z := Pos('?', su);
136 if (Length(su) >= (z + 2)) and (su[z + 2] = '?') then
137 begin
138 ichar := GetCPFromID(SeparateLeft(Copy(su, 1, z - 1), '*'));
139 c := UpperCase(su)[z + 1];
140 su := Copy(su, z + 3, Length(su) - z - 2);
141 if c = 'B' then
142 begin
143 s := DecodeBase64(su);
144 s := CharsetConversion(s, ichar, CP);
145 end;
146 if c = 'Q' then
147 begin
148 s := '';
149 for n := 1 to Length(su) do
150 if su[n] = '_' then
151 s := s + ' '
152 else
153 s := s + su[n];
154 s := DecodeQuotedPrintable(s);
155 s := CharsetConversion(s, ichar, CP);
156 end;
157 end;
158 Result := Result + s;
159 x := Pos('=?', v);
160 y := SearchEndInline(v, x);
161 end;
162 Result := Result + v;
163end;
164
165{==============================================================================}
166
167function InlineEncode(const Value: string; CP, MimeP: TMimeChar): string;
168var
169 s, s1, e: string;
170 n: Integer;
171begin
172 s := CharsetConversion(Value, CP, MimeP);
173 s := EncodeSafeQuotedPrintable(s);
174 e := GetIdFromCP(MimeP);
175 s1 := '';
176 Result := '';
177 for n := 1 to Length(s) do
178 if s[n] = ' ' then
179 begin
180// s1 := s1 + '=20';
181 s1 := s1 + '_';
182 if Length(s1) > 32 then
183 begin
184 if Result <> '' then
185 Result := Result + ' ';
186 Result := Result + '=?' + e + '?Q?' + s1 + '?=';
187 s1 := '';
188 end;
189 end
190 else
191 s1 := s1 + s[n];
192 if s1 <> '' then
193 begin
194 if Result <> '' then
195 Result := Result + ' ';
196 Result := Result + '=?' + e + '?Q?' + s1 + '?=';
197 end;
198end;
199
200{==============================================================================}
201
202function NeedInline(const Value: AnsiString): boolean;
203var
204 n: Integer;
205begin
206 Result := False;
207 for n := 1 to Length(Value) do
208 if Value[n] in (SpecialChar + NonAsciiChar - ['_']) then
209 begin
210 Result := True;
211 Break;
212 end;
213end;
214
215{==============================================================================}
216
217function InlineCodeEx(const Value: string; FromCP: TMimeChar): string;
218var
219 c: TMimeChar;
220begin
221 if NeedInline(Value) then
222 begin
223 c := IdealCharsetCoding(Value, FromCP, IdealCharsets);
224 Result := InlineEncode(Value, FromCP, c);
225 end
226 else
227 Result := Value;
228end;
229
230{==============================================================================}
231
232function InlineCode(const Value: string): string;
233begin
234 Result := InlineCodeEx(Value, GetCurCP);
235end;
236
237{==============================================================================}
238
239function InlineEmailEx(const Value: string; FromCP: TMimeChar): string;
240var
241 sd, se: string;
242begin
243 sd := GetEmailDesc(Value);
244 se := GetEmailAddr(Value);
245 if sd = '' then
246 Result := se
247 else
248 Result := '"' + InlineCodeEx(sd, FromCP) + '" <' + se + '>';
249end;
250
251{==============================================================================}
252
253function InlineEmail(const Value: string): string;
254begin
255 Result := InlineEmailEx(Value, GetCurCP);
256end;
257
258end.
Note: See TracBrowser for help on using the repository browser.