ExpandTabsReader.java revision 1327
922N/A/*
922N/A * CDDL HEADER START
922N/A *
922N/A * The contents of this file are subject to the terms of the
922N/A * Common Development and Distribution License (the "License").
922N/A * You may not use this file except in compliance with the License.
922N/A *
922N/A * See LICENSE.txt included in this distribution for the specific
922N/A * language governing permissions and limitations under the License.
922N/A *
922N/A * When distributing Covered Code, include this CDDL HEADER in each
922N/A * file and include the License file at LICENSE.txt.
922N/A * If applicable, add the following below this CDDL HEADER, with the
922N/A * fields enclosed by brackets "[]" replaced with your own identifying
922N/A * information: Portions Copyright [yyyy] [name of copyright owner]
922N/A *
922N/A * CDDL HEADER END
922N/A */
922N/A
922N/A/*
922N/A * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
922N/A * Use is subject to license terms.
922N/A */
922N/A
922N/Apackage org.opensolaris.opengrok.analysis;
922N/A
922N/Aimport java.io.FilterReader;
922N/Aimport java.io.IOException;
922N/Aimport java.io.Reader;
922N/Aimport org.opensolaris.opengrok.configuration.Project;
922N/A
922N/A/**
922N/A * Wrapper around Reader to expand tabs to spaces in the input.
922N/A */
922N/Apublic class ExpandTabsReader extends FilterReader {
922N/A /** The size of tabs. */
922N/A private final int tabSize;
922N/A
922N/A /**
922N/A * The position on the current line. Used to decide how many spaces to
922N/A * insert to fill up to the next tab stop.
922N/A */
922N/A private int pos;
922N/A
922N/A /**
922N/A * Number of spaces to insert (as replacement for a tab) before reading
922N/A * more from the underlying stream.
922N/A */
922N/A private int spacesToInsert;
922N/A
922N/A /**
922N/A * Create a new ExpandTabsReader to expand tabs to spaces.
922N/A *
922N/A * @param in the original input source
922N/A * @param tabSize the size of tabs
922N/A */
922N/A ExpandTabsReader(Reader in, int tabSize) {
922N/A super(in);
922N/A this.tabSize = tabSize;
922N/A }
922N/A
922N/A /**
922N/A * Wrap a reader in an ExpandTabsReader if the project has custom tab
922N/A * size settings.
922N/A *
922N/A * @param in the reader to wrap
922N/A * @param p the project
922N/A * @return {@code in} if the project doesn't have custom tab settings;
922N/A * otherwise, an {@code ExpandTabsReader} that wraps {@code in} and expands
922N/A * tabs as defined by the project's settings
922N/A */
922N/A public static Reader wrap(Reader in, Project p) {
922N/A return (p != null && p.hasTabSizeSetting())
922N/A ? new ExpandTabsReader(in, p.getTabSize())
922N/A : in;
922N/A }
922N/A
922N/A @Override
922N/A public int read() throws IOException {
922N/A
922N/A if (spacesToInsert > 0) {
922N/A pos++;
922N/A spacesToInsert--;
922N/A return ' ';
922N/A }
922N/A
922N/A int c = super.read();
922N/A
922N/A if (c == '\t') {
922N/A // Fill up with spaces up to the next tab stop
922N/A int spaces = tabSize - (pos % tabSize);
922N/A pos++;
922N/A spacesToInsert = spaces - 1;
922N/A return ' ';
922N/A }
922N/A
922N/A if (c == '\n' || c == '\r') {
922N/A // Reset position on new line
922N/A pos = 0;
922N/A } else {
922N/A pos++;
922N/A }
922N/A
922N/A return c;
922N/A }
922N/A
922N/A @Override
922N/A public int read(char[] cbuf, int off, int len) throws IOException {
922N/A for (int i = 0; i < len; i++) {
922N/A int c = read();
922N/A if (c == -1) {
922N/A return (i > 0 ? i : -1);
922N/A }
922N/A cbuf[off + i] = (char) c;
922N/A }
922N/A return len;
922N/A }
922N/A
922N/A @Override
922N/A public long skip(long n) throws IOException {
922N/A if (n < 0L) {
922N/A throw new IllegalArgumentException("n is negative");
922N/A }
922N/A
922N/A long skipped = 0;
922N/A for (long l = 0; l < n; l++) {
922N/A int c = read();
922N/A if (c == -1) {
922N/A break;
922N/A }
922N/A skipped++;
922N/A }
922N/A
922N/A return skipped;
922N/A }
922N/A
922N/A @Override
922N/A public boolean markSupported() {
922N/A // Support for mark/reset has not been implemented.
922N/A return false;
922N/A }
922N/A}