1 21 22 package org.apache.derbyTesting.functionTests.util.streams; 23 24 import java.io.IOException ; 25 import java.io.Reader ; 26 27 30 public class LoopingAlphabetReader 31 extends Reader { 32 33 37 private static final int MAX_BUF_SIZE = 32*1024; 38 39 private static final int SPACE = ' '; 40 41 42 private final long length; 43 44 private final int trailingBlanks; 45 46 private long remainingNonBlanks; 47 48 private long remainingBlanks; 49 53 private char[] buffer = new char[0]; 54 55 private final CharAlphabet alphabet; 56 57 private boolean closed = false; 58 59 64 public LoopingAlphabetReader(long length) { 65 this(length, 0); 66 } 67 68 78 public LoopingAlphabetReader(long length, int trailingBlanks) { 79 this.length = length; 80 this.trailingBlanks = trailingBlanks; 81 this.remainingNonBlanks = length - trailingBlanks; 82 this.remainingBlanks = trailingBlanks; 83 this.alphabet = CharAlphabet.modernLatinLowercase(); 84 fillBuffer(alphabet.charCount()); 85 } 86 87 93 public LoopingAlphabetReader(long length, CharAlphabet alphabet) { 94 this(length, alphabet, 0); 95 } 96 97 108 public LoopingAlphabetReader(long length, 109 CharAlphabet alphabet, 110 int trailingBlanks) { 111 this.length = length; 112 this.trailingBlanks = trailingBlanks; 113 this.remainingNonBlanks = length - trailingBlanks; 114 this.remainingBlanks = trailingBlanks; 115 this.alphabet = alphabet; 116 fillBuffer(alphabet.charCount()); 117 } 118 119 public int read() 120 throws IOException { 121 ensureOpen(); 122 if (remainingBlanks <= 0 && remainingNonBlanks <= 0) { 123 return -1; 124 } 125 if (remainingNonBlanks <= 0) { 126 remainingBlanks--; 127 return SPACE; 128 } 129 remainingNonBlanks--; 130 return alphabet.nextCharAsInt(); 131 } 132 133 public int read(char[] buf, int off, int length) 134 throws IOException { 135 ensureOpen(); 136 if (remainingBlanks <= 0 && remainingNonBlanks <= 0) { 137 return -1; 138 } 139 int nonBlankLength = Math.min((int)remainingNonBlanks, length); 141 fillBuffer(nonBlankLength); 142 int read = 0; 143 int cOff = alphabet.nextCharToRead(0); 145 if (nonBlankLength <= (buffer.length - cOff)) { 146 System.arraycopy(buffer, cOff, buf, off, nonBlankLength); 147 remainingNonBlanks -= nonBlankLength; 148 read = nonBlankLength; 149 alphabet.nextCharToRead(nonBlankLength); 150 } else { 151 int toRead = 0; 153 while (remainingNonBlanks > 0 && read < nonBlankLength) { 154 cOff = alphabet.nextCharToRead(toRead); 155 toRead = Math.min(buffer.length - cOff, nonBlankLength - read); 156 System.arraycopy(buffer, cOff, buf, off + read, toRead); 157 remainingNonBlanks -= toRead; 158 read += toRead; 159 } 160 cOff = alphabet.nextCharToRead(toRead); 161 } 162 if (read < length && remainingBlanks > 0) { 163 read += fillBlanks(buf, off + read, length - read); 164 } 165 return read; 166 } 167 168 171 public void reset() 172 throws IOException { 173 ensureOpen(); 174 remainingNonBlanks = length - trailingBlanks; 175 remainingBlanks = trailingBlanks; 176 alphabet.reset(); 177 } 178 179 182 public int available() { 183 return (int)(remainingNonBlanks + remainingBlanks); 184 } 185 186 189 public void close() { 190 this.closed = true; 191 } 192 193 198 private void fillBuffer(int bufSize) { 199 if (bufSize > MAX_BUF_SIZE) { 200 bufSize = MAX_BUF_SIZE; 201 } 202 if (bufSize <= buffer.length) { 203 return; 204 } 205 int curOff = alphabet.nextCharToRead(0); 206 alphabet.reset(); 208 buffer = new char[bufSize]; 209 for (int i=0; i < bufSize; i++) { 210 buffer[i] = alphabet.nextChar(); 211 } 212 alphabet.reset(); 215 alphabet.nextCharToRead(curOff); 216 } 217 218 225 private int fillBlanks(char[] buf, int off, int length) { 226 int i=0; 227 for (; i < length; i++) { 228 if (remainingBlanks > 0) { 229 buf[off+i] = SPACE; 230 remainingBlanks--; 231 } else { 232 break; 233 } 234 } 235 return i; 236 } 237 238 243 private final void ensureOpen() 244 throws IOException { 245 if (closed) { 246 throw new IOException ("Reader closed"); 247 } 248 } 249 } | Popular Tags |