KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > team > internal > core > streams > LFtoCRLFInputStream


1 /*******************************************************************************
2  * Copyright (c) 2000, 2006 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.team.internal.core.streams;
12
13 import java.io.FilterInputStream JavaDoc;
14 import java.io.IOException JavaDoc;
15 import java.io.InputStream JavaDoc;
16 import java.io.InterruptedIOException JavaDoc;
17
18 /**
19  * Converts LFs in the underlying input stream to CR/LF.
20  *
21  * Supports resuming partially completed operations after an InterruptedIOException
22  * if the underlying stream does. Check the bytesTransferred field to determine how
23  * much of the operation completed; conversely, at what point to resume.
24  */

25 public class LFtoCRLFInputStream extends FilterInputStream JavaDoc {
26     private boolean mustReturnLF = false;
27     
28     /**
29      * Creates a new filtered input stream.
30      * @param in the underlying input stream
31      */

32     public LFtoCRLFInputStream(InputStream JavaDoc in) {
33         super(in);
34     }
35
36     /**
37      * Wraps the underlying stream's method.
38      * Translates LFs to CR/LF sequences transparently.
39      * @throws InterruptedIOException if the operation was interrupted before all of the
40      * bytes specified have been skipped, bytesTransferred will be zero
41      * @throws IOException if an i/o error occurs
42      */

43     public int read() throws IOException JavaDoc {
44         if (mustReturnLF) {
45             mustReturnLF = false;
46             return '\n';
47         }
48         int b = in.read(); // ok if this throws
49
if (b == '\n') {
50             mustReturnLF = true;
51             b = '\r';
52         }
53         return b;
54     }
55
56     /**
57      * Wraps the underlying stream's method.
58      * Translates LFs to CR/LF sequences transparently.
59      * @throws InterruptedIOException if the operation was interrupted before all of the
60      * bytes specified have been skipped, bytesTransferred may be non-zero
61      * @throws IOException if an i/o error occurs
62      */

63     public int read(byte[] buffer, int off, int len) throws IOException JavaDoc {
64         // handle boundary cases cleanly
65
if (len == 0) {
66             return 0;
67         } else if (len == 1) {
68             int b = read();
69             if (b == -1) return -1;
70             buffer[off] = (byte) b;
71             return 1;
72         }
73         // prefix with remembered \n from last read, but don't expand it a second time
74
int count = 0;
75         if (mustReturnLF) {
76             mustReturnLF = false;
77             buffer[off++] = '\n';
78             --len;
79             count = 1;
80             if (len < 2) return count; // is there still enough room to expand more?
81
}
82         // read some bytes from the stream into the back half of the buffer
83
// this guarantees that there is always room to expand
84
len /= 2;
85         int j = off + len;
86         InterruptedIOException JavaDoc iioe = null;
87         try {
88             len = in.read(buffer, j, len);
89             if (len == -1) {
90                 return (count == 0) ? -1 : count;
91             }
92         } catch (InterruptedIOException JavaDoc e) {
93             len = e.bytesTransferred;
94             iioe = e;
95         }
96         count += len;
97         // copy bytes from the middle to the front of the array, expanding LF->CR/LF
98
while (len-- > 0) {
99             byte b = buffer[j++];
100             if (b == '\n') {
101                 buffer[off++] = '\r';
102                 count++;
103             }
104             buffer[off++] = b;
105         }
106         if (iioe != null) {
107             iioe.bytesTransferred = count;
108             throw iioe;
109         }
110         return count;
111     }
112
113     /**
114      * Calls read() to skip the specified number of bytes
115      * @throws InterruptedIOException if the operation was interrupted before all of the
116      * bytes specified have been skipped, bytesTransferred may be non-zero
117      * @throws IOException if an i/o error occurs
118      */

119     public long skip(long count) throws IOException JavaDoc {
120         int actualCount = 0; // assumes count < Integer.MAX_INT
121
try {
122             while (count-- > 0 && read() != -1) actualCount++; // skip the specified number of bytes
123
return actualCount;
124         } catch (InterruptedIOException JavaDoc e) {
125             e.bytesTransferred = actualCount;
126             throw e;
127         }
128     }
129
130     /**
131      * Wraps the underlying stream's method.
132      * Returns the number of bytes that can be read without blocking; accounts for
133      * possible translation of LFs to CR/LF sequences in these bytes.
134      * @throws IOException if an i/o error occurs
135      */

136     public int available() throws IOException JavaDoc {
137         return in.available(); // we can guarantee at least this amount after expansion
138
}
139     
140     /**
141      * Mark is not supported by the wrapper even if the underlying stream does, returns false.
142      */

143     public boolean markSupported() {
144         return false;
145     }
146 }
147
Popular Tags