KickJava   Java API By Example, From Geeks To Geeks.

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


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 CR/LFs in the underlying input stream to 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 CRLFtoLFInputStream extends FilterInputStream JavaDoc {
26     private boolean pendingByte = false;
27     private int lastByte = -1;
28     
29     /**
30      * Creates a new filtered input stream.
31      * @param in the underlying input stream
32      */

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

44     public int read() throws IOException JavaDoc {
45         if (! pendingByte) {
46             lastByte = in.read(); // ok if this throws
47
pendingByte = true; // remember the byte in case we throw an exception later on
48
}
49         if (lastByte == '\r') {
50             lastByte = in.read(); // ok if this throws
51
if (lastByte != '\n') {
52                 if (lastByte == -1) pendingByte = false;
53                 return '\r'; // leaves the byte pending for later
54
}
55         }
56         pendingByte = false;
57         return lastByte;
58     }
59     
60     /**
61      * Wraps the underlying stream's method.
62      * Translates CR/LF sequences to LFs transparently.
63      * @throws InterruptedIOException if the operation was interrupted before all of the
64      * bytes specified have been skipped, bytesTransferred may be non-zero
65      * @throws IOException if an i/o error occurs
66      */

67     public int read(byte[] buffer, int off, int len) throws IOException JavaDoc {
68         // handle boundary cases cleanly
69
if (len == 0) {
70             return 0;
71         } else if (len == 1) {
72             int b = read();
73             if (b == -1) return -1;
74             buffer[off] = (byte) b;
75             return 1;
76         }
77         // read some bytes from the stream
78
// prefix with pending byte from last read if any
79
int count = 0;
80         if (pendingByte) {
81             buffer[off] = (byte) lastByte;
82             pendingByte = false;
83             count = 1;
84         }
85         InterruptedIOException JavaDoc iioe = null;
86         try {
87             len = in.read(buffer, off + count, len - count);
88             if (len == -1) {
89                 return (count == 0) ? -1 : count;
90             }
91         } catch (InterruptedIOException JavaDoc e) {
92             len = e.bytesTransferred;
93             iioe = e;
94         }
95         count += len;
96         // strip out CR's in CR/LF pairs
97
// pendingByte will be true iff previous byte was a CR
98
int j = off;
99         for (int i = off; i < off + count; ++i) { // invariant: j <= i
100
lastByte = buffer[i];
101             if (lastByte == '\r') {
102                 if (pendingByte) {
103                     buffer[j++] = '\r'; // write out orphan CR
104
} else {
105                     pendingByte = true;
106                 }
107             } else {
108                 if (pendingByte) {
109                     if (lastByte != '\n') buffer[j++] = '\r'; // if LF, don't write the CR
110
pendingByte = false;
111                 }
112                 buffer[j++] = (byte) lastByte;
113             }
114         }
115         if (iioe != null) {
116             iioe.bytesTransferred = j - off;
117             throw iioe;
118         }
119         return j - off;
120     }
121
122     /**
123      * Calls read() to skip the specified number of bytes
124      * @throws InterruptedIOException if the operation was interrupted before all of the
125      * bytes specified have been skipped, bytesTransferred may be non-zero
126      * @throws IOException if an i/o error occurs
127      */

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

145     public int available() throws IOException JavaDoc {
146         return in.available() / 2; // we can guarantee at least this amount after contraction
147
}
148     
149     /**
150      * Mark is not supported by the wrapper even if the underlying stream does, returns false.
151      */

152     public boolean markSupported() {
153         return false;
154     }
155 }
156
Popular Tags