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 */
017package org.apache.logging.log4j.core.util;
018
019import java.io.IOException;
020import java.io.InputStream;
021import java.io.OutputStream;
022import java.io.Reader;
023import java.io.Writer;
024
025/**
026 * Copied from Apache Commons IO revision 1686747.
027 */
028public class IOUtils {
029
030    /**
031     * The default buffer size ({@value}) to use for
032     * {@link #copyLarge(InputStream, OutputStream)}
033     * and
034     * {@link #copyLarge(Reader, Writer)}
035     */
036    private static final int DEFAULT_BUFFER_SIZE = 1024 * 4;
037
038    /**
039     * Represents the end-of-file (or stream).
040     */
041    public static final int EOF = -1;
042
043    /**
044     * Copies chars from a <code>Reader</code> to a <code>Writer</code>.
045     * <p/>
046     * This method buffers the input internally, so there is no need to use a
047     * <code>BufferedReader</code>.
048     * <p/>
049     * Large streams (over 2GB) will return a chars copied value of
050     * <code>-1</code> after the copy has completed since the correct
051     * number of chars cannot be returned as an int. For large streams
052     * use the <code>copyLarge(Reader, Writer)</code> method.
053     *
054     * @param input the <code>Reader</code> to read from
055     * @param output the <code>Writer</code> to write to
056     * @return the number of characters copied, or -1 if &gt; Integer.MAX_VALUE
057     * @throws NullPointerException if the input or output is null
058     * @throws IOException          if an I/O error occurs
059     * @since 1.1
060     */
061    public static int copy(final Reader input, final Writer output) throws IOException {
062        final long count = copyLarge(input, output);
063        if (count > Integer.MAX_VALUE) {
064            return -1;
065        }
066        return (int) count;
067    }
068
069    /**
070     * Copies chars from a large (over 2GB) <code>Reader</code> to a <code>Writer</code>.
071     * <p/>
072     * This method buffers the input internally, so there is no need to use a
073     * <code>BufferedReader</code>.
074     * <p/>
075     * The buffer size is given by {@link #DEFAULT_BUFFER_SIZE}.
076     *
077     * @param input the <code>Reader</code> to read from
078     * @param output the <code>Writer</code> to write to
079     * @return the number of characters copied
080     * @throws NullPointerException if the input or output is null
081     * @throws IOException          if an I/O error occurs
082     * @since 1.3
083     */
084    public static long copyLarge(final Reader input, final Writer output) throws IOException {
085        return copyLarge(input, output, new char[DEFAULT_BUFFER_SIZE]);
086    }
087
088    /**
089     * Copies chars from a large (over 2GB) <code>Reader</code> to a <code>Writer</code>.
090     * <p/>
091     * This method uses the provided buffer, so there is no need to use a
092     * <code>BufferedReader</code>.
093     * <p/>
094     *
095     * @param input the <code>Reader</code> to read from
096     * @param output the <code>Writer</code> to write to
097     * @param buffer the buffer to be used for the copy
098     * @return the number of characters copied
099     * @throws NullPointerException if the input or output is null
100     * @throws IOException          if an I/O error occurs
101     * @since 2.2
102     */
103    public static long copyLarge(final Reader input, final Writer output, final char[] buffer) throws IOException {
104        long count = 0;
105        int n;
106        while (EOF != (n = input.read(buffer))) {
107            output.write(buffer, 0, n);
108            count += n;
109        }
110        return count;
111    }
112
113    /**
114     * Gets the contents of a <code>Reader</code> as a String.
115     * <p/>
116     * This method buffers the input internally, so there is no need to use a
117     * <code>BufferedReader</code>.
118     *
119     * @param input the <code>Reader</code> to read from
120     * @return the requested String
121     * @throws NullPointerException if the input is null
122     * @throws IOException          if an I/O error occurs
123     */
124    public static String toString(final Reader input) throws IOException {
125        final StringBuilderWriter sw = new StringBuilderWriter();
126        copy(input, sw);
127        return sw.toString();
128    }
129
130}