blob: 58a99b561bdb2466bdfc6e5e89be0aa80afbaa2a [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2011 Tasktop Technologies.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Tasktop Technologies - initial API and implementation
*******************************************************************************/
package org.eclipse.mylyn.internal.sandbox.search.ui.provider;
import java.io.IOException;
import java.io.Reader;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.OperationCanceledException;
/**
* A CharSequence that is based on a reader, providing a specified number of characters. If the reader cannot provide
* enough character data, the sequence is padded with whitespace.
*
* @author David Green
*/
class ReaderCharSequence implements CharSequence {
private final int length;
private Reader reader;
private final StringBuilder buffer;
private final IProgressMonitor monitor;
public ReaderCharSequence(int length, Reader reader, IProgressMonitor monitor) {
this.length = length;
this.reader = reader;
this.monitor = monitor;
buffer = new StringBuilder(length > 1024 ? 1024 : length);
}
public int length() {
return length;
}
public char charAt(int index) {
if (index >= length || index < 0) {
throw new IndexOutOfBoundsException();
}
if (index >= buffer.length()) {
fill(index);
}
if (index >= buffer.length()) {
return ' ';
}
return buffer.charAt(index);
}
private void fill(int maxIndex) {
if (reader == null) {
return;
}
int c;
while (buffer.length() <= maxIndex) {
if (monitor.isCanceled()) {
throw new OperationCanceledException();
}
try {
c = reader.read();
if (c == -1) {
reader = null;
break;
}
} catch (IOException e) {
reader = null;
break;
}
buffer.append((char) c);
}
}
public CharSequence subSequence(int start, int end) {
if (end > length || end < 0 || start < 0 || start > end) {
throw new IndexOutOfBoundsException();
}
if (end > buffer.length()) {
fill(end - 1);
}
if (end <= buffer.length()) {
return buffer.subSequence(start, end);
}
StringBuilder buf = new StringBuilder(end - start);
for (int x = start; x < end; ++x) {
buf.append(charAt(x));
}
return buf;
}
}