/************************************************************************** OmegaT - Computer Assisted Translation (CAT) tool with fuzzy matching, translation memory, keyword search, glossaries, and translation leveraging into updated projects. Copyright (C) 2000-2006 Keith Godfrey, Maxym Mykhalchuk, and Henry Pijffers Home page: http://www.omegat.org/ Support center: http://groups.yahoo.com/group/OmegaT/ This file is part of OmegaT. OmegaT is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. OmegaT 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 General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. **************************************************************************/ package org.omegat.util; import java.io.IOException; import java.io.PushbackReader; import java.io.Reader; /** * Reader class that preserves line breaks when using readLine(), that can be * retrieved through getLastLinebreak() * * @author Henry Pijffers (henry.pijffers@saxnot.com) */ public class LinebreakPreservingReader extends Reader { /** Reader for input, must be able to re-insert non-linebreak characters. */ private final PushbackReader in; /** Buffer that contains the last linebreak */ private StringBuffer linebreak = new StringBuffer(2);; /** * Creates a new reader. */ public LinebreakPreservingReader(Reader in) { this.in = new PushbackReader(in); } public void close() throws IOException { in.close(); } /** * Returns the linebreak after the last line read by readLine(). If any * other read methods are called after readLine(), the linebreak returned by * this method may be incorrect. */ public String getLinebreak() { return linebreak.toString(); } public void mark(int readAheadLimit) throws IOException { in.mark(readAheadLimit); } public boolean markSupported() { return in.markSupported(); } public int read() throws IOException { return in.read(); } public int read(char[] cbuf) throws IOException { return in.read(cbuf); } public int read(char[] cbuf, int off, int len) throws IOException { return in.read(cbuf, off, len); } public String readLine() throws IOException { // Clear linebreak buffer linebreak.setLength(0); // Get the next character and check if it's not the end of the stream int chr = in.read(); if (chr == -1) { return null; // end of the stream reached } // Create a buffer to contain the result StringBuilder line = new StringBuilder(1024); // Read and store characters until a linebreak character is encountered while ((chr != -1) && !isLinebreakCharacter(chr)) { line.append((char) chr); chr = in.read(); } // If the last read character is a linebreak character, save it if (isLinebreakCharacter(chr)) { // Save the linebreak character linebreak.append((char) chr); // If the linebreak character is \r, check if it's followed by \n if (chr == '\r') { // Get the next character chr = in.read(); // If the next character is \n, add it to the current linebreak, // otherwise push it back into the input reader if (chr == '\n') { linebreak.append((char) chr); } else { in.unread(chr); } } } // We're all done, give the caller what he bargained for return line.toString(); } public boolean ready() throws IOException { return in.ready(); } public void reset() throws IOException { in.reset(); } public long skip(long n) throws IOException { return in.skip(n); } private final boolean isLinebreakCharacter(int chr) { return chr == '\n' || chr == '\r'; } /* FOR TESTING ONLY */ public void printLinebreak(java.io.PrintStream out) { out.print("Break: "); for (int i = 0; i < linebreak.length(); i++) { char c = linebreak.charAt(i); if (c == '\r') out.print("\\r"); else if (c == '\n') out.print("\\n"); else out.print(c); } out.println(); } }