if (parseDebug)
System.out.println("DEBUG IMAP: parsing BODYSTRUCTURE");
msgno = r.getNumber();
if (parseDebug)
System.out.println("DEBUG IMAP: msgno " + msgno);
r.skipSpaces();
if (r.readByte() != '(")
throw new ParsingException(
"BODYSTRUCTURE parse error: missing ``('' at start");
if (r.peekByte() == '(") { // multipart
if (parseDebug)
System.out.println("DEBUG IMAP: parsing multipart");
type = "multipart";
processedType = MULTI;
Vector v = new Vector(1);
int i = 1;
do {
v.addElement(new BODYSTRUCTURE(r));
/*
* Even though the IMAP spec says there can't be any spaces
* between parts, some servers erroneously put a space in
* here. In the spirit of "be liberal in what you accept",
* we skip it.
*/
r.skipSpaces();
} while (r.peekByte() == '(");
// setup bodies.
bodies = new BODYSTRUCTURE[v.size()];
v.copyInto(bodies);
subtype = r.readString(); // subtype
if (parseDebug)
System.out.println("DEBUG IMAP: subtype " + subtype);
if (r.readByte() == ')") { // done
if (parseDebug)
System.out.println("DEBUG IMAP: parse DONE");
return;
}
// Else, we have extension data
if (parseDebug)
System.out.println("DEBUG IMAP: parsing extension data");
// Body parameters
cParams = parseParameters(r);
if (r.readByte() == ')") { // done
if (parseDebug)
System.out.println("DEBUG IMAP: body parameters DONE");
return;
}
// Disposition
byte b = r.readByte();
if (b == '(") {
if (parseDebug)
System.out.println("DEBUG IMAP: parse disposition");
disposition = r.readString();
if (parseDebug)
System.out.println("DEBUG IMAP: disposition " +
disposition);
dParams = parseParameters(r);
if (r.readByte() != ')") // eat the end ')'
throw new ParsingException(
"BODYSTRUCTURE parse error: " +
"missing ``)'' at end of disposition in multipart");
if (parseDebug)
System.out.println("DEBUG IMAP: disposition DONE");
} else if (b == 'N" || b == 'n") {
if (parseDebug)
System.out.println("DEBUG IMAP: disposition NIL");
r.skip(2); // skip 'NIL'
} else {
throw new ParsingException(
"BODYSTRUCTURE parse error: " +
type + "/" + subtype + ": " +
"bad multipart disposition, b " + b);
}
// RFC3501 allows no body-fld-lang after body-fld-disp,
// even though RFC2060 required it
if ((b = r.readByte()) == ')") {
if (parseDebug)
System.out.println("DEBUG IMAP: no body-fld-lang");
return; // done
}
if (b != ' ")
throw new ParsingException(
"BODYSTRUCTURE parse error: " +
"missing space after disposition");
// Language
if (r.peekByte() == '(") { // a list follows
language = r.readStringList();
if (parseDebug)
System.out.println(
"DEBUG IMAP: language len " + language.length);
} else {
String l = r.readString();
if (l != null) {
String[] la = { l };
language = la;
if (parseDebug)
System.out.println("DEBUG IMAP: language " + l);
}
}
// RFC3501 defines an optional "body location" next,
// but for now we ignore it along with other extensions.
// Throw away any further extension data
while (r.readByte() == ' ")
parseBodyExtension(r);
}
else { // Single part
if (parseDebug)
System.out.println("DEBUG IMAP: single part");
type = r.readString();
if (parseDebug)
System.out.println("DEBUG IMAP: type " + type);
processedType = SINGLE;
subtype = r.readString();
if (parseDebug)
System.out.println("DEBUG IMAP: subtype " + subtype);
// SIMS 4.0 returns NIL for a Content-Type of "binary", fix it here
if (type == null) {
type = "application";
subtype = "octet-stream";
}
cParams = parseParameters(r);
if (parseDebug)
System.out.println("DEBUG IMAP: cParams " + cParams);
id = r.readString();
if (parseDebug)
System.out.println("DEBUG IMAP: id " + id);
description = r.readString();
if (parseDebug)
System.out.println("DEBUG IMAP: description " + description);
encoding = r.readString();
if (parseDebug)
System.out.println("DEBUG IMAP: encoding " + encoding);
size = r.readNumber();
if (parseDebug)
System.out.println("DEBUG IMAP: size " + size);
if (size < 0)
throw new ParsingException(
"BODYSTRUCTURE parse error: bad ``size'' element");
// "text/*" & "message/rfc822" types have additional data ..
if (type.equalsIgnoreCase("text")) {
lines = r.readNumber();
if (parseDebug)
System.out.println("DEBUG IMAP: lines " + lines);
if (lines < 0)
throw new ParsingException(
"BODYSTRUCTURE parse error: bad ``lines'' element");
} else if (type.equalsIgnoreCase("message") &&
subtype.equalsIgnoreCase("rfc822")) {
// Nested message
processedType = NESTED;
envelope = new ENVELOPE(r);
BODYSTRUCTURE[] bs = { new BODYSTRUCTURE(r) };
bodies = bs;
lines = r.readNumber();
if (parseDebug)
System.out.println("DEBUG IMAP: lines " + lines);
if (lines < 0)
throw new ParsingException(
"BODYSTRUCTURE parse error: bad ``lines'' element");
} else {
// Detect common error of including lines element on other types
r.skipSpaces();
byte bn = r.peekByte();
if (Character.isDigit((char)bn)) // number
throw new ParsingException(
"BODYSTRUCTURE parse error: server erroneously " +
"included ``lines'' element with type " +
type + "/" + subtype);
}
if (r.peekByte() == ')") {
r.readByte();
if (parseDebug)
System.out.println("DEBUG IMAP: parse DONE");
return; // done
}
// Optional extension data
// MD5
md5 = r.readString();
if (r.readByte() == ')") {
if (parseDebug)
System.out.println("DEBUG IMAP: no MD5 DONE");
return; // done
}
// Disposition
byte b = r.readByte();
if (b == '(") {
disposition = r.readString();
if (parseDebug)
System.out.println("DEBUG IMAP: disposition " +
disposition);
dParams = parseParameters(r);
if (parseDebug)
System.out.println("DEBUG IMAP: dParams " + dParams);
if (r.readByte() != ')") // eat the end ')'
throw new ParsingException(
"BODYSTRUCTURE parse error: " +
"missing ``)'' at end of disposition");
} else if (b == 'N" || b == 'n") {
if (parseDebug)
System.out.println("DEBUG IMAP: disposition NIL");
r.skip(2); // skip 'NIL'
} else {
throw new ParsingException(
"BODYSTRUCTURE parse error: " +
type + "/" + subtype + ": " +
"bad single part disposition, b " + b);
}
if (r.readByte() == ')") {
if (parseDebug)
System.out.println("DEBUG IMAP: disposition DONE");
return; // done
}
// Language
if (r.peekByte() == '(") { // a list follows
language = r.readStringList();
if (parseDebug)
System.out.println("DEBUG IMAP: language len " +
language.length);
} else { // protocol is unnessarily complex here
String l = r.readString();
if (l != null) {
String[] la = { l };
language = la;
if (parseDebug)
System.out.println("DEBUG IMAP: language " + l);
}
}
// RFC3501 defines an optional "body location" next,
// but for now we ignore it along with other extensions.
// Throw away any further extension data
while (r.readByte() == ' ")
parseBodyExtension(r);
if (parseDebug)
System.out.println("DEBUG IMAP: all DONE");
}