FileDocCategorySizeDatePackage
MimeBoundaryInputStream.javaAPI DocAndroid 1.5 API5713Wed May 06 22:42:46 BST 2009org.apache.james.mime4j

MimeBoundaryInputStream

public class MimeBoundaryInputStream extends InputStream
Stream that constrains itself to a single MIME body part. After the stream ends (i.e. read() returns -1) {@link #hasMoreParts()} can be used to determine if a final boundary has been seen or not. If {@link #parentEOF()} is true an unexpected end of stream has been detected in the parent stream.
version
$Id: MimeBoundaryInputStream.java,v 1.2 2004/11/29 13:15:42 ntherning Exp $

Fields Summary
private PushbackInputStream
s
private byte[]
boundary
private boolean
first
private boolean
eof
private boolean
parenteof
private boolean
moreParts
Constructors Summary
public MimeBoundaryInputStream(InputStream s, String boundary)
Creates a new MimeBoundaryInputStream.

param
s The underlying stream.
param
boundary Boundary string (not including leading hyphens).


                          
         
              
        
        this.s = new PushbackInputStream(s, boundary.length() + 4);

        boundary = "--" + boundary;
        this.boundary = new byte[boundary.length()];
        for (int i = 0; i < this.boundary.length; i++) {
            this.boundary[i] = (byte) boundary.charAt(i);
        }
        
        /*
         * By reading one byte we will update moreParts to be as expected
         * before any bytes have been read.
         */
        int b = read();
        if (b != -1) {
            this.s.unread(b);
        }
    
Methods Summary
public voidclose()
Closes the underlying stream.

throws
IOException on I/O errors.

        s.close();
    
public voidconsume()
Consumes all unread bytes of this stream. After a call to this method this stream will have reached EOF.

throws
IOException on I/O errors.

        while (read() != -1) {
        }
    
public booleanhasMoreParts()
Determines if the underlying stream has more parts (this stream has not seen an end boundary).

return
true if there are more parts in the underlying stream, false otherwise.

        return moreParts;
    
private booleanmatchBoundary()

        
        for (int i = 0; i < boundary.length; i++) {
            int b = s.read();
            if (b != boundary[i]) {
                if (b != -1) {
                    s.unread(b);
                }
                for (int j = i - 1; j >= 0; j--) {
                    s.unread(boundary[j]);
                }
                return false;
            }
        }
        
        /*
         * We have a match. Is it an end boundary?
         */
        int prev = s.read();
        int curr = s.read();
        moreParts = !(prev == '-" && curr == '-");
        do {
            if (curr == '\n" && prev == '\r") {
                break;
            }
            prev = curr;
        } while ((curr = s.read()) != -1);
        
        if (curr == -1) {
            moreParts = false;
            parenteof = true;
        }
        
        eof = true;
        
        return true;
    
public booleanparentEOF()
Determines if the parent stream has reached EOF

return
true if EOF has been reached for the parent stream, false otherwise.

        return parenteof;
    
public intread()

see
java.io.InputStream#read()

        if (eof) {
            return -1;
        }
        
        if (first) {
            first = false;
            if (matchBoundary()) {
                return -1;
            }
        }
        
        int b1 = s.read();
        int b2 = s.read();
        
        if (b1 == '\r" && b2 == '\n") {
            if (matchBoundary()) {
                return -1;
            }
        }
        
        if (b2 != -1) {
            s.unread(b2);
        }

        parenteof = b1 == -1;
        eof = parenteof;
        
        return b1;