001package ezvcard.util; 002 003import java.io.BufferedInputStream; 004import java.io.ByteArrayOutputStream; 005import java.io.IOException; 006import java.io.InputStream; 007import java.io.InputStreamReader; 008import java.io.Reader; 009import java.nio.charset.Charset; 010import java.nio.file.Files; 011import java.nio.file.Path; 012 013/* 014 Copyright (c) 2012-2023, Michael Angstadt 015 All rights reserved. 016 017 Redistribution and use in source and binary forms, with or without 018 modification, are permitted provided that the following conditions are met: 019 020 1. Redistributions of source code must retain the above copyright notice, this 021 list of conditions and the following disclaimer. 022 2. Redistributions in binary form must reproduce the above copyright notice, 023 this list of conditions and the following disclaimer in the documentation 024 and/or other materials provided with the distribution. 025 026 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 027 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 028 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 029 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 030 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 031 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 032 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 033 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 034 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 035 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 036 037 The views and conclusions contained in the software and documentation are those 038 of the authors and should not be interpreted as representing official policies, 039 either expressed or implied, of the FreeBSD Project. 040 */ 041 042/** 043 * Gets the entire contents of an input stream or a file. 044 * @author Michael Angstadt 045 */ 046public class Gobble { 047 private final Path file; 048 private final InputStream in; 049 private final Reader reader; 050 051 /** 052 * Gets the contents of a file. 053 * @param file the file 054 */ 055 public Gobble(Path file) { 056 this(file, null, null); 057 } 058 059 /** 060 * Gets the contents of an input stream. 061 * @param in the input stream 062 */ 063 public Gobble(InputStream in) { 064 this(null, in, null); 065 } 066 067 /** 068 * Gets the contents of a reader. 069 * @param reader the reader 070 */ 071 public Gobble(Reader reader) { 072 this(null, null, reader); 073 } 074 075 private Gobble(Path file, InputStream in, Reader reader) { 076 this.file = file; 077 this.in = in; 078 this.reader = reader; 079 } 080 081 /** 082 * Gets the stream contents as a string. If something other than a 083 * {@link Reader} was passed into this class's constructor, this method 084 * decodes the stream data using the system's default character encoding. 085 * @return the string 086 * @throws IOException if there was a problem reading from the stream 087 */ 088 public String asString() throws IOException { 089 return asString(Charset.defaultCharset()); 090 } 091 092 /** 093 * Gets the stream contents as a string. 094 * @param charset the character set to decode the stream data with (this 095 * parameter is ignored if a {@link Reader} was passed into this class's 096 * constructor) 097 * @return the string 098 * @throws IOException if there was a problem reading from the stream 099 */ 100 public String asString(Charset charset) throws IOException { 101 Reader reader = buildReader(charset); 102 return consumeReader(reader); 103 } 104 105 /** 106 * Gets the stream contents as a byte array. 107 * @return the byte array 108 * @throws IOException if there was a problem reading from the stream 109 * @throws IllegalStateException if a {@link Reader} object was passed into 110 * this class's constructor 111 */ 112 public byte[] asByteArray() throws IOException { 113 if (reader != null) { 114 throw new IllegalStateException("Cannot get raw bytes from a Reader object."); 115 } 116 117 InputStream in = buildInputStream(); 118 return consumeInputStream(in); 119 } 120 121 private Reader buildReader(Charset charset) throws IOException { 122 return (reader == null) ? new InputStreamReader(buildInputStream(), charset) : reader; 123 } 124 125 private InputStream buildInputStream() throws IOException { 126 return (in == null) ? new BufferedInputStream(Files.newInputStream(file)) : in; 127 } 128 129 private String consumeReader(Reader reader) throws IOException { 130 StringBuilder sb = new StringBuilder(); 131 char[] buffer = new char[4096]; 132 int read; 133 try { 134 while ((read = reader.read(buffer)) != -1) { 135 sb.append(buffer, 0, read); 136 } 137 } finally { 138 reader.close(); 139 } 140 return sb.toString(); 141 } 142 143 private byte[] consumeInputStream(InputStream in) throws IOException { 144 ByteArrayOutputStream out = new ByteArrayOutputStream(); 145 byte[] buffer = new byte[4096]; 146 int read; 147 try { 148 while ((read = in.read(buffer)) != -1) { 149 out.write(buffer, 0, read); 150 } 151 } finally { 152 in.close(); 153 } 154 return out.toByteArray(); 155 } 156}