Skip to content

Instantly share code, notes, and snippets.

@basilevs
Created April 23, 2025 12:37
Show Gist options
  • Save basilevs/377246f2c66c70afab459ee07d5be039 to your computer and use it in GitHub Desktop.
Save basilevs/377246f2c66c70afab459ee07d5be039 to your computer and use it in GitHub Desktop.
Untested java.io.Reader decorator that filters out a set of characters
/*******************************************************************************
* Copyright (c) 2025 Xored Software Inc and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-v20.html
*
* Contributors:
* Xored Software Inc - initial API and implementation and/or initial documentation
*******************************************************************************/
package org.eclipse.rcptt.core.persistence.plain;
import java.io.FilterReader;
import java.io.IOException;
import java.io.Reader;
import java.nio.CharBuffer;
import java.util.Objects;
public class CharacterSkippingReader extends FilterReader {
private final CharBuffer buffer = CharBuffer.allocate(2048);
private String charsToRemove;
public CharacterSkippingReader(Reader in, String charsToRemove) {
super(in);
this.charsToRemove = Objects.requireNonNull(charsToRemove);
}
@Override
public int read(char[] cbuf, int off, int len) throws IOException {
int toRead = Math.min(buffer.remaining(), len);
buffer.get(cbuf, off, toRead);
if (toRead > 0) {
return toRead;
}
int result = readUpstream();
if (result <= 0) {
return result;
}
toRead = Math.min(buffer.remaining(), len);
buffer.get(cbuf, off, toRead);
return toRead;
}
@Override
public int read(CharBuffer target) throws IOException {
int result = buffer.read(target);
if (result > 0) {
return result;
}
result = readUpstream();
if (result <= 0) {
return result;
}
return buffer.read(target);
}
@Override
public void reset() throws IOException {
super.reset();
buffer.clear();
}
private int readUpstream() throws IOException {
buffer.compact();
try {
int startPosition = buffer.position();
while (buffer.position() == startPosition) {
int result = in.read(buffer);
assert buffer.position() >= startPosition;
if (result <= 0) {
return result;
}
removeChars(buffer, charsToRemove);
assert buffer.position() >= startPosition;
}
return buffer.position() - startPosition;
} finally {
buffer.flip();
}
}
private static void removeChars(CharBuffer inout, String charsToRemove) {
int readCursor = 0, writeCursor = 0;
for (;;) {
assert readCursor >= writeCursor;
if (readCursor >= inout.position()) {
break;
}
char c = inout.get(readCursor++);
if (charsToRemove.indexOf(c) >= 0) {
continue;
}
inout.put(writeCursor++, c);
}
inout.position(writeCursor);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment