1 11 package org.eclipse.core.internal.content; 12 13 import java.io.IOException ; 14 import java.io.Reader ; 15 16 public class LazyReader extends Reader implements ILazySource { 17 private int blockCapacity; 18 char[][] blocks = {}; 19 private int bufferSize; 20 private Reader in; 21 private int mark; 22 private int offset; 23 24 public LazyReader(Reader in, int blockCapacity) { 25 this.in = in; 26 this.blockCapacity = blockCapacity; 27 } 28 29 public void close() { 30 } 32 33 private int computeBlockSize(int blockIndex) { 34 if (blockIndex < blocks.length - 1) 35 return blockCapacity; 36 int blockSize = bufferSize % blockCapacity; 37 return blockSize == 0 ? blockCapacity : blockSize; 38 } 39 40 private int copyFromBuffer(char[] userBuffer, int userOffset, int needed) { 41 int copied = 0; 42 int current = offset / blockCapacity; 43 while ((needed - copied) > 0 && current < blocks.length) { 44 int blockSize = computeBlockSize(current); 45 int offsetInBlock = offset % blockCapacity; 46 int availableInBlock = blockSize - offsetInBlock; 47 int toCopy = Math.min(availableInBlock, needed - copied); 48 System.arraycopy(blocks[current], offsetInBlock, userBuffer, userOffset + copied, toCopy); 49 copied += toCopy; 50 current++; 51 offset += toCopy; 52 } 53 return copied; 54 } 55 56 private void ensureAvailable(long charsToRead) throws IOException { 57 int loadedBlockSize = blockCapacity; 58 while (bufferSize < offset + charsToRead && loadedBlockSize == blockCapacity) { 59 try { 60 loadedBlockSize = loadBlock(); 61 } catch (IOException ioe) { 62 throw new LowLevelIOException(ioe); 63 } 64 bufferSize += loadedBlockSize; 65 } 66 } 67 68 protected int getBlockCount() { 70 return blocks.length; 71 } 72 73 protected int getBufferSize() { 75 return bufferSize; 76 } 77 78 protected int getMark() { 80 return mark; 81 } 82 83 protected int getOffset() { 85 return offset; 86 } 87 88 public boolean isText() { 89 return true; 90 } 91 92 private int loadBlock() throws IOException { 93 char[] newBlock = new char[blockCapacity]; 95 int readCount = in.read(newBlock); 96 if (readCount == -1) 97 return 0; 98 char[][] tmpBlocks = new char[blocks.length + 1][]; 100 System.arraycopy(blocks, 0, tmpBlocks, 0, blocks.length); 101 blocks = tmpBlocks; 102 blocks[blocks.length - 1] = newBlock; 103 return readCount; 104 } 105 106 public void mark(int readlimit) { 107 mark = offset; 108 } 109 110 public boolean markSupported() { 111 return true; 112 } 113 114 public int read() throws IOException { 115 ensureAvailable(1); 116 if (bufferSize <= offset) 117 return -1; 118 char nextChar = blocks[offset / blockCapacity][offset % blockCapacity]; 119 offset++; 120 return nextChar; 121 } 122 123 public int read(char[] c) throws IOException { 124 return read(c, 0, c.length); 125 } 126 127 public int read(char[] c, int off, int len) throws IOException { 128 ensureAvailable(len); 129 int copied = copyFromBuffer(c, off, len); 130 return copied == 0 ? -1 : copied; 131 } 132 133 public boolean ready() throws IOException { 134 try { 135 return (bufferSize - offset) > 0 || in.ready(); 136 } catch (IOException ioe) { 137 throw new LowLevelIOException(ioe); 138 } 139 } 140 141 public void reset() { 142 offset = mark; 143 } 144 145 public void rewind() { 146 mark = 0; 147 offset = 0; 148 } 149 150 public long skip(long toSkip) throws IOException { 151 if (toSkip <= 0) 152 return 0; 153 ensureAvailable(toSkip); 154 long skipped = Math.min(toSkip, bufferSize - offset); 155 offset += skipped; 156 return skipped; 157 } 158 } 159 | Popular Tags |