1 /*
2 * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
50 * Create a Quoted Printable decoder that decodes the specified
51 * input stream.
52 * @param in the input stream
53 */
54 public QPDecoderStream(InputStream in) {
55 super(new PushbackInputStream(in, 2)); // pushback of size=2
56 }
57
58 /**
59 * Read the next decoded byte from this input stream. The byte
60 * is returned as an <code>int</code> in the range <code>0</code>
61 * to <code>255</code>. If no byte is available because the end of
62 * the stream has been reached, the value <code>-1</code> is returned.
63 * This method blocks until input data is available, the end of the
64 * stream is detected, or an exception is thrown.
65 *
66 * @return the next byte of data, or <code>-1</code> if the end of the
67 * stream is reached.
68 * @exception IOException if an I/O error occurs.
69 */
70 public int read() throws IOException {
71 if (spaces > 0) {
72 // We have cached space characters, return one
73 spaces--;
74 return ' ';
75 }
76
77 int c = in.read();
78
79 if (c == ' ') {
80 // Got space, keep reading till we get a non-space char
81 while ((c = in.read()) == ' ')
82 spaces++;
83
84 if (c == '\r' || c == '\n' || c == -1)
85 // If the non-space char is CR/LF/EOF, the spaces we got
86 // so far is junk introduced during transport. Junk 'em.
87 spaces = 0;
88 else {
89 // The non-space char is NOT CR/LF, the spaces are valid.
133 }
134 }
135 }
136 return c;
137 }
138
139 /**
140 * Reads up to <code>len</code> decoded bytes of data from this input stream
141 * into an array of bytes. This method blocks until some input is
142 * available.
143 * <p>
144 *
145 * @param buf the buffer into which the data is read.
146 * @param off the start offset of the data.
147 * @param len the maximum number of bytes read.
148 * @return the total number of bytes read into the buffer, or
149 * <code>-1</code> if there is no more data because the end of
150 * the stream has been reached.
151 * @exception IOException if an I/O error occurs.
152 */
153 public int read(byte[] buf, int off, int len) throws IOException {
154 int i, c;
155 for (i = 0; i < len; i++) {
156 if ((c = read()) == -1) {
157 if (i == 0) // At end of stream, so we should
158 i = -1; // return -1 , NOT 0.
159 break;
160 }
161 buf[off+i] = (byte)c;
162 }
163 return i;
164 }
165
166 /**
167 * Tests if this input stream supports marks. Currently this class
168 * does not support marks
169 */
170 public boolean markSupported() {
171 return false;
172 }
173
174 /**
175 * Returns the number of bytes that can be read from this input
176 * stream without blocking. The QP algorithm does not permit
177 * a priori knowledge of the number of bytes after decoding, so
178 * this method just invokes the <code>available</code> method
179 * of the original input stream.
180 */
181 public int available() throws IOException {
182 // This is bogus ! We don't really know how much
183 // bytes are available *after* decoding
184 return in.available();
185 }
186
187 /**** begin TEST program
188 public static void main(String argv[]) throws Exception {
189 FileInputStream infile = new FileInputStream(argv[0]);
190 QPDecoderStream decoder = new QPDecoderStream(infile);
191 int c;
192
193 while ((c = decoder.read()) != -1)
194 System.out.print((char)c);
195 System.out.println();
196 }
197 *** end TEST program ****/
198 }
|
1 /*
2 * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
50 * Create a Quoted Printable decoder that decodes the specified
51 * input stream.
52 * @param in the input stream
53 */
54 public QPDecoderStream(InputStream in) {
55 super(new PushbackInputStream(in, 2)); // pushback of size=2
56 }
57
58 /**
59 * Read the next decoded byte from this input stream. The byte
60 * is returned as an <code>int</code> in the range <code>0</code>
61 * to <code>255</code>. If no byte is available because the end of
62 * the stream has been reached, the value <code>-1</code> is returned.
63 * This method blocks until input data is available, the end of the
64 * stream is detected, or an exception is thrown.
65 *
66 * @return the next byte of data, or <code>-1</code> if the end of the
67 * stream is reached.
68 * @exception IOException if an I/O error occurs.
69 */
70 @Override
71 public int read() throws IOException {
72 if (spaces > 0) {
73 // We have cached space characters, return one
74 spaces--;
75 return ' ';
76 }
77
78 int c = in.read();
79
80 if (c == ' ') {
81 // Got space, keep reading till we get a non-space char
82 while ((c = in.read()) == ' ')
83 spaces++;
84
85 if (c == '\r' || c == '\n' || c == -1)
86 // If the non-space char is CR/LF/EOF, the spaces we got
87 // so far is junk introduced during transport. Junk 'em.
88 spaces = 0;
89 else {
90 // The non-space char is NOT CR/LF, the spaces are valid.
134 }
135 }
136 }
137 return c;
138 }
139
140 /**
141 * Reads up to <code>len</code> decoded bytes of data from this input stream
142 * into an array of bytes. This method blocks until some input is
143 * available.
144 * <p>
145 *
146 * @param buf the buffer into which the data is read.
147 * @param off the start offset of the data.
148 * @param len the maximum number of bytes read.
149 * @return the total number of bytes read into the buffer, or
150 * <code>-1</code> if there is no more data because the end of
151 * the stream has been reached.
152 * @exception IOException if an I/O error occurs.
153 */
154 @Override
155 public int read(byte[] buf, int off, int len) throws IOException {
156 int i, c;
157 for (i = 0; i < len; i++) {
158 if ((c = read()) == -1) {
159 if (i == 0) // At end of stream, so we should
160 i = -1; // return -1 , NOT 0.
161 break;
162 }
163 buf[off+i] = (byte)c;
164 }
165 return i;
166 }
167
168 /**
169 * Tests if this input stream supports marks. Currently this class
170 * does not support marks
171 */
172 @Override
173 public boolean markSupported() {
174 return false;
175 }
176
177 /**
178 * Returns the number of bytes that can be read from this input
179 * stream without blocking. The QP algorithm does not permit
180 * a priori knowledge of the number of bytes after decoding, so
181 * this method just invokes the <code>available</code> method
182 * of the original input stream.
183 */
184 @Override
185 public int available() throws IOException {
186 // This is bogus ! We don't really know how much
187 // bytes are available *after* decoding
188 return in.available();
189 }
190
191 /**** begin TEST program
192 public static void main(String argv[]) throws Exception {
193 FileInputStream infile = new FileInputStream(argv[0]);
194 QPDecoderStream decoder = new QPDecoderStream(infile);
195 int c;
196
197 while ((c = decoder.read()) != -1)
198 System.out.print((char)c);
199 System.out.println();
200 }
201 *** end TEST program ****/
202 }
|