Richard, The statement that "the character sequence <CRLF>.<CRLF> IS NOT a line containing only a period" is wrong. As you know from your own finite state machine, the required sequence in the stream is precisely CR-LF-.-CR-LF, which would be interpreted as
CR need-lf LF newline . line-containing-a-period-so-far CR newline-dot-cr-need-lf LF end-of-data Recognizing .<CRLF> is not sufficient; that implies already being in the newline state. It is the initial <CRLF> that puts the dot on a line by itself by putting your FSM into LINE_STARTING_STATE. Yes, there is a bug in James because it separates the command and data streams, and doesn't start the data stream in the NEWLINE state. And that should be fixed, although as both Valdis and Keith pointed out, an empty data set isn't a valid message. The <CRLF>.<CRLF> is written as a marker for another reason, and that is to indicate that the entire sequence is the terminator. That was the point of apparent disagreement between Keith and Daniel Bernstein. But they weren't really disagreeing. The RFC doesn't require you to store <CRLF> or any other line terminator at all. It only requires that whatever you use to represent line separation internally, you must use <CRLF> to separate lines in the stream when transmitting the data. As Keith illustrated, code can ensure the proper data terminator when delivering the message via SMTP or POP3. What you do internally is up to the program. Right now, as you noted (http://marc.theaimsgroup.com/?l=james-dev&m=105527214016488&w=2), James strips the entire <CRLF>.<CRLF> sequence, which is precisely the behavior that both Valdis ad Keith told you was correct. Then the POP3 handler will send the entire <CRLF>.<CRLF> sequence, as would the SMTP transport. Please note that JavaMail sends an explicit "\r\n.\r\n" to terminate the data stream. I believe that you indicated that you plan to use JavaMail. > I see that this submission makes work for you if you undertake to > implement and test it. Anything that deals with RFC compliance deserves special attention, and you seem to have a different understanding of the RFC, e.g., * <li>When the end of mail data indicator is recognized in the input stream, * the CRLF which immediately preceded the period in the indicator is * returned as part of the mail data as the CRLF which concludes the final * line of mail data, rather than being discarded as part of the end of mail * data indicator. None of this is to say that SMTPInputStream might not be useful, but if you make different assumptions about the RFC, then we would have to adjust the code in order to use it. FilteredInputStream is the right thing to extend. SMTPInputStream implements read() based upon the real stream, which is the one non-constructor method that is correct in the code. The rest are wrong. For example: public void close() throws IOException{ super.close(); } explicitly illustrates a problem that is implicit with all of the inherited methods. The code invokes the inherited implementation, often a NO-OP. It ought to be delegating to the real stream. FilteredInputStream provides the core wrapper for delegation, allowing you to override just those methods that implement your unique behavior. --- Noel --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]