public class FilterBufferImpl implements FilterBuffer { private int maxBufferSize; private boolean isClosed; private char[] buffer; public FilterBufferImpl(int maxsize) { maxBufferSize = maxsize; isClosed = false; buffer = new char[0]; } // Returns current contents of buffer and clears it. // FilterBuffers must block on read from empty buffer. // Read only returns after successul read. // Returns a zero-length array if its internal buffer // is empty and the FilterBuffer has been closed public synchronized char[] read () { try { while ( (buffer.length == 0) && (!isClosed) ) wait(); } catch (InterruptedException e) { e.printStackTrace(); } if ( (buffer.length == 0) && isClosed ) return new char[0]; char[] oldBuffer = buffer; buffer = new char[0]; notifyAll(); return oldBuffer; } // Write str to buffer if str.length is less than // maxBufferSize, otherwise throws exception. // FilterBuffers must block on write to full buffer. // Write only returns after successful write public synchronized void write(char[] str) throws BufTooSmallException { if (str.length > maxBufferSize) throw new BufTooSmallException(maxBufferSize, str.length); try { while (maxBufferSize - buffer.length < str.length) { wait(); } } catch (InterruptedException e) { e.printStackTrace(); } char[] newBuf = new char[buffer.length + str.length]; for (int i = 0; i < buffer.length; i++) newBuf[i] = buffer[i]; for (int i = 0, j = buffer.length; i < str.length; i++, j++) newBuf[j] = str[i]; buffer = newBuf; notifyAll(); } public int getMaxBufferSize() { return maxBufferSize; } // Informs the FilterBuffer that no more data will be written to it public synchronized void close() { isClosed = true; notifyAll(); } // Doesn't return until the buffer is empty public synchronized void flush() { try { while ( (buffer.length > 0) ) wait(); } catch (InterruptedException e) { e.printStackTrace(); } } }