1 /**************************************************************** 2 * Licensed to the Apache Software Foundation (ASF) under one * 3 * or more contributor license agreements. See the NOTICE file * 4 * distributed with this work for additional information * 5 * regarding copyright ownership. The ASF licenses this file * 6 * to you under the Apache License, Version 2.0 (the * 7 * "License"); you may not use this file except in compliance * 8 * with the License. You may obtain a copy of the License at * 9 * * 10 * http://www.apache.org/licenses/LICENSE-2.0 * 11 * * 12 * Unless required by applicable law or agreed to in writing, * 13 * software distributed under the License is distributed on an * 14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * 15 * KIND, either express or implied. See the License for the * 16 * specific language governing permissions and limitations * 17 * under the License. * 18 ****************************************************************/ 19 20 package org.apache.james.mime4j; 21 22 import java.io.IOException; 23 import java.io.InputStream; 24 import java.io.PushbackInputStream; 25 26 /** 27 * InputStream which converts <code>\r</code> 28 * bytes not followed by <code>\n</code> and <code>\n</code> not 29 * preceded by <code>\r</code> to <code>\r\n</code>. 30 * 31 * 32 * @version $Id: EOLConvertingInputStream.java,v 1.4 2004/11/29 13:15:42 ntherning Exp $ 33 */ 34 public class EOLConvertingInputStream extends InputStream { 35 /** Converts single '\r' to '\r\n' */ 36 public static final int CONVERT_CR = 1; 37 /** Converts single '\n' to '\r\n' */ 38 public static final int CONVERT_LF = 2; 39 /** Converts single '\r' and '\n' to '\r\n' */ 40 public static final int CONVERT_BOTH = 3; 41 42 private PushbackInputStream in = null; 43 private int previous = 0; 44 private int flags = CONVERT_BOTH; 45 46 /** 47 * Creates a new <code>EOLConvertingInputStream</code> 48 * instance converting bytes in the given <code>InputStream</code>. 49 * The flag <code>CONVERT_BOTH</code> is the default. 50 * 51 * @param in the <code>InputStream</code> to read from. 52 */ 53 public EOLConvertingInputStream(InputStream in) { 54 this(in, CONVERT_BOTH); 55 } 56 /** 57 * Creates a new <code>EOLConvertingInputStream</code> 58 * instance converting bytes in the given <code>InputStream</code>. 59 * 60 * @param in the <code>InputStream</code> to read from. 61 * @param flags one of <code>CONVERT_CR</code>, <code>CONVERT_LF</code> or 62 * <code>CONVERT_BOTH</code>. 63 */ 64 public EOLConvertingInputStream(InputStream in, int flags) { 65 super(); 66 67 this.in = new PushbackInputStream(in, 2); 68 this.flags = flags; 69 } 70 71 /** 72 * Closes the underlying stream. 73 * 74 * @throws IOException on I/O errors. 75 */ 76 public void close() throws IOException { 77 in.close(); 78 } 79 80 /** 81 * @see java.io.InputStream#read() 82 */ 83 public int read() throws IOException { 84 int b = in.read(); 85 86 if (b == -1) { 87 return -1; 88 } 89 90 if ((flags & CONVERT_CR) != 0 && b == '\r') { 91 int c = in.read(); 92 if (c != -1) { 93 in.unread(c); 94 } 95 if (c != '\n') { 96 in.unread('\n'); 97 } 98 } else if ((flags & CONVERT_LF) != 0 && b == '\n' && previous != '\r') { 99 b = '\r'; 100 in.unread('\n'); 101 } 102 103 previous = b; 104 105 return b; 106 } 107 108 } 109