Watch, Follow, &
Connect with Us

For forums, blogs and more please visit our
Developer Tools Community.


Welcome, Guest
Guest Settings
Help

Thread: Copying IdMessageParts from one IdMessage to other



Permlink Replies: 2 - Last Post: Nov 13, 2017 7:33 PM Last Post By: Joao Lira
Joao Lira

Posts: 40
Registered: 3/25/03
Copying IdMessageParts from one IdMessage to other
Click to report abuse...   Click to reply to this thread Reply
  Posted: Nov 12, 2017 6:28 PM
Hello,

How can I copy the 'IdMessageParts' from one 'IdMessage' to other?

I have an 'A' IdMessage and need to copy it to a 'B' IdMessage. If I do 'B := A' it copies, as expected, but when I do that it changes the 'ContentType boundary'. I am testing this copying a multi-part message ('text/html') and when the 'B' IdMessage is sent through SMTP the received message has a new 'ContentType boundary', so the message shows a messed 'html' part of the message. I think that this method of copying the 'IdMessageParts' isn't the best. How to copy ALL 'IdMessageParts' from 'A' to 'B' no matter the MIME types of 'IdMessageParts'?

Thanks for any help.

Joao Lira.

Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: Copying IdMessageParts from one IdMessage to other
Click to report abuse...   Click to reply to this thread Reply
  Posted: Nov 13, 2017 10:57 AM   in response to: Joao Lira in response to: Joao Lira
Joao Lira wrote:

How can I copy the 'IdMessageParts' from one 'IdMessage' to other?

You don't.

Although TIdMessageParts is a TCollection, its CollectionItem property
is set to TIdMessagePart, so any automated copying by the RTL (ie, the
Assign() method), will not copy descendants correctly (TIdText,
TIdAttachment..., etc). Also, even if it could copy descendants
correctly, TIdText implements Assign(), but TIdAttachment... does not,
so the attachment data would not be copied, only headers.

You are going to manually populate the target TIdMessageParts with data
that you manually copy from the source TIdMessageParts.

I have an 'A' IdMessage and need to copy it to a 'B' IdMessage. If I
do 'B := A' it copies, as expected

No, it doesn't. All that does is sets the 'B' object reference to
point at the 'A' object. No copy is performed at all.

but when I do that it changes the 'ContentType boundary'.

I am testing this copying a multi-part message ('text/html') and when
the 'B' IdMessage is sent through SMTP the received message has a new
'ContentType boundary'

As it should be, because TIdMessageClient (which TIdSMTP derives from)
generates new MIME boundaries when encoding a MIME-formatted TIdMessage
for transmission.

so the message shows a messed 'html' part of the message.

Then you don't have the TIdMessage setup correctly.

I think that this method of copying the 'IdMessageParts' isn't the
best.

There is no copy being performed.

How to copy ALL 'IdMessageParts' from 'A' to 'B' no matter the MIME
types of 'IdMessageParts'?

You would probably need to do something like this:

var
  OldPart, NewPart: TIdMessagePart;
  I: Integer;
  StreamToCopy: TStream;
begin
  for I := 0 to A.MessageParts.Count-1 do
  begin
    OldPart := A.MessageParts[I];
 
    // figure out what kind of descendant to create...
    case OldPart.PartType of
      mptText:
      begin
        NewPart := TIdText.Create(B.MessageParts, nil);
      end;
      mptAttachment:
      begin
        if OldPart.ClassType = TIdAttachmentFile then
        begin
          // just point it to the same existing file ...
          NewPart := TIdAttachmentFile.Create(B.MessageParts,
TIdAttachmentFile(OldPart).StoredPathName);
        end
        else if OldPart.ClassType = TIdAttachmentMemory then
        begin
          // make a copy of the memory data (unless you want to write
          // a custom TIdAttachment descendant that delegates to
          // TIdAttachmentMemory(OldPart).DataStream) ...
          StreamToCopy := OldPart.OpenLoadStream;
          try
            NewPart := TIdAttachmentMemory.Create(B.MessageParts,
StreamToCopy);
          finally
            OldPart.CloseLoadStream;
          end;
        end
        else
          raise Exception.Create('Unsupported attachment class type!');
      end;
    else
      raise Exception.Create('Unsupported message part type!');
    end;
 
    // copy headers...
    NewPart.Assign(OldPart);
  end;
end;


--
Remy Lebeau (TeamB)
Joao Lira

Posts: 40
Registered: 3/25/03
Re: Copying IdMessageParts from one IdMessage to other
Click to report abuse...   Click to reply to this thread Reply
  Posted: Nov 13, 2017 7:33 PM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
Hello Remy,

Thank you for your answer. I'll check your example and test it.

Regards,

Joao Lira.

Legend
Helpful Answer (5 pts)
Correct Answer (10 pts)

Server Response from: ETNAJIVE02