1 57 58 package org.enhydra.apache.xerces.readers; 59 60 import java.io.Reader ; 61 62 import org.enhydra.apache.xerces.framework.XMLErrorReporter; 63 import org.enhydra.apache.xerces.utils.CharDataChunk; 64 import org.enhydra.apache.xerces.utils.StringPool; 65 66 79 final class CharReader extends AbstractCharReader { 80 CharReader(XMLEntityHandler entityHandler, XMLErrorReporter errorReporter, boolean sendCharDataAsCharArray, Reader reader, StringPool stringPool) throws Exception { 84 super(entityHandler, errorReporter, sendCharDataAsCharArray, stringPool); 85 fCharacterStream = reader; 86 fillCurrentChunk(); 87 } 88 private Reader fCharacterStream = null; 92 private boolean fCheckOverflow = false; 99 private char[] fOverflow = null; 100 private int fOverflowOffset = 0; 101 private int fOverflowEnd = 0; 102 private int fOutputOffset = 0; 103 private boolean fSkipLinefeed = false; 104 protected int fillCurrentChunk() throws Exception { 108 char[] recycledData = fCurrentChunk.toCharArray(); 113 fOutputOffset = 0; 118 if (fCheckOverflow) { 119 fMostRecentData = recycledData; 125 if (fOverflowEnd < CharDataChunk.CHUNK_SIZE) { 126 recycledData = null; 127 if (fOverflowEnd > 0) { 128 if (fMostRecentData == null || fMostRecentData.length < 1 + fOverflowEnd - fOverflowOffset) 129 fMostRecentData = new char[1 + fOverflowEnd - fOverflowOffset]; 130 copyNormalize(fOverflow, fOverflowOffset, fMostRecentData, fOutputOffset); 131 } else { 132 if (fMostRecentData == null) 133 fMostRecentData = new char[1]; 134 } 135 fMostRecentData[fOutputOffset] = 0; 136 fOverflow = null; 140 fLength += fOutputOffset; 141 fCurrentIndex = 0; 142 fCurrentChunk.setCharArray(fMostRecentData); 143 return (fMostRecentChar = fMostRecentData[0]); 144 } 145 if (fMostRecentData == null || fMostRecentData.length < CharDataChunk.CHUNK_SIZE) 146 fMostRecentData = new char[CharDataChunk.CHUNK_SIZE]; 147 else 148 recycledData = null; 149 copyNormalize(fOverflow, fOverflowOffset, fMostRecentData, fOutputOffset); 150 fCheckOverflow = false; 151 } else { 152 if (fOverflow == null) { 153 fOverflow = recycledData; 154 if (fOverflow == null || fOverflow.length < CharDataChunk.CHUNK_SIZE) 155 fOverflow = new char[CharDataChunk.CHUNK_SIZE]; 156 else 157 recycledData = null; 158 } 159 fMostRecentData = null; 160 } 161 while (true) { 162 fOverflowOffset = 0; 163 fOverflowEnd = 0; 164 int capacity = CharDataChunk.CHUNK_SIZE; 165 int result = 0; 166 do { 167 try { 168 result = fCharacterStream.read(fOverflow, fOverflowEnd, capacity); 169 } catch (java.io.IOException ex) { 170 result = -1; 171 } 172 if (result == -1) { 173 fCharacterStream.close(); 177 fCharacterStream = null; 178 if (fMostRecentData == null) { 179 fMostRecentData = recycledData; 184 if (fMostRecentData == null || fMostRecentData.length < 1 + fOverflowEnd) 185 fMostRecentData = new char[1 + fOverflowEnd]; 186 else 187 recycledData = null; 188 copyNormalize(fOverflow, fOverflowOffset, fMostRecentData, fOutputOffset); 189 fOverflow = null; 190 fMostRecentData[fOutputOffset] = 0; 191 } else { 192 boolean alldone = copyNormalize(fOverflow, fOverflowOffset, fMostRecentData, fOutputOffset); 196 if (alldone) { 197 if (fOutputOffset == CharDataChunk.CHUNK_SIZE) { 198 fCheckOverflow = true; 206 fOverflowOffset = 0; 207 fOverflowEnd = 0; 208 } else { 209 fOverflow = null; 213 fMostRecentData[fOutputOffset] = 0; 214 } 215 } else { 216 fCheckOverflow = true; 221 } 222 } 223 break; 224 } 225 if (result > 0) { 226 fOverflowEnd += result; 227 capacity -= result; 228 } 229 } while (capacity > 0); 230 if (result == -1) 234 break; 235 if (fMostRecentData != null) { 236 boolean alldone = copyNormalize(fOverflow, fOverflowOffset, fMostRecentData, fOutputOffset); 237 if (fOutputOffset == CharDataChunk.CHUNK_SIZE) { 238 if (!alldone) { 242 fCheckOverflow = true; 246 } 247 break; 248 } 249 } else { 250 fMostRecentData = recycledData; 255 if (fMostRecentData == null || fMostRecentData.length < CharDataChunk.CHUNK_SIZE) 256 fMostRecentData = new char[CharDataChunk.CHUNK_SIZE]; 257 else 258 recycledData = null; 259 copyNormalize(fOverflow, fOverflowOffset, fMostRecentData, fOutputOffset); 260 if (fOutputOffset == CharDataChunk.CHUNK_SIZE) { 261 break; 265 } 266 } 267 } 272 fLength += fOutputOffset; 276 fCurrentIndex = 0; 277 fCurrentChunk.setCharArray(fMostRecentData); 278 return (fMostRecentChar = fMostRecentData[0]); 279 } 280 private boolean copyNormalize(char[] in, int inOffset, char[] out, int outOffset) throws Exception { 284 int inEnd = fOverflowEnd; 288 int outEnd = out.length; 289 if (inOffset == inEnd) 290 return true; 291 char b = in[inOffset]; 292 if (fSkipLinefeed) { 293 fSkipLinefeed = false; 294 if (b == 0x0A) { 295 if (++inOffset == inEnd) 296 return exitNormalize(inOffset, outOffset, true); 297 b = in[inOffset]; 298 } 299 } 300 while (outOffset < outEnd) { 301 int inCount = inEnd - inOffset; 306 int outCount = outEnd - outOffset; 307 if (inCount > outCount) 308 inCount = outCount; 309 inOffset++; 310 while (true) { 311 while (b == 0x0D) { 312 out[outOffset++] = 0x0A; 313 if (inOffset == inEnd) { 314 fSkipLinefeed = true; 315 return exitNormalize(inOffset, outOffset, true); 316 } 317 b = in[inOffset]; 318 if (b == 0x0A) { 319 if (++inOffset == inEnd) 320 return exitNormalize(inOffset, outOffset, true); 321 b = in[inOffset]; 322 } 323 if (outOffset == outEnd) 324 return exitNormalize(inOffset, outOffset, false); 325 inCount = inEnd - inOffset; 326 outCount = outEnd - outOffset; 327 if (inCount > outCount) 328 inCount = outCount; 329 inOffset++; 330 } 331 while (true) { 332 out[outOffset++] = b; 333 if (--inCount == 0) 334 break; 335 b = in[inOffset++]; 336 if (b == 0x0D) 337 break; 338 } 339 if (inCount == 0) 340 break; 341 } 342 if (inOffset == inEnd) 343 break; 344 } 345 return exitNormalize(inOffset, outOffset, inOffset == inEnd); 346 } 347 private boolean exitNormalize(int inOffset, int outOffset, boolean result) { 351 fOverflowOffset = inOffset; 352 fOutputOffset = outOffset; 353 return result; 354 } 355 } 356 | Popular Tags |