Hi,
Ken wrote:
> Andy wrote:
> > Precisely. Though in my current patch proposal, the problem isn't
> > with CR/LF but with the two .. signal terminator coming from POP.
> > The two dots must be getting split and the first dot is at the end
> > of a buffer and the second is at the beginning of the next buffer.
>
> Yeah, I was realizing this. I think the logic has to be something
> like:
>
> - netsec_read() into buffer 'b';
>
> - Loop over 'b':
>
> If ! CR && ! LF
> putc()
>
> If CR
> check to see if next character is LF. If it is, skip over CR.
> If it is not, output CR. If at the end of the buffer, read
> more and restart loop.
>
> If LF
> If at the end of buffer, read more and loop back to top.
>
> Output LF. If the next character is ".", make sure not at end of
> buffer (must have at least two more characters). If are, read more
> and loop back to top.
>
> If the next character is "." and the characters AFTER "." is not
> CR-LF, skip over ".". If the next characters ARE ". CR LF", then
> terminate multiline response.
>
> I ... think that's correct?
This kind of thing gets messy once there starts to be multiple booleans
tracking state. Have all cases been considered? I find it easier to
have states and events with a table which shows what happens in every
S*E cases.
So roughly starting like this. Roughly as I don't know the protocol so
don't know my aim. But I do know I can shuffle my way through the
table, one input byte at a time, finding out the action(s) and possible
new state.
══════════╤═══════════════════════════════════════════════════════════
│ Event
State │ CR LF . else
──────────┼───────────────────────────────────────────────────────────
start │ →cr put(LF) put(.) put(*)
cr │ put(CR) put(LF),→crlf put(.),→start put(*),→start
crlf │ →cr put(LF),→start →crlfdot put(*),→start
crlfdot │ put(.),→cr put(.LF),→start →crlf2dot put(.*)
crlf2dot │ ...
──────────┴───────────────────────────────────────────────────────────
An ‘->err’ can cause an ‘all engines stop’.
This doesn't need to be implemented as a big switch statement with an
enum for state. If the range of actions is small, it's often possible
to use an array of strings, one per state, with the printable chars
being a small instruction code. This remains readable, with some study,
and represents the table instead of the table ending up unmaintained in
a comment and the switch statement spread over screenfuls.
--
Cheers, Ralph.