src/org/sonews/util/io/CRLFOutputStream.java
author František Kučera <franta-hg@frantovo.cz>
Tue Oct 25 10:39:57 2011 +0200 (2011-10-25)
changeset 108 fdc075324ef3
parent 107 b723308e1359
permissions -rw-r--r--
SMTP: correct escaping of messages containing lines with single dot.
franta-hg@107
     1
/* CRLFOutputStream.java --
franta-hg@107
     2
Copyright (C) 2002, 2003, 2004  Free Software Foundation, Inc.
franta-hg@107
     3
franta-hg@107
     4
This file is part of GNU Classpath.
franta-hg@107
     5
franta-hg@107
     6
GNU Classpath is free software; you can redistribute it and/or modify
franta-hg@107
     7
it under the terms of the GNU General Public License as published by
franta-hg@107
     8
the Free Software Foundation; either version 2, or (at your option)
franta-hg@107
     9
any later version.
franta-hg@107
    10
franta-hg@107
    11
GNU Classpath is distributed in the hope that it will be useful, but
franta-hg@107
    12
WITHOUT ANY WARRANTY; without even the implied warranty of
franta-hg@107
    13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
franta-hg@107
    14
General Public License for more details.
franta-hg@107
    15
franta-hg@107
    16
You should have received a copy of the GNU General Public License
franta-hg@107
    17
along with GNU Classpath; see the file COPYING.  If not, write to the
franta-hg@107
    18
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
franta-hg@107
    19
02110-1301 USA.
franta-hg@107
    20
franta-hg@107
    21
Linking this library statically or dynamically with other modules is
franta-hg@107
    22
making a combined work based on this library.  Thus, the terms and
franta-hg@107
    23
conditions of the GNU General Public License cover the whole
franta-hg@107
    24
combination.
franta-hg@107
    25
franta-hg@107
    26
As a special exception, the copyright holders of this library give you
franta-hg@107
    27
permission to link this library with independent modules to produce an
franta-hg@107
    28
executable, regardless of the license terms of these independent
franta-hg@107
    29
modules, and to copy and distribute the resulting executable under
franta-hg@107
    30
terms of your choice, provided that you also meet, for each linked
franta-hg@107
    31
independent module, the terms and conditions of the license of that
franta-hg@107
    32
module.  An independent module is a module which is not derived from
franta-hg@107
    33
or based on this library.  If you modify this library, you may extend
franta-hg@107
    34
this exception to your version of the library, but you are not
franta-hg@107
    35
obligated to do so.  If you do not wish to do so, delete this
franta-hg@107
    36
exception statement from your version. 
franta-hg@107
    37
 */
franta-hg@107
    38
package org.sonews.util.io; // original package: gnu.java.net
franta-hg@107
    39
franta-hg@107
    40
import java.io.FilterOutputStream;
franta-hg@107
    41
import java.io.IOException;
franta-hg@107
    42
import java.io.OutputStream;
franta-hg@107
    43
import java.io.UnsupportedEncodingException;
franta-hg@107
    44
franta-hg@107
    45
/** 
franta-hg@107
    46
 * An output stream that filters LFs into CR/LF pairs.
franta-hg@107
    47
 *
franta-hg@107
    48
 * @author Chris Burdess (dog@gnu.org)
franta-hg@108
    49
 * @version classpath-0.98
franta-hg@107
    50
 */
franta-hg@107
    51
public class CRLFOutputStream extends FilterOutputStream {
franta-hg@107
    52
franta-hg@107
    53
	static final String US_ASCII = "US-ASCII";
franta-hg@107
    54
	/**
franta-hg@107
    55
	 * The CR octet.
franta-hg@107
    56
	 */
franta-hg@107
    57
	public static final int CR = 13;
franta-hg@107
    58
	/**
franta-hg@107
    59
	 * The LF octet.
franta-hg@107
    60
	 */
franta-hg@107
    61
	public static final int LF = 10;
franta-hg@107
    62
	/**
franta-hg@107
    63
	 * The CR/LF pair.
franta-hg@107
    64
	 */
franta-hg@107
    65
	public static final byte[] CRLF = {CR, LF};
franta-hg@107
    66
	/**
franta-hg@107
    67
	 * The last byte read.
franta-hg@107
    68
	 */
franta-hg@107
    69
	protected int last;
franta-hg@107
    70
franta-hg@107
    71
	/**
franta-hg@107
    72
	 * Constructs a CR/LF output stream connected to the specified output stream.
franta-hg@107
    73
	 */
franta-hg@107
    74
	public CRLFOutputStream(OutputStream out) {
franta-hg@107
    75
		super(out);
franta-hg@107
    76
		last = -1;
franta-hg@107
    77
	}
franta-hg@107
    78
franta-hg@107
    79
	/**
franta-hg@107
    80
	 * Writes a character to the underlying stream.
franta-hg@107
    81
	 * @exception IOException if an I/O error occurred
franta-hg@107
    82
	 */
franta-hg@107
    83
	@Override
franta-hg@107
    84
	public void write(int ch) throws IOException {
franta-hg@107
    85
		if (ch == CR) {
franta-hg@107
    86
			out.write(CRLF);
franta-hg@107
    87
		} else if (ch == LF) {
franta-hg@107
    88
			if (last != CR) {
franta-hg@107
    89
				out.write(CRLF);
franta-hg@107
    90
			}
franta-hg@107
    91
		} else {
franta-hg@107
    92
			out.write(ch);
franta-hg@107
    93
		}
franta-hg@107
    94
		last = ch;
franta-hg@107
    95
	}
franta-hg@107
    96
franta-hg@107
    97
	/**
franta-hg@107
    98
	 * Writes a byte array to the underlying stream.
franta-hg@107
    99
	 * @exception IOException if an I/O error occurred
franta-hg@107
   100
	 */
franta-hg@107
   101
	@Override
franta-hg@107
   102
	public void write(byte[] b) throws IOException {
franta-hg@107
   103
		write(b, 0, b.length);
franta-hg@107
   104
	}
franta-hg@107
   105
franta-hg@107
   106
	/**
franta-hg@107
   107
	 * Writes a portion of a byte array to the underlying stream.
franta-hg@107
   108
	 * @exception IOException if an I/O error occurred
franta-hg@107
   109
	 */
franta-hg@107
   110
	@Override
franta-hg@107
   111
	public void write(byte[] b, int off, int len) throws IOException {
franta-hg@107
   112
		int d = off;
franta-hg@107
   113
		len += off;
franta-hg@107
   114
		for (int i = off; i < len; i++) {
franta-hg@107
   115
			switch (b[i]) {
franta-hg@107
   116
				case CR:
franta-hg@107
   117
					out.write(b, d, i - d);
franta-hg@107
   118
					out.write(CRLF, 0, 2);
franta-hg@107
   119
					d = i + 1;
franta-hg@107
   120
					break;
franta-hg@107
   121
				case LF:
franta-hg@107
   122
					if (last != CR) {
franta-hg@107
   123
						out.write(b, d, i - d);
franta-hg@107
   124
						out.write(CRLF, 0, 2);
franta-hg@107
   125
					}
franta-hg@107
   126
					d = i + 1;
franta-hg@107
   127
					break;
franta-hg@107
   128
			}
franta-hg@107
   129
			last = b[i];
franta-hg@107
   130
		}
franta-hg@107
   131
		if (len - d > 0) {
franta-hg@107
   132
			out.write(b, d, len - d);
franta-hg@107
   133
		}
franta-hg@107
   134
	}
franta-hg@107
   135
franta-hg@107
   136
	/**
franta-hg@107
   137
	 * Writes the specified ASCII string to the underlying stream.
franta-hg@107
   138
	 * @exception IOException if an I/O error occurred
franta-hg@107
   139
	 */
franta-hg@107
   140
	public void write(String text) throws IOException {
franta-hg@107
   141
		try {
franta-hg@107
   142
			byte[] bytes = text.getBytes(US_ASCII);
franta-hg@107
   143
			write(bytes, 0, bytes.length);
franta-hg@107
   144
		} catch (UnsupportedEncodingException e) {
franta-hg@107
   145
			throw new IOException("The US-ASCII encoding is not supported on this system", e);
franta-hg@107
   146
		}
franta-hg@107
   147
	}
franta-hg@107
   148
franta-hg@107
   149
	/**
franta-hg@107
   150
	 * Writes a newline to the underlying stream.
franta-hg@107
   151
	 * @exception IOException if an I/O error occurred
franta-hg@107
   152
	 */
franta-hg@107
   153
	public void writeln() throws IOException {
franta-hg@107
   154
		out.write(CRLF, 0, 2);
franta-hg@107
   155
	}
franta-hg@107
   156
}