001/* 002 * JGrapes Event Driven Framework 003 * Copyright (C) 2018 Michael N. Lipp 004 * 005 * This program is free software; you can redistribute it and/or modify it 006 * under the terms of the GNU General Public License as published by 007 * the Free Software Foundation; either version 3 of the License, or 008 * (at your option) any later version. 009 * 010 * This program is distributed in the hope that it will be useful, but 011 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 012 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 013 * for more details. 014 * 015 * You should have received a copy of the GNU General Public License along 016 * with this program; if not, see <http://www.gnu.org/licenses/>. 017 */ 018 019package org.jgrapes.io.util; 020 021import java.io.FilterReader; 022import java.io.IOException; 023import java.io.Reader; 024 025/** 026 * A filter that copies all data read into a buffer. The buffer has to be 027 * cleared regularly (see {@link #copied} else heap space will eventually 028 * become exhausted. 029 */ 030public class CopyReader extends FilterReader { 031 032 @SuppressWarnings("PMD.AvoidStringBufferField") 033 private final StringBuilder copied = new StringBuilder(); 034 private int copyBufferSize = 1024 * 10; 035 private boolean overflow; 036 037 /** 038 * Instantiates a new copy reader. 039 * 040 * @param source the source 041 */ 042 public CopyReader(Reader source) { 043 super(source); 044 } 045 046 /** 047 * Sets the copy buffer size, defaults to 10240. 048 * 049 * @param size the size 050 * @return the copy reader 051 */ 052 @SuppressWarnings("PMD.LinguisticNaming") 053 public CopyReader setCopyBufferSize(int size) { 054 copyBufferSize = size; 055 return this; 056 } 057 058 @Override 059 public int read() throws IOException { 060 char[] buf = new char[1]; 061 if (read(buf, 0, 1) == -1) { 062 return -1; 063 } else { 064 return buf[0]; 065 } 066 } 067 068 @Override 069 public int read(char[] cbuf, int off, int len) throws IOException { 070 int count = in.read(cbuf, off, len); 071 if (count > 0 && !overflow) { 072 if (copied.length() > copyBufferSize) { 073 copied.append("..."); 074 overflow = true; 075 } else { 076 copied.append(cbuf, off, count); 077 } 078 } 079 return count; 080 } 081 082 /** 083 * Returns all chars and resets the copy buffer. 084 * 085 * @return the string 086 */ 087 public String copied() { 088 int count = copied.length(); 089 String res = copied.substring(0, count); 090 copied.delete(0, count); 091 overflow = false; 092 return res; 093 094 } 095}