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 3525 2007-10-16 11:43:48Z tmorgner $
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(final char[] cbuf, final int off, final int len) throws IOException
076      {
077        if (len < 0)
078        {
079          throw new IllegalArgumentException();
080        }
081        if (off < 0)
082        {
083          throw new IndexOutOfBoundsException();
084        }
085        if (cbuf == null)
086        {
087          throw new NullPointerException();
088        }
089        if ((len + off) > cbuf.length)
090        {
091          throw new IndexOutOfBoundsException();
092        }
093    
094        ensureSize (cursor + len);
095    
096        System.arraycopy(cbuf, off, this.buffer, cursor, len);
097        cursor += len;
098      }
099    
100      private void ensureSize(final int size)
101      {
102        if (this.buffer.length >= size)
103        {
104          return;
105        }
106    
107        final int newSize = Math.max (size, this.buffer.length + bufferIncrement);
108        final char[] newBuffer = new char[newSize];
109        System.arraycopy(this.buffer, 0, newBuffer, 0, cursor);
110      }
111    
112      /**
113       * Flush the stream.  If the stream has saved any characters from the various write() methods in a buffer, write them
114       * immediately to their intended destination.  Then, if that destination is another character or byte stream, flush
115       * it.  Thus one flush() invocation will flush all the buffers in a chain of Writers and OutputStreams.
116       * <p/>
117       * If the intended destination of this stream is an abstraction provided by the underlying operating system, for
118       * example a file, then flushing the stream guarantees only that bytes previously written to the stream are passed to
119       * the operating system for writing; it does not guarantee that they are actually written to a physical device such as
120       * a disk drive.
121       *
122       * @throws java.io.IOException If an I/O error occurs
123       */
124      public void flush() throws IOException
125      {
126    
127      }
128    
129      /**
130       * Close the stream, flushing it first.  Once a stream has been closed, further write() or flush() invocations will
131       * cause an IOException to be thrown.  Closing a previously-closed stream, however, has no effect.
132       *
133       * @throws java.io.IOException If an I/O error occurs
134       */
135      public void close() throws IOException
136      {
137      }
138    
139      public String toString ()
140      {
141        return new String (buffer, 0, cursor);
142      }
143    }