Coverage Report - palmed.edit.text.LineDelimiterInspector

Classes in this Package Line Coverage Branch Coverage Complexity
LineDelimiterInspector
70% 
86% 
1,643

 1  
 /**
 2  
  * Redistribution  and use  in source  and binary  forms, with  or without
 3  
  * modification, are permitted provided  that the following conditions are
 4  
  * met :
 5  
  *
 6  
  * . Redistributions  of  source  code  must  retain  the  above copyright
 7  
  *   notice, this list of conditions and the following disclaimer.
 8  
  *
 9  
  * . Redistributions in  binary form  must reproduce  the above  copyright
 10  
  *   notice, this list of conditions  and the following disclaimer in  the
 11  
  *   documentation and/or other materials provided with the distribution.
 12  
  *
 13  
  * . The name of the author may not be used to endorse or promote products
 14  
  *   derived from this software without specific prior written permission.
 15  
  *
 16  
  * THIS SOFTWARE IS  PROVIDED BY THE  AUTHOR ``AS IS''  AND ANY EXPRESS  OR
 17  
  * IMPLIED  WARRANTIES,  INCLUDING,  BUT   NOT  LIMITED  TO,  THE   IMPLIED
 18  
  * WARRANTIES OF MERCHANTABILITY AND  FITNESS FOR A PARTICULAR  PURPOSE ARE
 19  
  * DISCLAIMED.  IN NO  EVENT SHALL  THE AUTHOR  BE LIABLE  FOR ANY  DIRECT,
 20  
  * INDIRECT,  INCIDENTAL,  SPECIAL,  EXEMPLARY,  OR  CONSEQUENTIAL  DAMAGES
 21  
  * (INCLUDING,  BUT  NOT LIMITED  TO,  PROCUREMENT OF  SUBSTITUTE  GOODS OR
 22  
  * SERVICES;  LOSS  OF USE,  DATA,  OR PROFITS;  OR  BUSINESS INTERRUPTION)
 23  
  * HOWEVER CAUSED  AND ON  ANY THEORY  OF LIABILITY,  WHETHER IN  CONTRACT,
 24  
  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 25  
  * ANY  WAY  OUT OF  THE  USE OF  THIS  SOFTWARE, EVEN  IF  ADVISED OF  THE
 26  
  * POSSIBILITY OF SUCH DAMAGE.
 27  
  *
 28  
  * $Id$
 29  
  */
 30  
 
 31  
 package palmed.edit.text;
 32  
 
 33  
 import java.io.IOException;
 34  
 import java.io.InputStream;
 35  
 import java.io.OutputStream;
 36  
 
 37  
 /**
 38  
  * This class wraps an InputStream in order to detect the line delimiter type.
 39  
  *
 40  
  * @author Mathieu Champlon
 41  
  * @version $Revision$ $Date$
 42  
  */
 43  
 public final class LineDelimiterInspector extends InputStream
 44  
 {
 45  
     /**
 46  
      * The line feed delimiter.
 47  
      */
 48  
     private static final String LF = "\n";
 49  
     /**
 50  
      * The carriage return delimiter.
 51  
      */
 52  
     private static final String CR = "\r";
 53  
     /**
 54  
      * The carriage return/line feed delimiter.
 55  
      */
 56  
     private static final String CR_LF = "\r\n";
 57  
     /**
 58  
      * The wrapped stream.
 59  
      */
 60  
     private final InputStream stream_;
 61  
     /**
 62  
      * The delimiter.
 63  
      */
 64  
     private String delimiter_;
 65  
     /**
 66  
      * Whether the previous read byte was a carriage return or not.
 67  
      */
 68  
     private boolean wasCarriageReturn_;
 69  
     /**
 70  
      * Whether to skip the rest of the stream or not.
 71  
      */
 72  
     private boolean hasLineDelimiterBeenFound_;
 73  
 
 74  
     /**
 75  
      * Create a line delimiter inspector.
 76  
      *
 77  
      * @param stream the stream to wrap
 78  
      */
 79  
     public LineDelimiterInspector( final InputStream stream )
 80  315
     {
 81  315
         if( stream == null )
 82  5
             throw new IllegalArgumentException( "parameter 'stream' is null" );
 83  310
         stream_ = stream;
 84  310
         delimiter_ = CR_LF;
 85  310
         wasCarriageReturn_ = false;
 86  310
         hasLineDelimiterBeenFound_ = false;
 87  310
     }
 88  
 
 89  
     /**
 90  
      * Create a default line delimiter.
 91  
      */
 92  
     public LineDelimiterInspector()
 93  540
     {
 94  540
         stream_ = null;
 95  540
         delimiter_ = CR_LF;
 96  540
     }
 97  
 
 98  
     /**
 99  
      * {@inheritDoc}
 100  
      */
 101  
     public int read() throws IOException
 102  
     {
 103  0
         final int b = stream_.read();
 104  0
         if( hasLineDelimiterBeenFound_ )
 105  0
             return b;
 106  0
         return inspect( b );
 107  
     }
 108  
 
 109  
     /**
 110  
      * {@inheritDoc}
 111  
      */
 112  
     public int read( final byte[] b ) throws IOException
 113  
     {
 114  575
         return read( b, 0, b.length );
 115  
     }
 116  
 
 117  
     /**
 118  
      * {@inheritDoc}
 119  
      */
 120  
     public int read( final byte[] b, final int off, final int len ) throws IOException
 121  
     {
 122  595
         final int size = stream_.read( b, off, len );
 123  4075
         for( int i = off; i < size && !hasLineDelimiterBeenFound_; ++i )
 124  3480
             inspect( b[i] );
 125  595
         return size;
 126  
     }
 127  
 
 128  
     private int inspect( final int b )
 129  
     {
 130  3480
         if( b == '\r' )
 131  
         {
 132  30
             delimiter_ = CR;
 133  30
             wasCarriageReturn_ = true;
 134  30
         }
 135  
         else
 136  
         {
 137  3450
             if( b == '\n' )
 138  
             {
 139  120
                 if( wasCarriageReturn_ )
 140  15
                     delimiter_ = CR_LF;
 141  
                 else
 142  105
                     delimiter_ = LF;
 143  120
                 hasLineDelimiterBeenFound_ = true;
 144  120
             }
 145  3330
             else if( wasCarriageReturn_ )
 146  10
                 hasLineDelimiterBeenFound_ = true;
 147  
         }
 148  3480
         return b;
 149  
     }
 150  
 
 151  
     /**
 152  
      * Write the delimiter to an output stream.
 153  
      *
 154  
      * @param stream the stream to write into
 155  
      * @throws IOException an io exception occurs
 156  
      */
 157  
     public void write( final OutputStream stream ) throws IOException
 158  
     {
 159  190
         stream.write( delimiter_.getBytes() );
 160  190
     }
 161  
 
 162  
     /**
 163  
      * {@inheritDoc}
 164  
      */
 165  
     public int available() throws IOException
 166  
     {
 167  0
         return stream_.available();
 168  
     }
 169  
 
 170  
     /**
 171  
      * {@inheritDoc}
 172  
      */
 173  
     public void close() throws IOException
 174  
     {
 175  0
         stream_.close();
 176  0
     }
 177  
 
 178  
     /**
 179  
      * {@inheritDoc}
 180  
      */
 181  
     public void mark( final int readlimit )
 182  
     {
 183  0
         stream_.mark( readlimit );
 184  0
     }
 185  
 
 186  
     /**
 187  
      * {@inheritDoc}
 188  
      */
 189  
     public boolean markSupported()
 190  
     {
 191  0
         return stream_.markSupported();
 192  
     }
 193  
 
 194  
     /**
 195  
      * {@inheritDoc}
 196  
      */
 197  
     public void reset() throws IOException
 198  
     {
 199  0
         stream_.reset();
 200  0
     }
 201  
 
 202  
     /**
 203  
      * {@inheritDoc}
 204  
      */
 205  
     public long skip( final long n ) throws IOException
 206  
     {
 207  0
         return stream_.skip( n );
 208  
     }
 209  
 
 210  
     /**
 211  
      * {@inheritDoc}
 212  
      */
 213  
     public String toString()
 214  
     {
 215  0
         return delimiter_;
 216  
     }
 217  
 }