2008-04-23 23:48:39 +03:00
|
|
|
{==============================================================================|
|
2008-04-24 10:09:13 +03:00
|
|
|
| Project : Delphree - Synapse | 001.005.002 |
|
2008-04-23 23:48:39 +03:00
|
|
|
|==============================================================================|
|
2008-04-24 09:40:58 +03:00
|
|
|
| Content: MIME support procedures and functions |
|
2008-04-23 23:48:39 +03:00
|
|
|
|==============================================================================|
|
2008-04-24 10:05:26 +03:00
|
|
|
| The contents of this file are subject to the Mozilla Public License Ver. 1.1 |
|
2008-04-23 23:48:39 +03:00
|
|
|
| (the "License"); you may not use this file except in compliance with the |
|
|
|
|
| License. You may obtain a copy of the License at http://www.mozilla.org/MPL/ |
|
|
|
|
| |
|
|
|
|
| Software distributed under the License is distributed on an "AS IS" basis, |
|
|
|
|
| WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for |
|
|
|
|
| the specific language governing rights and limitations under the License. |
|
|
|
|
|==============================================================================|
|
|
|
|
| The Original Code is Synapse Delphi Library. |
|
|
|
|
|==============================================================================|
|
|
|
|
| The Initial Developer of the Original Code is Lukas Gebauer (Czech Republic).|
|
2008-04-24 09:47:56 +03:00
|
|
|
| Portions created by Lukas Gebauer are Copyright (c)2000,2001. |
|
2008-04-23 23:48:39 +03:00
|
|
|
| All Rights Reserved. |
|
|
|
|
|==============================================================================|
|
|
|
|
| Contributor(s): |
|
|
|
|
|==============================================================================|
|
|
|
|
| History: see HISTORY.HTM from distribution package |
|
|
|
|
| (Found at URL: http://www.ararat.cz/synapse/) |
|
|
|
|
|==============================================================================}
|
|
|
|
|
|
|
|
unit MIMEpart;
|
|
|
|
|
|
|
|
interface
|
|
|
|
|
|
|
|
uses
|
2008-04-24 10:05:26 +03:00
|
|
|
SysUtils, Classes,
|
|
|
|
SynaChar, SynaCode, SynaUtil, MIMEinLn;
|
2008-04-23 23:48:39 +03:00
|
|
|
|
|
|
|
type
|
|
|
|
|
2008-04-24 10:05:26 +03:00
|
|
|
TMimePrimary = (MP_TEXT, MP_MULTIPART,
|
|
|
|
MP_MESSAGE, MP_BINARY);
|
2008-04-23 23:48:39 +03:00
|
|
|
|
2008-04-24 10:05:26 +03:00
|
|
|
TMimeEncoding = (ME_7BIT, ME_8BIT, ME_QUOTED_PRINTABLE,
|
|
|
|
ME_BASE64, ME_UU, ME_XX);
|
2008-04-23 23:48:39 +03:00
|
|
|
|
2008-04-24 10:05:26 +03:00
|
|
|
TMimePart = class(TObject)
|
2008-04-23 23:48:39 +03:00
|
|
|
private
|
2008-04-24 10:05:26 +03:00
|
|
|
FPrimary: string;
|
|
|
|
FEncoding: string;
|
|
|
|
FCharset: string;
|
|
|
|
FPrimaryCode: TMimePrimary;
|
|
|
|
FEncodingCode: TMimeEncoding;
|
|
|
|
FCharsetCode: TMimeChar;
|
|
|
|
FTargetCharset: TMimeChar;
|
|
|
|
FSecondary: string;
|
|
|
|
FDescription: string;
|
|
|
|
FDisposition: string;
|
|
|
|
FContentID: string;
|
|
|
|
FBoundary: string;
|
|
|
|
FFileName: string;
|
|
|
|
FLines: TStringList;
|
|
|
|
FDecodedLines: TMemoryStream;
|
|
|
|
procedure SetPrimary(Value: string);
|
|
|
|
procedure SetEncoding(Value: string);
|
|
|
|
procedure SetCharset(Value: string);
|
2008-04-23 23:48:39 +03:00
|
|
|
public
|
|
|
|
constructor Create;
|
|
|
|
destructor Destroy; override;
|
2008-04-24 10:05:26 +03:00
|
|
|
procedure Clear;
|
|
|
|
function ExtractPart(Value: TStringList; BeginLine: Integer): Integer;
|
2008-04-23 23:48:39 +03:00
|
|
|
procedure DecodePart;
|
|
|
|
procedure EncodePart;
|
2008-04-24 10:05:26 +03:00
|
|
|
procedure MimeTypeFromExt(Value: string);
|
|
|
|
published
|
|
|
|
property Primary: string read FPrimary write SetPrimary;
|
|
|
|
property Encoding: string read FEncoding write SetEncoding;
|
|
|
|
property Charset: string read FCharset write SetCharset;
|
|
|
|
property PrimaryCode: TMimePrimary read FPrimaryCode Write FPrimaryCode;
|
|
|
|
property EncodingCode: TMimeEncoding read FEncodingCode Write FEncodingCode;
|
|
|
|
property CharsetCode: TMimeChar read FCharsetCode Write FCharsetCode;
|
|
|
|
property TargetCharset: TMimeChar read FTargetCharset Write FTargetCharset;
|
|
|
|
property Secondary: string read FSecondary Write FSecondary;
|
|
|
|
property Description: string read FDescription Write FDescription;
|
|
|
|
property Disposition: string read FDisposition Write FDisposition;
|
|
|
|
property ContentID: string read FContentID Write FContentID;
|
|
|
|
property Boundary: string read FBoundary Write FBoundary;
|
|
|
|
property FileName: string read FFileName Write FFileName;
|
2008-04-24 10:07:45 +03:00
|
|
|
property Lines: TStringList read FLines;
|
|
|
|
property DecodedLines: TMemoryStream read FDecodedLines;
|
2008-04-24 10:05:26 +03:00
|
|
|
end;
|
2008-04-23 23:48:39 +03:00
|
|
|
|
|
|
|
const
|
2008-04-24 10:05:26 +03:00
|
|
|
MaxMimeType = 25;
|
|
|
|
MimeType: array[0..MaxMimeType, 0..2] of string =
|
|
|
|
(
|
|
|
|
('AU', 'audio', 'basic'),
|
|
|
|
('AVI', 'video', 'x-msvideo'),
|
|
|
|
('BMP', 'image', 'BMP'),
|
|
|
|
('DOC', 'application', 'MSWord'),
|
|
|
|
('EPS', 'application', 'Postscript'),
|
|
|
|
('GIF', 'image', 'GIF'),
|
|
|
|
('JPEG', 'image', 'JPEG'),
|
|
|
|
('JPG', 'image', 'JPEG'),
|
|
|
|
('MID', 'audio', 'midi'),
|
|
|
|
('MOV', 'video', 'quicktime'),
|
|
|
|
('MPEG', 'video', 'MPEG'),
|
|
|
|
('MPG', 'video', 'MPEG'),
|
|
|
|
('MP2', 'audio', 'mpeg'),
|
|
|
|
('MP3', 'audio', 'mpeg'),
|
|
|
|
('PDF', 'application', 'PDF'),
|
|
|
|
('PNG', 'image', 'PNG'),
|
|
|
|
('PS', 'application', 'Postscript'),
|
|
|
|
('QT', 'video', 'quicktime'),
|
|
|
|
('RA', 'audio', 'x-realaudio'),
|
|
|
|
('RTF', 'application', 'RTF'),
|
|
|
|
('SND', 'audio', 'basic'),
|
|
|
|
('TIF', 'image', 'TIFF'),
|
|
|
|
('TIFF', 'image', 'TIFF'),
|
|
|
|
('WAV', 'audio', 'x-wav'),
|
|
|
|
('WPD', 'application', 'Wordperfect5.1'),
|
|
|
|
('ZIP', 'application', 'ZIP')
|
2008-04-23 23:48:39 +03:00
|
|
|
);
|
|
|
|
|
2008-04-24 10:05:26 +03:00
|
|
|
function NormalizeHeader(Value: TStringList; var Index: Integer): string;
|
|
|
|
function GenerateBoundary: string;
|
2008-04-23 23:48:39 +03:00
|
|
|
|
|
|
|
implementation
|
|
|
|
|
2008-04-24 10:05:26 +03:00
|
|
|
function NormalizeHeader(Value: TStringList; var Index: Integer): string;
|
2008-04-23 23:48:39 +03:00
|
|
|
var
|
2008-04-24 10:05:26 +03:00
|
|
|
s, t: string;
|
|
|
|
n: Integer;
|
2008-04-23 23:48:39 +03:00
|
|
|
begin
|
2008-04-24 10:05:26 +03:00
|
|
|
s := Value[Index];
|
|
|
|
Inc(Index);
|
|
|
|
if s <> '' then
|
|
|
|
while (Value.Count - 1) > Index do
|
|
|
|
begin
|
|
|
|
t := Value[Index];
|
|
|
|
if t = '' then
|
|
|
|
Break;
|
|
|
|
for n := 1 to Length(t) do
|
|
|
|
if t[n] = #9 then
|
|
|
|
t[n] := ' ';
|
|
|
|
if t[1] <> ' ' then
|
|
|
|
Break
|
|
|
|
else
|
|
|
|
begin
|
|
|
|
s := s + ' ' + Trim(t);
|
|
|
|
Inc(Index);
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
Result := s;
|
2008-04-23 23:48:39 +03:00
|
|
|
end;
|
|
|
|
|
|
|
|
{==============================================================================}
|
2008-04-24 10:05:26 +03:00
|
|
|
|
|
|
|
constructor TMIMEPart.Create;
|
2008-04-23 23:48:39 +03:00
|
|
|
begin
|
|
|
|
inherited Create;
|
2008-04-24 10:05:26 +03:00
|
|
|
FLines := TStringList.Create;
|
|
|
|
FDecodedLines := TMemoryStream.Create;
|
|
|
|
FTargetCharset := GetCurCP;
|
2008-04-23 23:48:39 +03:00
|
|
|
end;
|
|
|
|
|
2008-04-24 10:05:26 +03:00
|
|
|
destructor TMIMEPart.Destroy;
|
2008-04-23 23:48:39 +03:00
|
|
|
begin
|
2008-04-24 10:05:26 +03:00
|
|
|
FDecodedLines.Free;
|
|
|
|
FLines.Free;
|
|
|
|
inherited Destroy;
|
2008-04-23 23:48:39 +03:00
|
|
|
end;
|
|
|
|
|
|
|
|
{==============================================================================}
|
2008-04-24 10:05:26 +03:00
|
|
|
|
2008-04-23 23:48:39 +03:00
|
|
|
procedure TMIMEPart.Clear;
|
|
|
|
begin
|
2008-04-24 10:05:26 +03:00
|
|
|
FPrimary := '';
|
|
|
|
FEncoding := '';
|
|
|
|
FCharset := '';
|
|
|
|
FPrimaryCode := MP_TEXT;
|
|
|
|
FEncodingCode := ME_7BIT;
|
|
|
|
FCharsetCode := ISO_8859_1;
|
|
|
|
FTargetCharset := GetCurCP;
|
|
|
|
FSecondary := '';
|
|
|
|
FDisposition := '';
|
|
|
|
FContentID := '';
|
|
|
|
FDescription := '';
|
|
|
|
FBoundary := '';
|
|
|
|
FFileName := '';
|
|
|
|
FLines.Clear;
|
|
|
|
FDecodedLines.Clear;
|
2008-04-23 23:48:39 +03:00
|
|
|
end;
|
|
|
|
|
|
|
|
{==============================================================================}
|
2008-04-24 10:05:26 +03:00
|
|
|
|
|
|
|
function TMIMEPart.ExtractPart(Value: TStringList; BeginLine: Integer): Integer;
|
2008-04-23 23:48:39 +03:00
|
|
|
var
|
2008-04-24 10:05:26 +03:00
|
|
|
n, x, x1, x2: Integer;
|
|
|
|
t: TStringList;
|
|
|
|
s, su, b: string;
|
|
|
|
st, st2: string;
|
|
|
|
e: Boolean;
|
|
|
|
fn: string;
|
2008-04-23 23:48:39 +03:00
|
|
|
begin
|
2008-04-24 10:05:26 +03:00
|
|
|
t := TStringlist.Create;
|
2008-04-23 23:48:39 +03:00
|
|
|
try
|
2008-04-24 10:05:26 +03:00
|
|
|
{ defaults }
|
|
|
|
FLines.Clear;
|
|
|
|
Primary := 'text';
|
|
|
|
FSecondary := 'plain';
|
|
|
|
FDescription := '';
|
|
|
|
Charset := 'US-ASCII';
|
|
|
|
FFileName := '';
|
|
|
|
Encoding := '7BIT';
|
2008-04-23 23:48:39 +03:00
|
|
|
|
2008-04-24 10:05:26 +03:00
|
|
|
fn := '';
|
|
|
|
x := BeginLine;
|
|
|
|
b := FBoundary;
|
2008-04-24 10:07:45 +03:00
|
|
|
{ if multipart - skip pre-part }
|
2008-04-24 10:05:26 +03:00
|
|
|
if b <> '' then
|
|
|
|
while Value.Count > x do
|
2008-04-23 23:48:39 +03:00
|
|
|
begin
|
2008-04-24 10:05:26 +03:00
|
|
|
s := Value[x];
|
|
|
|
Inc(x);
|
2008-04-24 10:07:45 +03:00
|
|
|
if Pos('--' + b, s) = 1 then
|
2008-04-24 10:05:26 +03:00
|
|
|
Break;
|
|
|
|
end;
|
|
|
|
|
|
|
|
{ parse header }
|
|
|
|
while Value.Count > x do
|
|
|
|
begin
|
|
|
|
s := NormalizeHeader(Value, x);
|
|
|
|
if s = '' then
|
|
|
|
Break;
|
|
|
|
su := UpperCase(s);
|
|
|
|
if Pos('CONTENT-TYPE:', su) = 1 then
|
|
|
|
begin
|
|
|
|
st := SeparateRight(su, ':');
|
|
|
|
st2 := SeparateLeft(st, ';');
|
|
|
|
Primary := SeparateLeft(st2, '/');
|
|
|
|
FSecondary := SeparateRight(st2, '/');
|
2008-04-24 10:07:45 +03:00
|
|
|
if (FSecondary = Primary) and (Pos('/', st2) < 1) then
|
|
|
|
FSecondary := '';
|
2008-04-24 10:05:26 +03:00
|
|
|
case FPrimaryCode of
|
|
|
|
MP_TEXT:
|
2008-04-24 10:09:13 +03:00
|
|
|
begin
|
|
|
|
Charset := UpperCase(GetParameter(s, 'charset='));
|
|
|
|
FFileName := GetParameter(s, 'name=');
|
|
|
|
end;
|
2008-04-24 10:05:26 +03:00
|
|
|
MP_MULTIPART:
|
|
|
|
FBoundary := GetParameter(s, 'Boundary=');
|
|
|
|
MP_MESSAGE:
|
|
|
|
begin
|
2008-04-23 23:48:39 +03:00
|
|
|
end;
|
2008-04-24 10:05:26 +03:00
|
|
|
MP_BINARY:
|
|
|
|
FFileName := GetParameter(s, 'name=');
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
if Pos('CONTENT-TRANSFER-ENCODING:', su) = 1 then
|
|
|
|
Encoding := SeparateRight(su, ':');
|
|
|
|
if Pos('CONTENT-DESCRIPTION:', su) = 1 then
|
|
|
|
FDescription := SeparateRight(s, ':');
|
|
|
|
if Pos('CONTENT-DISPOSITION:', su) = 1 then
|
|
|
|
begin
|
|
|
|
FDisposition := SeparateRight(su, ':');
|
|
|
|
FDisposition := Trim(SeparateLeft(FDisposition, ';'));
|
|
|
|
fn := GetParameter(s, 'FileName=');
|
2008-04-23 23:48:39 +03:00
|
|
|
end;
|
2008-04-24 10:05:26 +03:00
|
|
|
if Pos('CONTENT-ID:', su) = 1 then
|
|
|
|
FContentID := SeparateRight(s, ':');
|
|
|
|
end;
|
2008-04-23 23:48:39 +03:00
|
|
|
|
2008-04-24 10:05:26 +03:00
|
|
|
if (PrimaryCode = MP_BINARY) and (FFileName = '') then
|
|
|
|
FFileName := fn;
|
|
|
|
FFileName := InlineDecode(FFileName, getCurCP);
|
|
|
|
FFileName := ExtractFileName(FFileName);
|
2008-04-23 23:49:43 +03:00
|
|
|
|
2008-04-24 10:07:45 +03:00
|
|
|
{ finding part content x1-begin x2-end }
|
2008-04-24 10:05:26 +03:00
|
|
|
x1 := x;
|
|
|
|
x2 := Value.Count - 1;
|
2008-04-24 10:07:45 +03:00
|
|
|
{ if multipart - end is before next boundary }
|
2008-04-24 10:05:26 +03:00
|
|
|
if b <> '' then
|
|
|
|
begin
|
|
|
|
for n := x to Value.Count - 1 do
|
2008-04-23 23:48:39 +03:00
|
|
|
begin
|
2008-04-24 10:05:26 +03:00
|
|
|
x2 := n;
|
|
|
|
s := Value[n];
|
2008-04-24 10:07:45 +03:00
|
|
|
if Pos('--' + b, s) = 1 then
|
2008-04-24 10:05:26 +03:00
|
|
|
begin
|
|
|
|
Dec(x2);
|
|
|
|
Break;
|
|
|
|
end;
|
2008-04-23 23:48:39 +03:00
|
|
|
end;
|
2008-04-24 10:05:26 +03:00
|
|
|
end;
|
2008-04-24 10:07:45 +03:00
|
|
|
{ if content is multipart - content is delimited by their boundaries }
|
2008-04-24 10:05:26 +03:00
|
|
|
if FPrimaryCode = MP_MULTIPART then
|
|
|
|
begin
|
|
|
|
for n := x to Value.Count - 1 do
|
2008-04-23 23:48:39 +03:00
|
|
|
begin
|
2008-04-24 10:05:26 +03:00
|
|
|
s := Value[n];
|
2008-04-24 10:07:45 +03:00
|
|
|
if Pos('--' + FBoundary, s) = 1 then
|
2008-04-24 10:05:26 +03:00
|
|
|
begin
|
|
|
|
x1 := n;
|
|
|
|
Break;
|
|
|
|
end;
|
2008-04-23 23:48:39 +03:00
|
|
|
end;
|
2008-04-24 10:05:26 +03:00
|
|
|
for n := Value.Count - 1 downto x do
|
2008-04-23 23:48:39 +03:00
|
|
|
begin
|
2008-04-24 10:05:26 +03:00
|
|
|
s := Value[n];
|
2008-04-24 10:07:45 +03:00
|
|
|
if Pos('--' + FBoundary, s) = 1 then
|
2008-04-24 10:05:26 +03:00
|
|
|
begin
|
|
|
|
x2 := n;
|
|
|
|
Break;
|
|
|
|
end;
|
2008-04-23 23:48:39 +03:00
|
|
|
end;
|
2008-04-24 10:05:26 +03:00
|
|
|
end;
|
2008-04-24 10:07:45 +03:00
|
|
|
{ copy content }
|
2008-04-24 10:05:26 +03:00
|
|
|
for n := x1 to x2 do
|
|
|
|
FLines.Add(Value[n]);
|
|
|
|
Result := x2;
|
2008-04-24 10:07:45 +03:00
|
|
|
{ if content is multipart - find real end }
|
2008-04-24 10:05:26 +03:00
|
|
|
if FPrimaryCode = MP_MULTIPART then
|
|
|
|
begin
|
|
|
|
e := False;
|
|
|
|
for n := x2 + 1 to Value.Count - 1 do
|
2008-04-24 10:09:13 +03:00
|
|
|
if Pos('--' + b, Value[n]) = 1 then
|
2008-04-24 10:05:26 +03:00
|
|
|
begin
|
|
|
|
e := True;
|
|
|
|
Break;
|
|
|
|
end;
|
|
|
|
if not e then
|
|
|
|
Result := Value.Count - 1;
|
|
|
|
end;
|
2008-04-24 10:07:45 +03:00
|
|
|
{ if multipart - skip ending postpart}
|
|
|
|
if b <> '' then
|
|
|
|
begin
|
|
|
|
x1 := Result;
|
|
|
|
for n := x1 to Value.Count - 1 do
|
|
|
|
begin
|
|
|
|
s := Value[n];
|
|
|
|
if Pos('--' + b, s) = 1 then
|
|
|
|
begin
|
|
|
|
s := TrimRight(s);
|
|
|
|
x := Length(s);
|
|
|
|
if x > 4 then
|
|
|
|
if (s[x] = '-') and (S[x-1] = '-') then
|
|
|
|
Result := Value.Count - 1;
|
|
|
|
Break;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
end;
|
2008-04-23 23:48:39 +03:00
|
|
|
finally
|
2008-04-24 10:05:26 +03:00
|
|
|
t.Free;
|
2008-04-23 23:48:39 +03:00
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
{==============================================================================}
|
2008-04-24 10:05:26 +03:00
|
|
|
|
2008-04-23 23:48:39 +03:00
|
|
|
procedure TMIMEPart.DecodePart;
|
|
|
|
const
|
2008-04-24 10:05:26 +03:00
|
|
|
CRLF = #13#10;
|
2008-04-23 23:48:39 +03:00
|
|
|
var
|
2008-04-24 10:05:26 +03:00
|
|
|
n: Integer;
|
|
|
|
s: string;
|
2008-04-23 23:48:39 +03:00
|
|
|
begin
|
2008-04-24 10:05:26 +03:00
|
|
|
FDecodedLines.Clear;
|
|
|
|
for n := 0 to FLines.Count - 1 do
|
|
|
|
begin
|
|
|
|
s := FLines[n];
|
|
|
|
case FEncodingCode of
|
|
|
|
ME_7BIT:
|
|
|
|
s := s + CRLF;
|
|
|
|
ME_8BIT:
|
|
|
|
begin
|
|
|
|
s := CharsetConversion(s, FCharsetCode, FTargetCharset);
|
|
|
|
s := s + CRLF;
|
|
|
|
end;
|
|
|
|
ME_QUOTED_PRINTABLE:
|
|
|
|
begin
|
|
|
|
if s = '' then
|
|
|
|
s := CRLF
|
|
|
|
else
|
|
|
|
if s[Length(s)] <> '=' then
|
|
|
|
s := s + CRLF;
|
|
|
|
s := DecodeQuotedPrintable(s);
|
|
|
|
if FPrimaryCode = MP_TEXT then
|
|
|
|
s := CharsetConversion(s, FCharsetCode, FTargetCharset);
|
|
|
|
end;
|
|
|
|
ME_BASE64:
|
|
|
|
begin
|
|
|
|
if s <> '' then
|
|
|
|
s := DecodeBase64(s);
|
|
|
|
if FPrimaryCode = MP_TEXT then
|
|
|
|
s := CharsetConversion(s, FCharsetCode, FTargetCharset);
|
|
|
|
end;
|
|
|
|
ME_UU:
|
|
|
|
if s <> '' then
|
|
|
|
s := DecodeUU(s);
|
|
|
|
ME_XX:
|
|
|
|
if s <> '' then
|
|
|
|
s := DecodeXX(s);
|
2008-04-23 23:48:39 +03:00
|
|
|
end;
|
2008-04-24 10:05:26 +03:00
|
|
|
FDecodedLines.Write(Pointer(s)^, Length(s));
|
|
|
|
end;
|
|
|
|
FDecodedLines.Seek(0, soFromBeginning);
|
2008-04-23 23:48:39 +03:00
|
|
|
end;
|
|
|
|
|
|
|
|
{==============================================================================}
|
2008-04-24 10:05:26 +03:00
|
|
|
|
2008-04-23 23:48:39 +03:00
|
|
|
procedure TMIMEPart.EncodePart;
|
|
|
|
var
|
2008-04-24 10:05:26 +03:00
|
|
|
l: TStringList;
|
|
|
|
s, buff: string;
|
|
|
|
n, x: Integer;
|
2008-04-23 23:48:39 +03:00
|
|
|
begin
|
2008-04-24 10:05:26 +03:00
|
|
|
if (FEncodingCode = ME_UU) or (FEncodingCode = ME_XX) then
|
|
|
|
Encoding := 'base64';
|
|
|
|
l := TStringList.Create;
|
|
|
|
FLines.Clear;
|
|
|
|
FDecodedLines.Seek(0, soFromBeginning);
|
2008-04-23 23:48:39 +03:00
|
|
|
try
|
2008-04-24 10:05:26 +03:00
|
|
|
case FPrimaryCode of
|
|
|
|
MP_MULTIPART, MP_MESSAGE:
|
|
|
|
FLines.LoadFromStream(FDecodedLines);
|
|
|
|
MP_TEXT, MP_BINARY:
|
|
|
|
if FEncodingCode = ME_BASE64 then
|
|
|
|
begin
|
|
|
|
while FDecodedLines.Position < FDecodedLines.Size do
|
|
|
|
begin
|
|
|
|
Setlength(Buff, 54);
|
|
|
|
s := '';
|
|
|
|
x := FDecodedLines.Read(pointer(Buff)^, 54);
|
|
|
|
for n := 1 to x do
|
|
|
|
s := s + Buff[n];
|
|
|
|
if FPrimaryCode = MP_TEXT then
|
|
|
|
s := CharsetConversion(s, FTargetCharset, FCharsetCode);
|
|
|
|
s := EncodeBase64(s);
|
|
|
|
FLines.Add(s);
|
|
|
|
end;
|
|
|
|
end
|
|
|
|
else
|
2008-04-23 23:48:39 +03:00
|
|
|
begin
|
2008-04-24 10:05:26 +03:00
|
|
|
l.LoadFromStream(FDecodedLines);
|
|
|
|
for n := 0 to l.Count - 1 do
|
|
|
|
begin
|
|
|
|
s := l[n];
|
|
|
|
if FPrimaryCode = MP_TEXT then
|
|
|
|
s := CharsetConversion(s, FTargetCharset, FCharsetCode);
|
|
|
|
s := EncodeQuotedPrintable(s);
|
|
|
|
FLines.Add(s);
|
|
|
|
end;
|
2008-04-23 23:48:39 +03:00
|
|
|
end;
|
|
|
|
|
|
|
|
end;
|
2008-04-24 10:05:26 +03:00
|
|
|
FLines.Add('');
|
|
|
|
FLines.Insert(0, '');
|
|
|
|
if FSecondary = '' then
|
|
|
|
case FPrimaryCode of
|
|
|
|
MP_TEXT:
|
|
|
|
FSecondary := 'plain';
|
|
|
|
MP_MULTIPART:
|
|
|
|
FSecondary := 'mixed';
|
|
|
|
MP_MESSAGE:
|
|
|
|
FSecondary := 'rfc822';
|
|
|
|
MP_BINARY:
|
|
|
|
FSecondary := 'octet-stream';
|
2008-04-24 09:47:56 +03:00
|
|
|
end;
|
2008-04-24 10:05:26 +03:00
|
|
|
if FDescription <> '' then
|
|
|
|
FLines.Insert(0, 'Content-Description: ' + FDescription);
|
|
|
|
if FDisposition <> '' then
|
|
|
|
begin
|
|
|
|
s := '';
|
|
|
|
if FFileName <> '' then
|
|
|
|
s := '; FileName="' + FFileName + '"';
|
|
|
|
FLines.Insert(0, 'Content-Disposition: ' + LowerCase(FDisposition) + s);
|
|
|
|
end;
|
|
|
|
if FContentID <> '' then
|
|
|
|
FLines.Insert(0, 'Content-ID: ' + FContentID);
|
|
|
|
|
|
|
|
case FEncodingCode of
|
|
|
|
ME_7BIT:
|
|
|
|
s := '7bit';
|
|
|
|
ME_8BIT:
|
|
|
|
s := '8bit';
|
|
|
|
ME_QUOTED_PRINTABLE:
|
|
|
|
s := 'Quoted-printable';
|
|
|
|
ME_BASE64:
|
|
|
|
s := 'Base64';
|
2008-04-23 23:48:39 +03:00
|
|
|
end;
|
2008-04-24 10:05:26 +03:00
|
|
|
case FPrimaryCode of
|
2008-04-23 23:48:39 +03:00
|
|
|
MP_TEXT,
|
2008-04-24 10:05:26 +03:00
|
|
|
MP_BINARY: FLines.Insert(0, 'Content-Transfer-Encoding: ' + s);
|
2008-04-23 23:48:39 +03:00
|
|
|
end;
|
2008-04-24 10:05:26 +03:00
|
|
|
case FPrimaryCode of
|
|
|
|
MP_TEXT:
|
|
|
|
s := FPrimary + '/' + FSecondary + '; charset=' + GetIDfromCP(FCharsetCode);
|
|
|
|
MP_MULTIPART:
|
2008-04-24 10:07:45 +03:00
|
|
|
s := FPrimary + '/' + FSecondary + '; boundary="' + FBoundary + '"';
|
2008-04-24 10:05:26 +03:00
|
|
|
MP_MESSAGE:
|
|
|
|
s := FPrimary + '/' + FSecondary + '';
|
|
|
|
MP_BINARY:
|
|
|
|
s := FPrimary + '/' + FSecondary + '; name="' + FFileName + '"';
|
2008-04-23 23:48:39 +03:00
|
|
|
end;
|
2008-04-24 10:05:26 +03:00
|
|
|
FLines.Insert(0, 'Content-type: ' + s);
|
2008-04-23 23:48:39 +03:00
|
|
|
finally
|
2008-04-24 10:05:26 +03:00
|
|
|
l.Free;
|
2008-04-23 23:48:39 +03:00
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
{==============================================================================}
|
2008-04-24 10:05:26 +03:00
|
|
|
|
|
|
|
procedure TMIMEPart.MimeTypeFromExt(Value: string);
|
2008-04-23 23:48:39 +03:00
|
|
|
var
|
2008-04-24 10:05:26 +03:00
|
|
|
s: string;
|
|
|
|
n: Integer;
|
2008-04-23 23:48:39 +03:00
|
|
|
begin
|
2008-04-24 10:05:26 +03:00
|
|
|
Primary := '';
|
|
|
|
FSecondary := '';
|
|
|
|
s := UpperCase(ExtractFileExt(Value));
|
|
|
|
if s = '' then
|
|
|
|
s := UpperCase(Value);
|
|
|
|
s := SeparateRight(s, '.');
|
|
|
|
for n := 0 to MaxMimeType do
|
|
|
|
if MimeType[n, 0] = s then
|
|
|
|
begin
|
|
|
|
Primary := MimeType[n, 1];
|
|
|
|
FSecondary := MimeType[n, 2];
|
|
|
|
Break;
|
|
|
|
end;
|
|
|
|
if Primary = '' then
|
|
|
|
Primary := 'application';
|
|
|
|
if FSecondary = '' then
|
2008-04-24 10:07:45 +03:00
|
|
|
FSecondary := 'octet-string';
|
2008-04-23 23:48:39 +03:00
|
|
|
end;
|
|
|
|
|
|
|
|
{==============================================================================}
|
2008-04-24 10:05:26 +03:00
|
|
|
|
|
|
|
procedure TMIMEPart.SetPrimary(Value: string);
|
2008-04-23 23:48:39 +03:00
|
|
|
var
|
2008-04-24 10:05:26 +03:00
|
|
|
s: string;
|
2008-04-23 23:48:39 +03:00
|
|
|
begin
|
2008-04-24 10:05:26 +03:00
|
|
|
FPrimary := Value;
|
|
|
|
s := UpperCase(Value);
|
|
|
|
FPrimaryCode := MP_BINARY;
|
|
|
|
if Pos('TEXT', s) = 1 then
|
|
|
|
FPrimaryCode := MP_TEXT;
|
|
|
|
if Pos('MULTIPART', s) = 1 then
|
|
|
|
FPrimaryCode := MP_MULTIPART;
|
|
|
|
if Pos('MESSAGE', s) = 1 then
|
|
|
|
FPrimaryCode := MP_MESSAGE;
|
2008-04-23 23:48:39 +03:00
|
|
|
end;
|
|
|
|
|
2008-04-24 10:05:26 +03:00
|
|
|
procedure TMIMEPart.SetEncoding(Value: string);
|
2008-04-23 23:48:39 +03:00
|
|
|
var
|
2008-04-24 10:05:26 +03:00
|
|
|
s: string;
|
2008-04-23 23:48:39 +03:00
|
|
|
begin
|
2008-04-24 10:05:26 +03:00
|
|
|
FEncoding := Value;
|
|
|
|
s := UpperCase(Value);
|
|
|
|
FEncodingCode := ME_7BIT;
|
|
|
|
if Pos('8BIT', s) = 1 then
|
|
|
|
FEncodingCode := ME_8BIT;
|
|
|
|
if Pos('QUOTED-PRINTABLE', s) = 1 then
|
|
|
|
FEncodingCode := ME_QUOTED_PRINTABLE;
|
|
|
|
if Pos('BASE64', s) = 1 then
|
|
|
|
FEncodingCode := ME_BASE64;
|
|
|
|
if Pos('X-UU', s) = 1 then
|
|
|
|
FEncodingCode := ME_UU;
|
|
|
|
if Pos('X-XX', s) = 1 then
|
|
|
|
FEncodingCode := ME_XX;
|
2008-04-23 23:48:39 +03:00
|
|
|
end;
|
|
|
|
|
2008-04-24 10:05:26 +03:00
|
|
|
procedure TMIMEPart.SetCharset(Value: string);
|
2008-04-23 23:48:39 +03:00
|
|
|
begin
|
2008-04-24 10:05:26 +03:00
|
|
|
FCharset := Value;
|
|
|
|
FCharsetCode := GetCPFromID(Value);
|
2008-04-23 23:48:39 +03:00
|
|
|
end;
|
|
|
|
|
|
|
|
{==============================================================================}
|
2008-04-24 10:05:26 +03:00
|
|
|
|
|
|
|
function GenerateBoundary: string;
|
2008-04-23 23:48:39 +03:00
|
|
|
var
|
2008-04-24 10:05:26 +03:00
|
|
|
x: Integer;
|
2008-04-23 23:48:39 +03:00
|
|
|
begin
|
2008-04-24 10:05:26 +03:00
|
|
|
Randomize;
|
|
|
|
x := Random(MaxInt);
|
2008-04-24 10:07:45 +03:00
|
|
|
Result := '--' + IntToHex(x, 8) + '_Synapse_message_boundary--';
|
2008-04-23 23:48:39 +03:00
|
|
|
end;
|
|
|
|
|
|
|
|
end.
|