/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 * 
 *      https://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.directory.api.util;


import java.io.Writer;


/**
 * {@link Writer} implementation that outputs to a {@link StringBuilder}.
 * <p>
 * <strong>NOTE:</strong> This implementation, as an alternative to
 * <code>java.io.StringWriter</code>, provides an <i>un-synchronized</i>
 * (i.e. for use in a single thread) implementation for better performance.
 * For safe usage with multiple {@link Thread}s then
 * <code>java.io.StringWriter</code> should be used.
 *
 * @version $Id: StringBuilderWriter.java 1415850 2012-11-30 20:51:39Z ggregory $
 * @since 2.0
 */
public class StringBuilderWriter extends Writer
{

    private final StringBuilder builder;


    /**
     * Construct a new {@link StringBuilder} instance with default capacity.
     */
    public StringBuilderWriter()
    {
        builder = new StringBuilder();
    }


    /**
     * Construct a new {@link StringBuilder} instance with the specified capacity.
     *
     * @param capacity The initial capacity of the underlying {@link StringBuilder}
     */
    public StringBuilderWriter( int capacity )
    {
        builder = new StringBuilder( capacity );
    }


    /**
     * Construct a new instance with the specified {@link StringBuilder}.
     *
     * @param builder The String builder
     */
    public StringBuilderWriter( StringBuilder builder )
    {
        this.builder = builder != null ? builder : new StringBuilder();
    }


    /**
     * Append a single character to this Writer.
     *
     * @param value The character to append
     * @return This writer instance
     */
    @Override
    public Writer append( char value )
    {
        builder.append( value );
        
        return this;
    }


    /**
     * Append a character sequence to this Writer.
     *
     * @param value The character to append
     * @return This writer instance
     */
    @Override
    public Writer append( CharSequence value )
    {
        builder.append( value );
        
        return this;
    }


    /**
     * Append a portion of a character sequence to the {@link StringBuilder}.
     *
     * @param value The character to append
     * @param start The index of the first character
     * @param end The index of the last character + 1
     * @return This writer instance
     */
    @Override
    public Writer append( CharSequence value, int start, int end )
    {
        builder.append( value, start, end );
        
        return this;
    }


    /**
     * Closing this writer has no effect. 
     */
    @Override
    public void close()
    {
    }


    /**
     * Flushing this writer has no effect. 
     */
    @Override
    public void flush()
    {
    }


    /**
     * Write a String to the {@link StringBuilder}.
     * 
     * @param value The value to write
     */
    @Override
    public void write( String value )
    {
        if ( value != null )
        {
            builder.append( value );
        }
    }


    /**
     * Write a portion of a character array to the {@link StringBuilder}.
     *
     * @param value The value to write
     * @param offset The index of the first character
     * @param length The number of characters to write
     */
    @Override
    public void write( char[] value, int offset, int length )
    {
        if ( value != null )
        {
            builder.append( value, offset, length );
        }
    }


    /**
     * Return the underlying builder.
     *
     * @return The underlying builder
     */
    public StringBuilder getBuilder()
    {
        return builder;
    }


    /**
     * Returns {@link StringBuilder#toString()}.
     *
     * @return The contents of the String builder.
     */
    @Override
    public String toString()
    {
        return builder.toString();
    }
}
