Coverage Report - org.apache.tapestry.util.text.ExtendedReader
 
Classes in this File Line Coverage Branch Coverage Complexity
ExtendedReader
0%
0/57
0%
0/26
2.545
 
 1  
 // Copyright 2004, 2005 The Apache Software Foundation
 2  
 //
 3  
 // Licensed under the Apache License, Version 2.0 (the "License");
 4  
 // you may not use this file except in compliance with the License.
 5  
 // You may obtain a copy of the License at
 6  
 //
 7  
 //     http://www.apache.org/licenses/LICENSE-2.0
 8  
 //
 9  
 // Unless required by applicable law or agreed to in writing, software
 10  
 // distributed under the License is distributed on an "AS IS" BASIS,
 11  
 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 12  
 // See the License for the specific language governing permissions and
 13  
 // limitations under the License.
 14  
 
 15  
 package org.apache.tapestry.util.text;
 16  
 
 17  
 import java.io.IOException;
 18  
 import java.io.Reader;
 19  
 
 20  
 /**
 21  
  * A Reader that provides some additional functionality, such as peek().
 22  
  * 
 23  
  * @author mb
 24  
  * @since 4.0
 25  
  */
 26  
 public class ExtendedReader extends Reader
 27  
 {
 28  
     private Reader _reader;
 29  0
     private boolean _hasBufferedChar = false;
 30  
     private char _bufferedChar;
 31  
     
 32  
     /**
 33  
      * Creates a new extended reader that reads from the provided object.
 34  
      * 
 35  
      * @param in the Reader to get data from
 36  
      */
 37  
     public ExtendedReader(Reader in)
 38  0
     {
 39  0
         _reader = in;
 40  0
     }
 41  
 
 42  
     /**
 43  
      * Returns the next character in the stream without actually comitting the read.
 44  
      * Multiple consequtive invocations of this method should return the same value.
 45  
      * 
 46  
      * @return the next character waiting in the stream or -1 if the end of the stream is reached
 47  
      * @throws IOException if an error occurs
 48  
      */
 49  
     public synchronized int peek() throws IOException
 50  
     {
 51  0
         if (!_hasBufferedChar) {
 52  0
             int bufferedChar = read();
 53  0
             if (bufferedChar < 0)
 54  0
                 return bufferedChar;
 55  0
             _bufferedChar = (char) bufferedChar;
 56  0
             _hasBufferedChar = true;
 57  
         }
 58  0
         return _bufferedChar;
 59  
     }
 60  
     
 61  
     /**
 62  
      * Determines whether the end of the stream is reached.
 63  
      * 
 64  
      * @return true if at the end of stream
 65  
      * @throws IOException if an error occurs
 66  
      */
 67  
     public synchronized boolean isEndOfStream() throws IOException
 68  
     {
 69  0
         return peek() < 0;
 70  
     }
 71  
 
 72  
     /**
 73  
      * Skips the next characters until a character that does not match the provided rule is reached.
 74  
      * 
 75  
      * @param matcher the object determining whether a character should be skipped
 76  
      * @throws IOException if an error occurs
 77  
      */
 78  
     public synchronized void skipCharacters(ICharacterMatcher matcher) throws IOException
 79  
     {
 80  
         while (true) {
 81  0
             if (isEndOfStream())
 82  0
                 break;
 83  0
             char ch = (char) peek();
 84  0
             if (!matcher.matches(ch))
 85  0
                 break;
 86  0
             read();
 87  0
         }
 88  0
     }
 89  
     
 90  
     /**
 91  
      * Reads the next characters until a character that does not match the provided rule is reached.
 92  
      * 
 93  
      * @param matcher the object determining whether a character should be read
 94  
      * @return the string of characters read
 95  
      * @throws IOException if an error occurs
 96  
      */
 97  
     public synchronized String readCharacters(ICharacterMatcher matcher) throws IOException
 98  
     {
 99  0
         StringBuffer buf = new StringBuffer();
 100  
         while (true) {
 101  0
             if (isEndOfStream())
 102  0
                 break;
 103  0
             char ch = (char) peek();
 104  0
             if (!matcher.matches(ch))
 105  0
                 break;
 106  0
             buf.append(read());
 107  0
         }
 108  0
         return buf.toString();
 109  
     }
 110  
     
 111  
     /** 
 112  
      * @see java.io.FilterReader#read(char[], int, int)
 113  
      */
 114  
     public synchronized int read(char[] cbuf, int off, int len) throws IOException
 115  
     {
 116  0
         int offset = off;
 117  0
         if (len <= 0)
 118  0
             return 0;
 119  0
         int readLength = len;
 120  
         
 121  0
         boolean extraChar = _hasBufferedChar;
 122  0
         if (_hasBufferedChar) {
 123  0
             _hasBufferedChar = false;
 124  0
             cbuf[offset++] = _bufferedChar;
 125  0
             readLength--;
 126  
         }
 127  
 
 128  0
         int read = _reader.read(cbuf, offset, readLength);
 129  0
         if (extraChar)
 130  0
             read++;
 131  0
         return read;
 132  
     }
 133  
     
 134  
     /** 
 135  
      * @see java.io.FilterReader#ready()
 136  
      */
 137  
     public synchronized boolean ready() throws IOException
 138  
     {
 139  0
         if (_hasBufferedChar)
 140  0
             return true;
 141  0
         return _reader.ready();
 142  
     }
 143  
     
 144  
     /** 
 145  
      * @see java.io.FilterReader#markSupported()
 146  
      */
 147  
     public synchronized boolean markSupported()
 148  
     {
 149  0
         return false;
 150  
     }
 151  
     
 152  
     /** 
 153  
      * @see java.io.FilterReader#reset()
 154  
      */
 155  
     public synchronized void reset() throws IOException
 156  
     {
 157  0
         _hasBufferedChar = false;
 158  0
         _reader.reset();
 159  0
     }
 160  
     
 161  
     /** 
 162  
      * @see java.io.FilterReader#skip(long)
 163  
      */
 164  
     public synchronized long skip(long n) throws IOException
 165  
     {
 166  0
         long skipChars = n;
 167  0
         if (_hasBufferedChar && skipChars > 0) {
 168  0
             _hasBufferedChar = false;
 169  0
             skipChars--;
 170  
         }
 171  0
         return _reader.skip(skipChars);
 172  
     }
 173  
 
 174  
     /** 
 175  
      * @see java.io.Reader#close()
 176  
      */
 177  
     public synchronized void close() throws IOException
 178  
     {
 179  0
         _hasBufferedChar = false;
 180  0
         _reader.close();
 181  0
     }
 182  
     
 183  
 }