Source code: org/finj/filter/ASCIIDataFilterInputStream.java
1 package org.finj.filter;
2
3 import java.io.FilterInputStream;
4 import java.io.PushbackInputStream;
5 import java.io.InputStream;
6 import java.io.IOException;
7
8 /**
9 * Filter to be placed on <code>InputStream</code> when downloading
10 * data in <code>org.finj.FTPConstants.ASCII_DATA_TYPE</code>.
11 *
12 * Exchanges all occurrences of CR, CR/LF, LF/CR, LF for the one that
13 * is correct for the plateform on which <code>org.finj.FTPClient</code>
14 * is running.
15 *
16 * FIXME : mention default values.
17 *
18 * Copyright (C)
19 *
20 * This library is free software; you can redistribute it and/or
21 * modify it under the terms of the GNU Lesser General Public
22 * License as published by the Free Software Foundation; either
23 * version 2.1 of the License, or (at your option) any later version.
24 *
25 * This library is distributed in the hope that it will be useful,
26 * but WITHOUT ANY WARRANTY; without even the implied warranty of
27 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
28 * Lesser General Public License for more details.
29 *
30 * You should have received a copy of the GNU Lesser General Public
31 * License along with this library; if not, write to the Free Software
32 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
33 *
34 * @author Javier Iglesias -- jiglesias@users.sourceforge.net
35 * @version $Id: ASCIIDataFilterInputStream.java,v 1.1.1.1 2003/05/12 16:37:27 jiglesia Exp $
36 */
37 public class ASCIIDataFilterInputStream extends FilterInputStream {
38
39 /**
40 * Defines the integer value that corresponding to the LineFeed character in the table.
41 *
42 * @since v1.0.2
43 */
44 private int LF_CODE = 0x0A;
45
46 /**
47 * Defines the integer value corresponding to the CarriageReturn character in the table.
48 *
49 * @since v1.0.2
50 */
51 private int CR_CODE = 0x0D;
52
53 /**
54 * Constructs a new instance of this class, wrapping and filtering <code>in</code>.
55 *
56 * @param in <code>InputStream</code> to filter.
57 * @since v1.0.2
58 */
59 public ASCIIDataFilterInputStream ( InputStream in ) {
60 super(new PushbackInputStream(in, 1));
61 }
62
63 /**
64 * Constructs a new instance of this class, resetting the integer values
65 * for the LineFeed and CarriageReturn characters to the values provided.
66 *
67 * @param in <code>InputStream</code> to filter.
68 * @param lineFeed value to consider as being the LineFeed character in the table.
69 * @param carriageReturn value to consider as being the CarriageReturn character in the table.
70 * @since v1.0.2
71 */
72 protected ASCIIDataFilterInputStream ( InputStream in,
73 int lineFeed,
74 int carriageReturn ) {
75 this(in);
76 LF_CODE = lineFeed;
77 CR_CODE = carriageReturn;
78 }
79
80 /**
81 * Returns one filtered <code>byte</code> from the undelying fields.
82 *
83 * Any occurrence of LF, or LF+CR, or CR+LF, or CR is replaced by the
84 * local system '\n' character. Decision is left to the JVM !
85 *
86 * @return value read.
87 * @since v1.0.2
88 */
89 public int read ( ) throws IOException {
90 int data = read();
91
92 if ( data == LF_CODE ) {
93 // it's a LF, maybe followd by a CR ?
94 data = read();
95 if ( data != CR_CODE ) {
96 // ... no : push it back !
97 ((PushbackInputStream)in).unread(data);
98 }
99 return '\n'; // let JVM decide which character to use :)
100 }
101
102 if ( data == CR_CODE ) {
103 // it's a CR, maybe followed by a LF ?
104 data = read();
105 if ( data != LF_CODE ) {
106 // ... no : push it back !
107 ((PushbackInputStream)in).unread(data);
108 }
109 return '\n'; // let JVM decide which character to use :)
110 }
111
112 // this is no NL character !
113 return data;
114 }
115
116 /**
117 * Stores as much filtered <code>data</code> as possible to read from the
118 * underlying stream.
119 *
120 * @return number of <code>byte</code>s returned.
121 * @since v1.0.2
122 */
123 public int read ( byte[] data ) throws IOException {
124 return read(data, 0, data.length);
125 }
126
127
128 /**
129 * Stores as much filtered <code>data</code> as possible to read from the
130 * underlying stream.
131 *
132 * @return number of <code>byte</code>s returned.
133 * @since v1.0.2
134 */
135 public int read ( byte[] data, int offset, int length ) throws IOException {
136 // NB : for efficiency (?), count is shifted by offset !
137 int count = offset;
138
139 while ( (available() > 0) &&
140 (count<length) ) {
141 data[count] = (byte)read();
142 count++;
143 }
144
145 return (count-offset); // remove offset before returning. cf. NB above.
146 }
147 }