Discussion:
Error loading from stream
(too old to reply)
Uli Becker
2008-07-09 07:38:00 UTC
Permalink
Hi,

I am using this code to load a message (formerly saved by using Indy9 btw)
into an idMessage component:

idMessage.clear;
ms := TEDBBlobStream.Create(dm.MessagesTableMessage, bmread);
try
ms.position := 0;
idMessage.LoadFromStream(ms,false);
ShowMessage(idMessage.Body.Text); <---------------- Error or empty
finally
ms.Free;
end;

When executing the code I get an empty result in most cases, in some cases
this error is raised: "Max line length exceeded."

Saving the same message to file as .eml from the database and loading it
into idMessage always works fine.
What could be wrong here? (Delphi2007 last Indy snapshot)

Here you find an eml-file that produces the error when loaded from
stream: www.beckersoft.de/temp/sample.eml

Thanks. Uli
Remy Lebeau (TeamB)
2008-07-09 19:06:00 UTC
Permalink
Post by Uli Becker
ms := TEDBBlobStream.Create(dm.MessagesTableMessage, bmread);
You should use the CreateBlobStream() method instead:

ms :=
dm.MessagesTableMessage.DataSet.CreateBlobStream(dm.MessagesTableMessage,
bmRead);
Post by Uli Becker
When executing the code I get an empty result in most cases
What does the actual blob data look like? Most likely, the data is being
stored in the TIdMessage.MessageParts collection instead.
Post by Uli Becker
in some cases this error is raised: "Max line length exceeded."
By default, the maximum length that individual lines of text can be is 16384
characters. TIdTCPConnection in Indy 9, and TIdIOHandler in Indy 10, have a
MaxLineLength that you can set to increase that value if needed.
Post by Uli Becker
Saving the same message to file as .eml from the database and
loading it into idMessage always works fine.
TIdMessage.LoadFromFile() calls LoadFromStream() internally, so the same
logic is invoked either way.
Post by Uli Becker
Here you find an eml-file that produces the error when loaded from
stream: www.beckersoft.de/temp/sample.eml
That is not a valid .eml file


Gambit
Uli Becker
2008-07-10 07:51:06 UTC
Permalink
Remy,

thanks for your help.

<<
You should use the CreateBlobStream() method instead:
I did, and there are no empty results any more. But the error (Max line
length exceeded) is the same.
I tried to debug it and found the reason for the error here:

function TIdIOHandler.ReadLnRFC(var VMsgEnd: Boolean; const ALineTerminator:
string;
const ADelim: String = '.'; const AEncoding: TIdEncoding = en7Bit):
string;
begin
Result := ReadLn(ALineTerminator, AEncoding);
<------------------------------------------ Error
// Do not use ATerminator since always ends with . (standard)
if Result = ADelim then
begin
VMsgEnd := True;
Exit;
end;
if TextStartsWith(Result, '.') then begin {do not localize}
Delete(Result, 1, 1);
end;
VMsgEnd := False;
end;

<<
What does the actual blob data look like? Most likely, the data is being
stored in the TIdMessage.MessageParts collection instead.
It's exactly the content of the eml-file.
I found out that the error only occurs if there is a file-attachment in the
message.

<<
By default, the maximum length that individual lines of text can be is 16384
characters. TIdTCPConnection in Indy 9, and TIdIOHandler in Indy 10, have a
MaxLineLength that you can set to increase that value if needed.
I checked the blob-content. Actually there are no long lines in it.

<<
stream: www.beckersoft.de/temp/sample.eml
That is not a valid .eml file
It was saved by using an indy9 idMessage component. Outlook Express has no
problems to open it.

Regards Uli
Remy Lebeau (TeamB)
2008-07-10 08:17:19 UTC
Permalink
You did not show the call stack leading up to ReadLnRFC().
Post by Uli Becker
I found out that the error only occurs if there is a file-attachment
in the message.
<snip>
Post by Uli Becker
I checked the blob-content. Actually there are no long lines in it.
Then it is likely calling ReadLn() on a block of binary data, not textual
data.

You did not show the actual .eml data like I asked for. It is very
important to see all of the message headers and such.
Post by Uli Becker
Post by Uli Becker
stream: www.beckersoft.de/temp/sample.eml
That is not a valid .eml file
It was saved by using an indy9 idMessage component.
Outlook Express has no problems to open it.
The data I see at that URL is an HTML webpage, not an .eml file.


Gambit
Uli Becker
2008-07-10 10:22:13 UTC
Permalink
Remy,
Post by Remy Lebeau (TeamB)
You did not show the call stack leading up to ReadLnRFC().
I'll check that out.
Post by Remy Lebeau (TeamB)
stream: www.beckersoft.de/temp/sample.eml
The data I see at that URL is an HTML webpage, not an .eml file.
That's weird. I just clicked on the link and was able to download the .eml
file.
Here a new try:

http://www.beckersoft.de/temp/test.zip

Regards Uli
Remy Lebeau (TeamB)
2008-07-10 17:20:16 UTC
Permalink
Post by Uli Becker
That's weird. I just clicked on the link and was able to
download the .eml file.
http://www.beckersoft.de/temp/test.zip
Better.

I see nothing in that message that can cause a "Max line length exceeded"
exception to be raised. Are you sure the DB blob is not stripping out CRLF
characters, by chance?


Gambit
Uli Becker
2008-07-10 20:31:11 UTC
Permalink
Remy,
Post by Remy Lebeau (TeamB)
I see nothing in that message that can cause a "Max line length exceeded"
exception to be raised. Are you sure the DB blob is not stripping out
CRLF characters, by chance?
I don't know how to check that, here is the (quite simple) code (I am using
ElevateDB):

procedure TForm1.Button6Click(Sender: TObject);
var
MyStream: TStream;
begin
memoRawMessage.lines.text := dm.MessagesTableMessage.value;
MyStream :=
dm.MessagesTable.CreateBlobStream(dm.MessagesTableMessage,bmread);
try
MyStream.position := 0;
try
idMessage.LoadFromStream(MyStream);
ShowMessage(idMessage.headers.text);
except
ShowMessage('Error');
end;
finally
MyStream.free;
end;
end;

Regards Uli
Remy Lebeau (TeamB)
2008-07-11 01:27:27 UTC
Permalink
Post by Uli Becker
I don't know how to check that
View the raw blob data. Or save it to a file.


Gambit
Uli Becker
2008-07-11 20:19:37 UTC
Permalink
Post by Remy Lebeau (TeamB)
View the raw blob data. Or save it to a file.
I saved the stream to a listbox. No rows in there longer than 77 chars.

Regards Uli
Remy Lebeau (TeamB)
2008-07-11 20:29:46 UTC
Permalink
Post by Uli Becker
I saved the stream to a listbox. No rows in there longer than 77 chars.
I'd rather you save it to a file. Then you can view the actual link breaks.
Loading it into a ListBox loses that information.


Gambit
Uli Becker
2008-07-12 06:31:01 UTC
Permalink
Post by Remy Lebeau (TeamB)
I'd rather you save it to a file. Then you can view the actual link
breaks. Loading it into a ListBox loses that information.
Sorry, I don't want to waste your time, but:TStream has no saveToFile
method. Since I am not familiar with streams I don't know how to do that.

Uli
Remy Lebeau (TeamB)
2008-07-12 07:56:23 UTC
Permalink
TStream has no saveToFile method.
Instantiate a separate TFileStream object and then pass the blob stream to
its CopyFrom() method, ie:

procedure TForm1.Button6Click(Sender: TObject);
var
BStream, FStream: TStream;
begin
BStream :=
dm.MessagesTable.CreateBlobStream(dm.MessagesTableMessage, bmRead);
try
FStream := TFileStream.Create('c:\blob.data', fmCreate);
try
FStream.CopyFrom(BStream, 0);
finally
FStream.Free;
end;
finally
BStream.Free;
end;
end;


Gambit
Uli Becker
2008-07-12 12:46:55 UTC
Permalink
Post by Remy Lebeau (TeamB)
Instantiate a separate TFileStream object and then pass the blob stream to
Thanks for your patience.

Here the saved blob-stream:

http://www.beckersoft.de/temp/blob.zip

Would you please have a look on it?

Thanks and regards Uli
Uli Becker
2008-07-15 06:59:17 UTC
Permalink
Remy,

could you already have a look on the saved stream?

Thank you.

Uli
Post by Uli Becker
Post by Remy Lebeau (TeamB)
Instantiate a separate TFileStream object and then pass the blob stream
Thanks for your patience.
http://www.beckersoft.de/temp/blob.zip
Would you please have a look on it?
Thanks and regards Uli
Remy Lebeau (TeamB)
2008-07-15 16:38:56 UTC
Permalink
Post by Uli Becker
http://www.beckersoft.de/temp/blob.zip
Would you please have a look on it?
Your data is using CR for all of its line breaks instead of using LF or
CRLF, as required by not only Indy but also the RFC standards for email
messages in general. That is why you are getting the "Max line length
exceeded" error. You need to fix your data.


Gambit
Uli Becker
2008-07-15 18:47:51 UTC
Permalink
Thank you very much for your help!

Uli
Post by Remy Lebeau (TeamB)
Post by Uli Becker
http://www.beckersoft.de/temp/blob.zip
Would you please have a look on it?
Your data is using CR for all of its line breaks instead of using LF or
CRLF, as required by not only Indy but also the RFC standards for email
messages in general. That is why you are getting the "Max line length
exceeded" error. You need to fix your data.
Gambit
Loading...