Post by Yahoo SeriousWhat I mean is: if you define ATerminator to be LF or empty
(which defaults to LF), this is interpreted as "receive a line of
text without the terminating line break".
ReadLn() always strips off whatever terminator is specified. For example:
line := TCPClient.ReadLn('end');
If ReadLn() receives 'this is the end' then only 'this is the ' will be
returned. That is by design.
Post by Yahoo SeriousThen both LF and CRLF are considered a terminator and removed.
I already explained why that is.
Post by Yahoo SeriousBut CR alone is not considered a terminator (and not removed) in this
scenario.
If CR is the sole terminator, it will be stripped off as expected when
ReadLn() receives a line with CR in it. If ReadLn() received a CRLF rather
than just a CR, the LF will be preserved (though it will be carried over to
the next ReadLn() call). Again, that is by design. CR by itself is a valid
single-character terminator, and will be treated as such. LF by itself
refers to both CRLF and LF as a terminator. CRLF is a special case for
reasons I have already explained.
Post by Yahoo SeriousIf one would define ATerminator to be CR, it would not remove LF and CRLF.
It is not supposed to, by design.
Post by Yahoo SeriousSo my point is, that using LF as "receive a line of text without
the terminating line break", is not handling all the cases
It is not supposed to, by design. Again, CRLF is a single special case in
order to handle most Internet protocols. Stop reading too much into this.
You keep misinterpretting what ReadLn() does.
Post by Yahoo SeriousIf one can use/interpret ATerminator=LF as "receive a line of
text without the terminating line break"
That is not what it means. You are misinterpretting it. ATerminator=LF
means only LF and CRLF exclusively. Nothing else. It does NOT mean "all
possible line breaks".
Post by Yahoo Seriousthen I think this interpretation should handle all cases.
No, it should not, because that is the wrong interpretation to begin with.
Post by Yahoo SeriousSo it should also handle these Unicode-breaks.
No can do. Do you know how many Unicode line breaks there actually are? Do
you really want ReadLn() to waste time and memory checking for all of them?
And for what? Most protocols don't use them anyway. If you want to support
them, then derive your own client code that checks for them as needed.
Post by Yahoo SeriousPost by Remy Lebeau (TeamB)Most standardized Internet protocols are line-based textual protocols.
And how will those protocols handle lines ending in just CR, NEL, or LS?
Have you read any RFCs for any Internet protocols? Any protocol that is
based on textual lines has to explicitally define which line breaks are
actually valid for the protocol. Most protocols use CRLF exclusively. In
fact, most protocols are ASCII based only, so Unicode line breaks don't
apply anyway. Any protocol that wants to support Unicode generally has to
use UTF-8 or other encoding so Unicode data stays within the confines of the
ASCII subset for the procotol. So Unicode line breaks still would not apply
when reading lines from the connection.
Post by Yahoo SeriousReadLn is the only public method available to read using a time out
No, it is not. The connection's ReadTimeout property applies to all of the
reading methods equally. It just happens that ReadLn() also has its own
ATimeout parameter on top of that. When ATimeout is IdTimeoutDefault, the
ReadTimeout property is used instead. This allows per-line timeouts to be
specified. But most usages of ReadLn() do not make use of that feature.
Post by Yahoo Seriouswhich is also implied by the property name ReadLnTimedOut
That property exists for convenience. There are cases where protocol
handlers want to know if a line timed out, without using exception handlers
to detect that.
Post by Yahoo SeriousSo I agree it is a completely unrelated feature, but (unfortunately) it is
not [implemented] completely separate.
Yes, it is implemented separately. ReadLn()'s timeout handling is just
extra handling on top of the generic timeout handling that applies to the
entire connection as a whole.
Post by Yahoo SeriousPost by Remy Lebeau (TeamB)Post by Yahoo SeriousMaybe there could be a separate "ReadLn" and
"ReadUntilSeparatorWithTimeOut" to prevent any confusion.
There is no need to do that.
IMO it would complicate implementation, but it would clarify behavior.
Not really. Considering that ReadLn() already has an ATimeout parameter
that is visible and documented, having a separate
ReadUntilSeparatorWithTimeOut() method is just redundant and a waste of
code.
Post by Yahoo SeriousBut I'll settle for support for multi character terminators ;-)
It has already been implemented. I checked in some new code last night.
Gambit