Home | History | Annotate | Download | only in mime4j
      1 /****************************************************************
      2  * Licensed to the Apache Software Foundation (ASF) under one   *
      3  * or more contributor license agreements.  See the NOTICE file *
      4  * distributed with this work for additional information        *
      5  * regarding copyright ownership.  The ASF licenses this file   *
      6  * to you under the Apache License, Version 2.0 (the            *
      7  * "License"); you may not use this file except in compliance   *
      8  * with the License.  You may obtain a copy of the License at   *
      9  *                                                              *
     10  *   http://www.apache.org/licenses/LICENSE-2.0                 *
     11  *                                                              *
     12  * Unless required by applicable law or agreed to in writing,   *
     13  * software distributed under the License is distributed on an  *
     14  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
     15  * KIND, either express or implied.  See the License for the    *
     16  * specific language governing permissions and limitations      *
     17  * under the License.                                           *
     18  ****************************************************************/
     19 
     20 package org.apache.james.mime4j;
     21 
     22 import java.io.IOException;
     23 import java.io.InputStream;
     24 
     25 /**
     26  * <code>InputStream</code> used by the parser to wrap the original user
     27  * supplied stream. This stream keeps track of the current line number and
     28  * can also be truncated. When truncated the stream will appear to have
     29  * reached end of file. This is used by the parser's
     30  * {@link org.apache.james.mime4j.MimeStreamParser#stop()} method.
     31  *
     32  *
     33  * @version $Id: RootInputStream.java,v 1.2 2004/10/02 12:41:10 ntherning Exp $
     34  */
     35 class RootInputStream extends InputStream {
     36     private InputStream is = null;
     37     private int lineNumber = 1;
     38     private int prev = -1;
     39     private boolean truncated = false;
     40 
     41     /**
     42      * Creates a new <code>RootInputStream</code>.
     43      *
     44      * @param in the stream to read from.
     45      */
     46     public RootInputStream(InputStream is) {
     47         this.is = is;
     48     }
     49 
     50     /**
     51      * Gets the current line number starting at 1
     52      * (the number of <code>\r\n</code> read so far plus 1).
     53      *
     54      * @return the current line number.
     55      */
     56     public int getLineNumber() {
     57         return lineNumber;
     58     }
     59 
     60     /**
     61      * Truncates this <code>InputStream</code>. After this call any
     62      * call to {@link #read()}, {@link #read(byte[]) or
     63      * {@link #read(byte[], int, int)} will return
     64      * -1 as if end-of-file had been reached.
     65      */
     66     public void truncate() {
     67         this.truncated = true;
     68     }
     69 
     70     /**
     71      * @see java.io.InputStream#read()
     72      */
     73     public int read() throws IOException {
     74         if (truncated) {
     75             return -1;
     76         }
     77 
     78         int b = is.read();
     79         if (prev == '\r' && b == '\n') {
     80             lineNumber++;
     81         }
     82         prev = b;
     83         return b;
     84     }
     85 
     86     /**
     87      *
     88      * @see java.io.InputStream#read(byte[], int, int)
     89      */
     90     public int read(byte[] b, int off, int len) throws IOException {
     91         if (truncated) {
     92             return -1;
     93         }
     94 
     95         int n = is.read(b, off, len);
     96         for (int i = off; i < off + n; i++) {
     97             if (prev == '\r' && b[i] == '\n') {
     98                 lineNumber++;
     99             }
    100             prev = b[i];
    101         }
    102         return n;
    103     }
    104 
    105     /**
    106      * @see java.io.InputStream#read(byte[])
    107      */
    108     public int read(byte[] b) throws IOException {
    109         return read(b, 0, b.length);
    110     }
    111 }