001    /**
002     * ========================================
003     * JFreeReport : a free Java report library
004     * ========================================
005     *
006     * Project Info:  http://reporting.pentaho.org/
007     *
008     * (C) Copyright 2000-2007, by Object Refinery Limited, Pentaho Corporation and Contributors.
009     *
010     * This library is free software; you can redistribute it and/or modify it under the terms
011     * of the GNU Lesser General Public License as published by the Free Software Foundation;
012     * either version 2.1 of the License, or (at your option) any later version.
013     *
014     * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
015     * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
016     * See the GNU Lesser General Public License for more details.
017     *
018     * You should have received a copy of the GNU Lesser General Public License along with this
019     * library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
020     * Boston, MA 02111-1307, USA.
021     *
022     * [Java is a trademark or registered trademark of Sun Microsystems, Inc.
023     * in the United States and other countries.]
024     *
025     * ------------
026     * $Id: MemoryStringWriter.java,v 1.1 2007/05/14 08:56:29 taqua Exp $
027     * ------------
028     * (C) Copyright 2000-2005, by Object Refinery Limited.
029     * (C) Copyright 2005-2007, by Pentaho Corporation.
030     */
031    
032    package org.jfree.report.util;
033    
034    import java.io.IOException;
035    import java.io.Writer;
036    
037    /**
038     * A string writer that is able to write large amounts of data. The original StringWriter contained in Java doubles
039     * its buffersize everytime the buffer overflows. This is nice with small amounts of data, but awfull for huge
040     * buffers.
041     *
042     * @author Thomas Morgner
043     */
044    public class MemoryStringWriter extends Writer
045    {
046      private int bufferIncrement;
047      private int cursor;
048      private char[] buffer;
049    
050      /**
051       * Create a new character-stream writer whose critical sections will synchronize on the writer itself.
052       */
053      public MemoryStringWriter()
054      {
055        this(4096);
056      }
057    
058      /**
059       * Create a new character-stream writer whose critical sections will synchronize on the writer itself.
060       */
061      public MemoryStringWriter(final int bufferSize)
062      {
063        this.bufferIncrement = bufferSize;
064        this.buffer = new char[bufferSize];
065      }
066    
067      /**
068       * Write a portion of an array of characters.
069       *
070       * @param cbuf Array of characters
071       * @param off  Offset from which to start writing characters
072       * @param len  Number of characters to write
073       * @throws java.io.IOException If an I/O error occurs
074       */
075      public synchronized void write(char cbuf[], int off, int len) throws IOException
076      {
077        if (len < 0) throw new IllegalArgumentException();
078        if (off < 0)
079        {
080          throw new IndexOutOfBoundsException();
081        }
082        if (cbuf == null)
083        {
084          throw new NullPointerException();
085        }
086        if ((len + off) > cbuf.length)
087        {
088          throw new IndexOutOfBoundsException();
089        }
090    
091        ensureSize (cursor + len);
092    
093        System.arraycopy(cbuf, off, this.buffer, cursor, len);
094        cursor += len;
095      }
096    
097      private void ensureSize(final int size)
098      {
099        if (this.buffer.length >= size)
100        {
101          return;
102        }
103    
104        final int newSize = Math.max (size, this.buffer.length + bufferIncrement);
105        final char[] newBuffer = new char[newSize];
106        System.arraycopy(this.buffer, 0, newBuffer, 0, cursor);
107      }
108    
109      /**
110       * Flush the stream.  If the stream has saved any characters from the various write() methods in a buffer, write them
111       * immediately to their intended destination.  Then, if that destination is another character or byte stream, flush
112       * it.  Thus one flush() invocation will flush all the buffers in a chain of Writers and OutputStreams.
113       * <p/>
114       * If the intended destination of this stream is an abstraction provided by the underlying operating system, for
115       * example a file, then flushing the stream guarantees only that bytes previously written to the stream are passed to
116       * the operating system for writing; it does not guarantee that they are actually written to a physical device such as
117       * a disk drive.
118       *
119       * @throws java.io.IOException If an I/O error occurs
120       */
121      public void flush() throws IOException
122      {
123    
124      }
125    
126      /**
127       * Close the stream, flushing it first.  Once a stream has been closed, further write() or flush() invocations will
128       * cause an IOException to be thrown.  Closing a previously-closed stream, however, has no effect.
129       *
130       * @throws java.io.IOException If an I/O error occurs
131       */
132      public void close() throws IOException
133      {
134      }
135    
136      public String toString ()
137      {
138        return new String (buffer, 0, cursor);
139      }
140    }