gecko-dev/grendel/mime/parser/MimeMessageRFC822.java

112 строки
3.4 KiB
Java

/* -*- Mode: java; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.0 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
*
* The Original Code is the Grendel mail/news client.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are Copyright (C) 1997
* Netscape Communications Corporation. All Rights Reserved.
*
* Created: Jamie Zawinski <jwz@netscape.com>, 21 Aug 1997.
*/
package grendel.mime.parser;
import grendel.mime.IMimeOperator;
import calypso.util.ByteBuf;
import calypso.util.ByteLineBuffer;
import javax.mail.internet.InternetHeaders;
/** This class implements the parser for the message/rfc822 and message/news
MIME containers, which is to say, mail and news messages. This is a
container which holds exactly one child, the body: messages with multiple
parts are those which have a multipart/ as their body.
@see MimeMultipart
@see MimeLeaf
*/
class MimeMessageRFC822 extends MimeContainer {
ByteLineBuffer line_buffer;
ByteBuf line_bytes;
InternetHeaders child_headers;
public MimeMessageRFC822(String content_type, InternetHeaders headers) {
super(content_type, headers);
line_buffer = new ByteLineBuffer();
line_bytes = new ByteBuf(100);
child_headers = new InternetHeaders();
}
/** Buffers the bytes into lines, and calls process_line() on each line. */
public void pushBytes(ByteBuf bytes) {
line_buffer.pushBytes(bytes);
while (line_buffer.pullLine(line_bytes))
process_line(line_bytes);
}
/** Flushes the line buffer, and (maybe) calls process_line() one last time.
*/
public void pushEOF() {
line_buffer.pushEOF();
while (line_buffer.pullLine(line_bytes))
process_line(line_bytes);
line_buffer = null;
// make sure every message has a body, even if it's a null body.
if (open_child == null) {
line_bytes.setLength(0);
line_bytes.append("\r\n");
process_line(line_bytes);
}
line_bytes = null;
super.pushEOF();
}
/** Called for each line of this message. */
void process_line(ByteBuf line) {
if (open_child == null) { // Still parsing the headers
child_headers.addHeaderLine(line.toString());
// If this is a blank line, create a child.
byte b = line.byteAt(0);
if (b == '\r' || b == '\n') {
String hh[] = child_headers.getHeader("Content-Type");
String child_type = null;
if (hh != null && hh.length != 0) {
child_type = hh[0];
// #### strip to first token
int i = child_type.indexOf(';');
if (i > 0)
child_type = child_type.substring(0, i);
child_type = child_type.trim();
}
hh = null;
openChild(child_type, child_headers);
child_type = null;
child_headers = null;
}
} else { // Parsing the body
open_child.pushBytes(line);
}
}
}