[Oberon] Removing unnecessary and embedded RETURNs.
joerg.straube at iaeth.ch
joerg.straube at iaeth.ch
Mon Nov 13 06:37:10 CET 2023
Peter
You said “ReadText is external to this byte padding.” Is it?
RFC 1939 states:
Responses to certain commands are multi-line. In these cases, which
are clearly indicated below, after sending the first line of the
response and a CRLF, any additional lines are sent, each terminated
by a CRLF pair. When all lines of the response have been sent, a
final line is sent, consisting of a termination octet (decimal code
046, ".") and a CRLF pair. If any line of the multi-line response
begins with the termination octet, the line is "byte-stuffed" by
pre-pending the termination octet to that line of the response.
Hence a multi-line response is terminated with the five octets
"CRLF.CRLF". When examining a multi-line response, the client checks
to see if the line begins with the termination octet. If so and if
octets other than CRLF follow, the first octet of the line (the
termination octet) is stripped away. If so and if CRLF immediately
follows the termination character, then the response from the POP
server is ended and the line containing ".CRLF" is not considered
part of the multi-line response.
As the last line with only “.CRLF” is not considered part of the text, you should delay Files.Write(R, ch); in state 3, 4, 5 until you know whether it’s the termination case or byte-stuffed case.
BTW: the original code does not copy the starting “.” of a line to the file, but copies over the final CRLF. In most cases, this additional CRLF at the end does not harm but is - strictly speaking - not correct.
br
Jörg
Von: joerg.straube at iaeth.ch <joerg.straube at iaeth.ch>
Datum: Montag, 13. November 2023 um 06:08
An: ETH Oberon and related systems <oberon at lists.inf.ethz.ch>
Betreff: AW: [Oberon] Removing unnecessary and embedded RETURNs.
Peter
The idea with the state machine is good.
One remark:
I don’t understand you remark “ReadText is external to this byte padding”
In my point of view in the ELSE part of state 3 you would have to strip the stuffed period.
In other words: you would have to reposition and copy the Files.Write(R, ch); to almost all your cases
br
Jörg
Von: Oberon <oberon-bounces at lists.inf.ethz.ch> im Auftrag von peter at easthope.ca <peter at easthope.ca>
Datum: Sonntag, 12. November 2023 um 15:58
An: oberon at lists.inf.ethz.ch <oberon at lists.inf.ethz.ch>
Betreff: Re: [Oberon] Removing unnecessary and embedded RETURNs.
This is my alternative Mail.ReadText with no RETURN. ReportError was
helpful in debugging; probably can be deleted now.
Apology for the verbose comments. Added to help a non-expert
understand the non-obvious activity. =8~)
I wonder whether this use of CASE is good practise. Observations?
Thanks, ... P.L.
PROCEDURE ReportError(c: CHAR);
BEGIN
Texts.WriteString(W, "Mail.ReadText(): LF absent at CASE "); Texts.Write(W, c);
Texts.Write(W, "."); Texts.WriteLn(W);
Texts.Append(Oberon.Log, W.buf); HALT(6)
END ReportError;
(* According to Post Office Protocol, the end of a message body is
marked by character sequence CR LF "." CR LF.
A message line can begin with a period. To distinguish from end-of-message,
the message sender prepends an additional period which is removed before the
message is displayed to the recipient. ReadText is external to this byte padding.
https://en.wikipedia.org/wiki/Post_Office_Protocol
https://tools.ietf.org/html/rfc1939#section-3 *)
PROCEDURE ReadText(S: NetTools.Session; VAR R: Files.Rider);
VAR
buffer: ARRAY BufLen OF CHAR;
len, readLen, i: SIGNED32;
ch: CHAR;
progress: CHAR; (*
"0"= continuing
"1"= CR
"2"= CR LF
"3"= CR LF "."
"4"= CR LF "." CR
"5"= CR LF "." CR LF = end-of-message; or no more characters *)
BEGIN
readLen := 0;
i := readLen;
progress := "0";
WHILE progress < "5" DO (* Write byte to the MailMessages file. *)
IF i = readLen THEN (* More characters required. *)
len := NetSystem.Available(S.C);
IF (len = 0) & (NetSystem.State(S.C) # NetSystem.inout) THEN
progress := "5"
ELSE
IF len > (BufLen-2) THEN readLen := BufLen-2 ELSE readLen := len END;
NetSystem.ReadBytes(S.C, 0, readLen, buffer);
DEC(len, readLen);
i := 0
END
ELSE (* i < readLen. character available *)
ch := buffer[i];
CASE progress OF
"0": IF ch = Strings.CR THEN progress := "1" END |
"1": IF ch = Strings.LF THEN progress := "2" ELSE ReportError(progress) END |
"2": IF ch = Strings.CR THEN progress := "1"
ELSIF ch = "." THEN progress := "3" ELSE progress := "0" END |
"3": IF ch = Strings.CR THEN progress := "4" ELSE progress := "0" END |
"4": IF ch = Strings.LF THEN progress := "5" ELSE ReportError(progress) END
END;
Files.Write(R, ch);
INC(i)
END
END
END ReadText;
-
VoIP: +1 604 670 0140
work: https://en.wikibooks.org/wiki/User:PeterEasthope
--
Oberon at lists.inf.ethz.ch mailing list for ETH Oberon and related systems
https://lists.inf.ethz.ch/mailman/listinfo/oberon
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.inf.ethz.ch/pipermail/oberon/attachments/20231113/bd2bac73/attachment.html>
More information about the Oberon
mailing list