001/*
002 *  Licensed to the Apache Software Foundation (ASF) under one or more
003 *  contributor license agreements.  See the NOTICE file distributed with
004 *  this work for additional information regarding copyright ownership.
005 *  The ASF licenses this file to You under the Apache License, Version 2.0
006 *  (the "License"); you may not use this file except in compliance with
007 *  the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 *  Unless required by applicable law or agreed to in writing, software
012 *  distributed under the License is distributed on an "AS IS" BASIS,
013 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 *  See the License for the specific language governing permissions and
015 *  limitations under the License.
016 */
017
018package org.apache.commons.io.input;
019
020import java.io.BufferedReader;
021import java.io.FilterInputStream;
022import java.io.IOException;
023import java.io.InputStream;
024import java.io.UncheckedIOException;
025
026import org.apache.commons.io.build.AbstractStreamBuilder;
027import org.apache.commons.io.function.Uncheck;
028
029/**
030 * A {@link BufferedReader} that throws {@link UncheckedIOException} instead of {@link IOException}.
031 *
032 * @see BufferedReader
033 * @see IOException
034 * @see UncheckedIOException
035 * @since 2.12.0
036 */
037public final class UncheckedFilterInputStream extends FilterInputStream {
038
039    /**
040     * Builds a new {@link UncheckedFilterInputStream} instance.
041     * <p>
042     * Using File IO:
043     * </p>
044     * <pre>{@code
045     * UncheckedFilterInputStream s = UncheckedFilterInputStream.builder()
046     *   .setFile(file)
047     *   .get()}
048     * </pre>
049     * <p>
050     * Using NIO Path:
051     * </p>
052     * <pre>{@code
053     * UncheckedFilterInputStream s = UncheckedFilterInputStream.builder()
054     *   .setPath(path)
055     *   .get()}
056     * </pre>
057     */
058    public static class Builder extends AbstractStreamBuilder<UncheckedFilterInputStream, Builder> {
059
060        @Override
061        public UncheckedFilterInputStream get() {
062            // This an unchecked class, so this method is as well.
063            return Uncheck.get(() -> new UncheckedFilterInputStream(getOrigin().getInputStream()));
064        }
065
066    }
067
068    /**
069     * Constructs a new {@link Builder}.
070     *
071     * @return a new {@link Builder}.
072     */
073    public static Builder builder() {
074        return new Builder();
075    }
076
077    /**
078     * Creates a {@link UncheckedFilterInputStream}.
079     *
080     * @param inputStream the underlying input stream, or {@code null} if this instance is to be created without an
081     *        underlying stream.
082     */
083    private UncheckedFilterInputStream(final InputStream inputStream) {
084        super(inputStream);
085    }
086
087    /**
088     * Calls this method's super and rethrow {@link IOException} as {@link UncheckedIOException}.
089     */
090    @Override
091    public int available() throws UncheckedIOException {
092        return Uncheck.get(super::available);
093    }
094
095    /**
096     * Calls this method's super and rethrow {@link IOException} as {@link UncheckedIOException}.
097     */
098    @Override
099    public void close() throws UncheckedIOException {
100        Uncheck.run(super::close);
101    }
102
103    /**
104     * Calls this method's super and rethrow {@link IOException} as {@link UncheckedIOException}.
105     */
106    @Override
107    public int read() throws UncheckedIOException {
108        return Uncheck.get(super::read);
109    }
110
111    /**
112     * Calls this method's super and rethrow {@link IOException} as {@link UncheckedIOException}.
113     */
114    @Override
115    public int read(final byte[] b) throws UncheckedIOException {
116        return Uncheck.apply(super::read, b);
117    }
118
119    /**
120     * Calls this method's super and rethrow {@link IOException} as {@link UncheckedIOException}.
121     */
122    @Override
123    public int read(final byte[] b, final int off, final int len) throws UncheckedIOException {
124        return Uncheck.apply(super::read, b, off, len);
125    }
126
127    /**
128     * Calls this method's super and rethrow {@link IOException} as {@link UncheckedIOException}.
129     */
130    @Override
131    public synchronized void reset() throws UncheckedIOException {
132        Uncheck.run(super::reset);
133    }
134
135    /**
136     * Calls this method's super and rethrow {@link IOException} as {@link UncheckedIOException}.
137     */
138    @Override
139    public long skip(final long n) throws UncheckedIOException {
140        return Uncheck.apply(super::skip, n);
141    }
142
143}