Logo
Distributed Genetic Programming Framework
print print

File org.sfc.io.TextWriter.java

Here you can find all the information about the file org.sfc.io.TextWriter.java. You may explore it here or download it onto your local disk.
/*
 * Copyright (c) 2005 Thomas Weise
 *
 * E-Mail           : tweise@gmx.de
 * Creation Date    : 2005-12-20 09:43:24
 * Original Filename: org.sfc.io.TextWriter.java
 * Version          : 3.0.0
 * Last modification: 2006-04-10
 *                by: Thomas Weise
 *
 * License          : GNU LESSER GENERAL PUBLIC LICENSE
 *                    Version 2.1, February 1999
 *                    You should have received a copy of this license along
 *                    with this library; if not, write to the Free Software
 *                    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *                    MA 02111-1307, USA or download the license under
 *                    http://www.gnu.org/copyleft/lesser.html.
 *
 * Warranty         : This software is provided "as is" without any
 *                    warranty; without even the implied warranty of
 *                    merchantability or fitness for a particular purpose.
 *                    See the Gnu Lesser General Public License for more
 *                    details.
 */


package org.sfc.io;

import java.io.IOException;
import java.util.Calendar;
import java.util.GregorianCalendar;

import org.sfc.collections.Arrays;
import org.sfc.text.Text;

/**
 * A writer backed by a string builder. This writer can be used to write
 * structured/typed data into an internal buffer which then can be flushed
 * to the output.
 *
 *
 * @author Thomas Weise
 */

public class TextWriter extends ReferenceCountedWriter
  {
/**
 * The internal indentation buffer.
 */

  private static  char[]  s_indent = new char[] {' '' '' '' ',
                                                 ' '' '' '' ',
                                                 ' '' '' '' ',
                                                 ' '' '' '' ',
                                                 ' '' '' '' ',
                                                 ' '' '' '' ',
                                                 ' '' '' '' ',
                                                 ' '' '' '' '};
/**
 * The ultimate line break char.
 */

  private static  final char  LINE_BREAK  =
  Text.LINE_BREAK_CHARS[Text.LINE_BREAK_CHARS.length-1];
/**
 * The internal char array holding <code>"null"</code> 
 */

  private static  final char[]  NULL_CHB = (""+null).toCharArray();
  
/**
 * The internal string builder.
 */

  private final StringBuilder                m_sb     ;
/**
 * The output writer object.
 */

  private final ReferenceCountedWriter       m_out     ;
/**
 * The calendar to be used internally.
 */

  private final Calendar                     m_calendar;
/**
 * The indentation count.
 */

  private       int                          m_indent  ;
/**
 * >= 0 as long as indentation will be performed.
 */

  private       int                          m_active  ;
/**
 * <code>true</code> if indentation is required at the next output
 * operation.
 */

  private       boolean                      m_new_line ;
/**
 * The indentation factor.
 */

  private       int                          m_indent_factor  ;
/**
 * The internal buffer;
 */

  private       char[]                       m_buffer;
  
  
/**
 * Create a new buffered writer.
 * @param p_out             The output stream to write to.
 * @param p_default_indent  The default indentation step width.
 */

  public   TextWriter(final Object p_out,
                      final int    p_default_indent)
    {
    super();
    this.m_sb             = new StringBuilder();
    this.m_out            = IO.get_writer(p_out);
    this.m_calendar       = new GregorianCalendar();
    this.m_indent_factor  = ((p_default_indent > 0) ? p_default_indent : 4);
    this.m_new_line       = true;
    this.m_buffer         = new char[128];
    }
  
/**
 * Create a new buffered writer.
 * @param p_out             The output stream to write to.
 */

  public   TextWriter(final Object p_out)
    {
    this(p_out, -1);
    }
  
/**
 * Ensures the the stuff written next will be at the beginning of a new
 * line.
 */

  public  final void  ensure_new_line()
    {
    if(!(this.m_new_line))
      {      
      this.m_sb.append(Text.LINE_BREAK_CHARS, 0, Text.LINE_BREAK_CHARS.length);
      this.m_new_line = true;
      }
    }
  
/**
 * Increase the indentation level.
 */

  public  final void  inc_indent ()
    {
    int l_x;
    
    l_x = (this.m_indent + this.m_indent_factor);
    this.m_indent = l_x;
    
    synchronized(TextWriter.class)
      {
      if(l_x > s_indent.length)
        {
        s_indent = new char[l_x << 1];
        Arrays.fill(s_indent, ' ');
        }
      }
    }
  
/**
 * Decrease the indentation level.
 */

  public  final void  dec_indent ()
    {
    this.m_indent -= this.m_indent_factor;
    }
  
/**
 * Turn indentation on.
 */

  public  final void  indent_on ()
    {
    this.m_active++;
    }
  
/**
 * Turn indentation off.
 */

  public  final void  indent_off ()
    {
    this.m_active--;
    }
  
/**
 * Returns the current indentation level of the writer.
 * @return  The current indentation level of the writer.
 */

  public  final int get_indent  ()
    {
    return this.m_indent;
    }
  
  
/**
 * Buffer a time constant.
 * @param p_time      The time constant. This is a value of the type
 *                    <code>long</code>, for example obtained by
 *                    <code>System.currentMillies</code>.
 * @param p_relative  <code>true</code> if the time expression is relative.
 * @see System#currentTimeMillis()
 */

  public  final void  write_time   (final long     p_time,
                                    final boolean  p_relative)
    {
    Calendar  l_c;
    
    l_c = this.m_calendar;
    l_c.setTimeInMillis(p_time);
    this.write(Text.time_to_string(l_c, p_relative));
    }



/**
 * Buffer a double to this event output.
 * @param p_double  The double to be buffered.
 */

  public  final void  write_double (final double p_double)
    {
    this.write(Text.double_to_string(p_double));
    }

/**
 * Buffer a integer to this event output.
 * @param p_integer  The integer to be buffered.
 */

  public  final void  write_int    (final int   p_integer)
    {
    this.m_sb.append(p_integer);
    }

/**
 * Buffer a object to this event output.
 * @param p_object  The object to be buffered.
 */

  public  final void  write_object  (final Object p_object)
    {
    this.write(String.valueOf(p_object));
    }

/**
 * Buffer a long to this event output.
 * @param p_long  The long to be buffered.
 */

  public  final void  write_long   (final long  p_long)
    {
    String l_s;
    l_s = Long.toString(p_long);
    this.write(l_s, 0, l_s.length());
    }


/**
 * Write a single character.
 * @param p_c The character to be written.
 */

  @Override
  public final  void write(final  int p_c)
    {
    if(this.m_active >= 0)
      {
      if(p_c == LINE_BREAK)
        {
        this.m_new_line = true;
        }
      else
        {
        if((this.m_new_line) && (this.m_active >= 0))
          {
          this.m_sb.append(s_indent, 0, this.m_indent);
          }
        this.m_new_line = false;
        }
      }
    
    this.m_sb.append((char)p_c);
    }

/**
 * Write a portion of an array of characters.
 *
 * @param  p_cbuf  Buffer of characters to be written
 * @param  p_off   Offset from which to start reading characters
 * @param  p_len   Number of characters to be written
 */

  @Override
  public final  void write(final  char[]  p_cbuf,
                                  int     p_off,
                                  int     p_len)
    {
    int     l_i, l_idt;
    char    l_x;
    boolean l_z;
    
    if(p_len <= 0) return;
    
    if(this.m_active >= 0)
      {
      l_x    = LINE_BREAK;
      p_len += p_off;
      l_idt  = this.m_indent;
      l_z    = this.m_new_line;
      
      for(l_i = p_off; l_i < p_len; l_i++)
        {
        if(p_cbuf[l_i] == l_x)
          {
          if(l_z)
            {
            if(l_i > p_off) this.m_sb.append(s_indent, 0, l_idt);
            }
          else l_z = true;
                    
          this.m_sb.append(p_cbuf, p_off, l_i - p_off + 1);          
          p_off = (l_i + 1);
          }
        }
      
      if(p_off < l_i)
        {
        if(l_z) this.m_sb.append(s_indent, 0, l_idt);
        this.m_sb.append(p_cbuf, p_off, l_i - p_off);
        this.m_new_line = false;
        }
      else
        {
        this.m_new_line = true;
        }
      }
    else
      {
      this.m_sb.append(p_cbuf, p_off, p_len);
      }    
    }

/**
 * Return the name of the character encoding being used by this stream.
 *
 * <p> If the encoding has an historical name then that name is returned;
 * otherwise the encoding's canonical name is returned.
 *
 * <p> If this instance was created with the  constructor then the returned
 * name, being unique for the encoding, may differ from the name passed to
 * the constructor.  This method may return <tt>null</tt> if the stream has
 * been closed. </p>
 *
 * @return The historical name of this encoding, or possibly
 *         <code>null</code> if the stream has been closed
 */

  @Override
  public  final String  get_encoding  ()
    {
    return default_get_encoding(this.m_out);
    }

/**
 * Ensure proper buffer size.
 * @param p_size  The needed buffer size.
 * @return  The buffer.
 */

  private final char[]  ensure_size (final int p_size)
    {
    char[]  l_b;
    
    l_b = this.m_buffer;
        
    if(l_b.length < p_size)
      {
      return (this.m_buffer = new char[p_size << 1]);
      }
    
    return l_b;
    }
  
/**
 * Write a portion of a string.
 *
 * @param  p_str  String to be written
 * @param  p_off  Offset from which to start reading characters
 * @param  p_len  Number of characters to be written
 */

  @Override
  public final  void write(final  String  p_str,
                           final  int     p_off,
                           final  int     p_len)
    {
    char[]  l_b;
    
    if(p_len > 0)
      {
      if(this.m_active >= 0)
        {        
        l_b = this.ensure_size(p_len);        
        p_str.getChars(p_off, p_off + p_len, l_b, 0);
        this.write(l_b, 0, p_len);
        
        }
      else this.m_sb.append(p_str, p_off, p_len);
      }
    }

/**
 * Write an array of characters.
 *
 * @param  p_cbuf  Array of characters to be written
 */

  @Override
  public final  void write(char p_cbuf[])
    {
    if(p_cbuf == null) p_cbuf = NULL_CHB;
    this.write(p_cbuf, 0, p_cbuf.length);
    }

/**
 * Write a string.
 *
 * @param  p_str  String to be written
 */

  @Override
  public final  void write(final  String p_str)
    {
    if(p_str != null)
      {
      this.write(p_str, 0, p_str.length());
      }
    else
      {
      this.write(NULL_CHB, 0, NULL_CHB.length);
      }
    }

/**
 * Write a boolean value.
 *
 * @param  p_bool The boolean value to write.
 */

  public final  void write_boolean(final  boolean p_bool)
    {
    this.write(p_bool ? '1' : '0');
    }

/**
 * Append a newline to the internal buffer.
 * @see Text#LINE_BREAK_CHARS
 */

  public  final void  write_linebreak ()
    {
    this.m_sb.append(Text.LINE_BREAK_CHARS, 0, Text.LINE_BREAK_CHARS.length);
    /* if(this.m_active >= 0)*/ this.m_new_line = true;    
    }
  
/**
 * This method will return <code>true</code> if and only if the item
 * printed next would be the first thing on a new line.
 * @return  This method will return <code>true</code> if and only if the
 *          item printed next would be the first thing on a new line.
 */

  public  final boolean is_new_line()
    {
    return this.m_new_line;
    }

/**
 * Append the given char sequence to the text writer,
 * @param p_cs  The char sequence to append.
 */

  public  final void  write_cs  (final CharSequence p_cs)
    {
    char[]  l_b;
    int     l_l, l_j;
    
    l_l = p_cs.length();
    
    if(l_l > 0)
      {
      if(this.m_active >= 0)
        {        
        l_b = this.ensure_size(l_l);
        
        for(l_j = (l_l-1); l_j >= 0; l_j--)
          {
          l_b[l_j] = p_cs.charAt(l_j);
          }
        
        this.write(l_b, 0, l_l);        
        }
      else this.m_sb.append(p_cs);
      }
    this.m_sb.append(p_cs);
    }

/**
 * Append a csv separator.
 * @see Text#CSV_SEPARATOR_CHARS
 */

  public  final void  write_csv_separator ()
    {
    this.write(Text.CSV_SEPARATOR_CHARS);
    }

/**
 * Obtain the current length of the internal buffer.
 * @return The current length of the internal buffer.
 */

  public final int get_buffer_length ()
    {
    return this.m_sb.length();
    }

/**
 * Flush the stream.
 */

  @Override
  public final  void flush()
    {
    StringBuilder l_sb;
    char[]        l_b;
    int           l_i;

    l_sb = this.m_sb;
    l_i  = l_sb.length();
    if(l_i > 0)
      {
      try
        {
        l_b = ensure_size(l_i);
        l_sb.getChars(0, l_i, l_b, 0);
        this.m_out.write(l_b, 0, l_i);
        }
      catch(Throwable l_t)
        {
        //
        }
      finally
        {
        l_sb.setLength(0);
        }

      try
        {
        this.m_out.flush();
        }
      catch(Throwable l_t)
        {
        //
        }
      }
    }
  
/**
 * Dispose this reference counted writer.
 * @throws  IOException If the underlying was closed and caused an
 *                      IOException.
 */

  @Override
  protected void  dispose () throws IOException
    {
    this.flush();
    try
      {
      this.m_out.close();
      }
    finally
      {    
      super.dispose();
      }
    }
  
/**
 * Obtain a text writer from a normal object.
 * @param p_o   The object to be converted to a text writer.
 * @return  The text writer representing the object.
 */

  public  static  final TextWriter  get_text_writer (final Object p_o)
    {
    if(p_o instanceof TextWriter) return ((TextWriter)p_o);
    return new TextWriter(IO.get_writer(p_o));
    }
  }

File Information:

file name:TextWriter.java
package:org.sfc.io
qualified name:org.sfc.io.TextWriter.java
file type:Java Source File
download location:download http://dgpf.sourceforge.net/source/org/sfc/io/TextWriter.java
size:14.191 KB (14532 B)
uploaded: 2015-07-22 04:11:12 GMT+0000
last update: 2006-05-29 04:16:36 GMT+0000
last access: 2018-01-22 04:02:40 GMT+0000

statistics online since 2006-01-02.   RSS Feed
Contact us by sending an email to tweise@gmx.de to receive further information, to report errors, or to join our project.
All content on this site (http://dgpf.sourceforge.net/) is LGPL-licensed.
http://dgpf.sourceforge.net/scripts/source/source.php last modified at 2015-07-22 04:10:53 GMT+0000 served at 2018-01-22 04:02:40 GMT+0000.
Valid CSS Valid XHTML 1.1
Valid RSS SourceForge.net Logo