This is an automated email from the ASF dual-hosted git repository. ggregory pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/commons-io.git
The following commit(s) were added to refs/heads/master by this push: new 8a681ea Variation of PR #227 from Rob Spoor (robtimus) but does not add a new class. 8a681ea is described below commit 8a681ea4bc91b3f58e44042d4e6eb23d996e0d76 Author: Gary Gregory <gardgreg...@gmail.com> AuthorDate: Wed May 12 14:22:05 2021 -0400 Variation of PR #227 from Rob Spoor (robtimus) but does not add a new class. - Add AbstractCharacterFilterReader(Reader, IntPredicate). - Add CharacterFilterReader(Reader, IntPredicate). - Add AbstractCharacterFilterReader(Reader, IntPredicate). - Add CharacterFilterReaderIntPredicateTest. --- .../io/input/AbstractCharacterFilterReader.java | 35 ++++-- .../commons/io/input/CharacterFilterReader.java | 18 +-- .../commons/io/input/CharacterSetFilterReader.java | 12 +- .../CharacterFilterReaderIntPredicateTest.java | 129 +++++++++++++++++++++ 4 files changed, 168 insertions(+), 26 deletions(-) diff --git a/src/main/java/org/apache/commons/io/input/AbstractCharacterFilterReader.java b/src/main/java/org/apache/commons/io/input/AbstractCharacterFilterReader.java index 70f92a2..02147ca 100644 --- a/src/main/java/org/apache/commons/io/input/AbstractCharacterFilterReader.java +++ b/src/main/java/org/apache/commons/io/input/AbstractCharacterFilterReader.java @@ -21,19 +21,46 @@ import static org.apache.commons.io.IOUtils.EOF; import java.io.FilterReader; import java.io.IOException; import java.io.Reader; +import java.util.function.IntPredicate; /** * A filter reader that filters out characters where subclasses decide which characters to filter out. */ public abstract class AbstractCharacterFilterReader extends FilterReader { + private static final IntPredicate SKIP_NONE = ch -> false; + + private final IntPredicate skip; + /** * Constructs a new reader. * * @param reader the reader to filter */ protected AbstractCharacterFilterReader(final Reader reader) { + this(reader, SKIP_NONE); + } + + /** + * Constructs a new reader. + * + * @param reader the reader to filter. + * @param skip Skip test. + * @since 2.9.0 + */ + protected AbstractCharacterFilterReader(final Reader reader, final IntPredicate skip) { super(reader); + this.skip = skip == null ? SKIP_NONE : skip; + } + + /** + * Returns true if the given character should be filtered out, false to keep the character. + * + * @param ch the character to test. + * @return true if the given character should be filtered out, false to keep the character. + */ + protected boolean filter(final int ch) { + return skip.test(ch); } @Override @@ -45,14 +72,6 @@ public abstract class AbstractCharacterFilterReader extends FilterReader { return ch; } - /** - * Returns true if the given character should be filtered out, false to keep the character. - * - * @param ch the character to test. - * @return true if the given character should be filtered out, false to keep the character. - */ - protected abstract boolean filter(int ch); - @Override public int read(final char[] cbuf, final int off, final int len) throws IOException { final int read = super.read(cbuf, off, len); diff --git a/src/main/java/org/apache/commons/io/input/CharacterFilterReader.java b/src/main/java/org/apache/commons/io/input/CharacterFilterReader.java index ff949bd..c6edd5b 100644 --- a/src/main/java/org/apache/commons/io/input/CharacterFilterReader.java +++ b/src/main/java/org/apache/commons/io/input/CharacterFilterReader.java @@ -17,6 +17,7 @@ package org.apache.commons.io.input; import java.io.Reader; +import java.util.function.IntPredicate; /** * A filter reader that filters out a given character represented as an {@code int} code point, handy to remove @@ -25,8 +26,6 @@ import java.io.Reader; */ public class CharacterFilterReader extends AbstractCharacterFilterReader { - private final int skip; - /** * Constructs a new reader. * @@ -36,13 +35,18 @@ public class CharacterFilterReader extends AbstractCharacterFilterReader { * the character to filter out. */ public CharacterFilterReader(final Reader reader, final int skip) { - super(reader); - this.skip = skip; + super(reader, c -> c == skip); } - @Override - protected boolean filter(final int ch) { - return ch == skip; + /** + * Constructs a new reader. + * + * @param reader the reader to filter. + * @param skip Skip test. + * @since 2.9.0 + */ + public CharacterFilterReader(final Reader reader, final IntPredicate skip) { + super(reader, skip); } } diff --git a/src/main/java/org/apache/commons/io/input/CharacterSetFilterReader.java b/src/main/java/org/apache/commons/io/input/CharacterSetFilterReader.java index 064cab6..a7577a9 100644 --- a/src/main/java/org/apache/commons/io/input/CharacterSetFilterReader.java +++ b/src/main/java/org/apache/commons/io/input/CharacterSetFilterReader.java @@ -32,9 +32,6 @@ import java.util.Set; */ public class CharacterSetFilterReader extends AbstractCharacterFilterReader { - private static final Set<Integer> EMPTY_SET = Collections.emptySet(); - private final Set<Integer> skipSet; - /** * Constructs a new reader. * @@ -53,14 +50,7 @@ public class CharacterSetFilterReader extends AbstractCharacterFilterReader { * @param skip the set of characters to filter out. */ public CharacterSetFilterReader(final Reader reader, final Set<Integer> skip) { - super(reader); - this.skipSet = skip == null ? EMPTY_SET : Collections.unmodifiableSet(skip); - } - - @Override - protected boolean filter(final int ch) { - // Note WRT Integer.valueOf(): You can increase the Integer cache with a system property, see {@link Integer}. - return skipSet.contains(Integer.valueOf(ch)); + super(reader, c -> skip == null ? null : Collections.unmodifiableSet(skip).contains(Integer.valueOf(c))); } } diff --git a/src/test/java/org/apache/commons/io/input/CharacterFilterReaderIntPredicateTest.java b/src/test/java/org/apache/commons/io/input/CharacterFilterReaderIntPredicateTest.java new file mode 100644 index 0000000..fba9c4a --- /dev/null +++ b/src/test/java/org/apache/commons/io/input/CharacterFilterReaderIntPredicateTest.java @@ -0,0 +1,129 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.io.input; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.io.IOException; +import java.io.StringReader; +import java.util.function.IntPredicate; + +import org.apache.commons.io.IOUtils; +import org.apache.commons.io.output.StringBuilderWriter; +import org.apache.commons.lang3.StringUtils; +import org.junit.jupiter.api.Test; + +/** + * Tests {@link CharacterFilterReader} with an {@link IntPredicate}. + */ +public class CharacterFilterReaderIntPredicateTest { + + @Test + public void testInputSize0FilterAll() throws IOException { + final StringReader input = new StringReader(StringUtils.EMPTY); + try (CharacterFilterReader reader = new CharacterFilterReader(input, ch -> true)) { + assertEquals(-1, reader.read()); + } + } + + @Test + public void testInputSize1FilterAll() throws IOException { + try (StringReader input = new StringReader("a"); + CharacterFilterReader reader = new CharacterFilterReader(input, ch -> true)) { + assertEquals(-1, reader.read()); + } + } + + @Test + public void testInputSize2FilterAll() throws IOException { + final StringReader input = new StringReader("aa"); + try (CharacterFilterReader reader = new CharacterFilterReader(input, ch -> true)) { + assertEquals(-1, reader.read()); + } + } + + @Test + public void testInputSize2FilterFirst() throws IOException { + final StringReader input = new StringReader("ab"); + try (CharacterFilterReader reader = new CharacterFilterReader(input, ch -> ch == 'a')) { + assertEquals('b', reader.read()); + assertEquals(-1, reader.read()); + } + } + + @Test + public void testInputSize2FilterLast() throws IOException { + final StringReader input = new StringReader("ab"); + try (CharacterFilterReader reader = new CharacterFilterReader(input, ch -> ch == 'b')) { + assertEquals('a', reader.read()); + assertEquals(-1, reader.read()); + } + } + + @Test + public void testInputSize5FilterWhitespace() throws IOException { + final StringReader input = new StringReader(" a b "); + try (CharacterFilterReader reader = new CharacterFilterReader(input, Character::isWhitespace)) { + assertEquals('a', reader.read()); + assertEquals('b', reader.read()); + assertEquals(-1, reader.read()); + } + } + + @Test + public void testReadIntoBuffer() throws IOException { + final StringReader input = new StringReader("ababcabcd"); + try (CharacterFilterReader reader = new CharacterFilterReader(input, ch -> ch == 'b')) { + final char[] buff = new char[9]; + final int charCount = reader.read(buff); + assertEquals(6, charCount); + assertEquals("aacacd", new String(buff, 0, charCount)); + } + } + + @Test + public void testReadIntoBufferFilterWhitespace() throws IOException { + final StringReader input = new StringReader(" a b a b c a b c d "); + try (CharacterFilterReader reader = new CharacterFilterReader(input, Character::isWhitespace)) { + final char[] buff = new char[19]; + final int charCount = reader.read(buff); + assertEquals(9, charCount); + assertEquals("ababcabcd", new String(buff, 0, charCount)); + } + } + + @Test + public void testReadUsingReader() throws IOException { + final StringReader input = new StringReader("ababcabcd"); + try (StringBuilderWriter output = new StringBuilderWriter(); + CharacterFilterReader reader = new CharacterFilterReader(input, ch -> ch == 'b')) { + IOUtils.copy(reader, output); + assertEquals("aacacd", output.toString()); + } + } + + @Test + public void testReadUsingReaderFilterWhitespace() throws IOException { + final StringReader input = new StringReader(" a b a b c a b c d "); + try (StringBuilderWriter output = new StringBuilderWriter(); + CharacterFilterReader reader = new CharacterFilterReader(input, Character::isWhitespace)) { + IOUtils.copy(reader, output); + assertEquals("ababcabcd", output.toString()); + } + } + +} \ No newline at end of file