1 /* 2 * reserved comment block 3 * DO NOT REMOVE OR ALTER! 4 */ 5 /* 6 * Copyright 1999-2004 The Apache Software Foundation. 7 * 8 * Licensed under the Apache License, Version 2.0 (the "License"); 9 * you may not use this file except in compliance with the License. 10 * You may obtain a copy of the License at 11 * 12 * http://www.apache.org/licenses/LICENSE-2.0 13 * 14 * Unless required by applicable law or agreed to in writing, software 15 * distributed under the License is distributed on an "AS IS" BASIS, 16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 * See the License for the specific language governing permissions and 18 * limitations under the License. 19 */ 20 21 package com.sun.org.apache.regexp.internal; 22 23 import java.io.InputStream; 24 import java.io.IOException; 25 26 /** 27 * Encapsulates java.io.InputStream as CharacterIterator. 28 * 29 * @author <a href="mailto:ales.novak@netbeans.com">Ales Novak</a> 30 */ 31 public final class StreamCharacterIterator implements CharacterIterator 32 { 33 /** Underlying is */ 34 private final InputStream is; 35 36 /** Buffer of read chars */ 37 private final StringBuffer buff; 38 39 /** read end? */ 40 private boolean closed; 41 42 /** @param is an InputStream, which is parsed */ 43 public StreamCharacterIterator(InputStream is) 44 { 45 this.is = is; 46 this.buff = new StringBuffer(512); 47 this.closed = false; 48 } 49 50 /** @return a substring */ 51 public String substring(int beginIndex, int endIndex) 52 { 53 try 54 { 55 ensure(endIndex); 56 return buff.toString().substring(beginIndex, endIndex); 57 } 58 catch (IOException e) 59 { 60 throw new StringIndexOutOfBoundsException(e.getMessage()); 61 } 62 } 63 64 /** @return a substring */ 65 public String substring(int beginIndex) 66 { 67 try 68 { 69 readAll(); 70 return buff.toString().substring(beginIndex); 71 } 72 catch (IOException e) 73 { 74 throw new StringIndexOutOfBoundsException(e.getMessage()); 75 } 76 } 77 78 79 /** @return a character at the specified position. */ 80 public char charAt(int pos) 81 { 82 try 83 { 84 ensure(pos); 85 return buff.charAt(pos); 86 } 87 catch (IOException e) 88 { 89 throw new StringIndexOutOfBoundsException(e.getMessage()); 90 } 91 } 92 93 /** @return <tt>true</tt> iff if the specified index is after the end of the character stream */ 94 public boolean isEnd(int pos) 95 { 96 if (buff.length() > pos) 97 { 98 return false; 99 } 100 else 101 { 102 try 103 { 104 ensure(pos); 105 return (buff.length() <= pos); 106 } 107 catch (IOException e) 108 { 109 throw new StringIndexOutOfBoundsException(e.getMessage()); 110 } 111 } 112 } 113 114 /** Reads n characters from the stream and appends them to the buffer */ 115 private int read(int n) throws IOException 116 { 117 if (closed) 118 { 119 return 0; 120 } 121 122 int c; 123 int i = n; 124 while (--i >= 0) 125 { 126 c = is.read(); 127 if (c < 0) // EOF 128 { 129 closed = true; 130 break; 131 } 132 buff.append((char) c); 133 } 134 return n - i; 135 } 136 137 /** Reads rest of the stream. */ 138 private void readAll() throws IOException 139 { 140 while(! closed) 141 { 142 read(1000); 143 } 144 } 145 146 /** Reads chars up to the idx */ 147 private void ensure(int idx) throws IOException 148 { 149 if (closed) 150 { 151 return; 152 } 153 154 if (idx < buff.length()) 155 { 156 return; 157 } 158 159 read(idx + 1 - buff.length()); 160 } 161 }