/* * Geotools 2 - OpenSource mapping toolkit * (C) 2003, Geotools Project Managment Committee (PMC) * (C) 2001, Institut de Recherche pour le Développement * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but 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. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package org.geotools.io; // Standard I/O import java.io.FilterWriter; import java.io.IOException; import java.io.Writer; // Geotools dependencies import org.geotools.resources.Utilities; /** * Writes characters to a stream while expanding * tabs ('\t') into spaces. * * @version $Id$ * @author Martin Desruisseaux * * @since 2.0 */ public class ExpandedTabWriter extends FilterWriter { /** * Tab width (in number of spaces). */ private int tabWidth = 8; /** * Current column position. * Columns are numbered from 0. */ private int column = 0; /** * Constructs a filter which replaces tab characters ('\t') * with spaces. Tab widths default to 8 characters. * * @param out a Writer object to provide the underlying stream. */ public ExpandedTabWriter(final Writer out) { super(out); } /** * Constructs a filter which replaces tab characters ('\t') * with spaces, using the specified tab width. * * @param out a Writer object to provide the underlying stream. * @param tabWidth The tab width. Must be greater than 0. * @throws IllegalArgumentException if {@code tabWidth} * is not greater than 0. */ public ExpandedTabWriter(Writer out, int tabWidth) throws IllegalArgumentException { super(out); setTabWidth(tabWidth); } /** * Sets the tab width. * * @param tabWidth The tab width. Must be greater than 0. * @throws IllegalArgumentException if {@code tabWidth} * is not greater than 0. */ public void setTabWidth(final int tabWidth) throws IllegalArgumentException { synchronized (lock) { if (tabWidth > 0) { this.tabWidth = tabWidth; } else { throw new IllegalArgumentException(Integer.toString(tabWidth)); } } } /** * Returns the tab width. */ public int getTabWidth() { return tabWidth; } /** * Writes spaces for a tab character. * * @throws IOException If an I/O error occurs */ private void expand() throws IOException { final int width = tabWidth - (column % tabWidth); out.write(Utilities.spaces(width)); column += width; } /** * Writes a single character. * * @throws IOException If an I/O error occurs */ public void write(final int c) throws IOException { synchronized (lock) { switch (c) { case '\r': // fall through case '\n': column=0; break; case '\t': expand(); return; default : column++; break; } out.write(c); } } /** * Writes a portion of an array of characters. * * @param buffer Buffer of characters to be written * @param offset Offset from which to start reading characters * @param length Number of characters to be written * @throws IOException If an I/O error occurs */ public void write(final char[] buffer, final int offset, int length) throws IOException { synchronized (lock) { int start = offset; length += offset; for (int end=offset; end