Statistics
| Revision:

root / tmp / org.txm.core / src / groovy / filters / FusionXmlHeaderBody / ReaderInputStream.groovy @ 187

History | View | Annotate | Download (5.4 kB)

1
// Copyright © 2010-2013 ENS de Lyon.
2
// Copyright © 2007-2010 ENS de Lyon, CNRS, INRP, University of
3
// Lyon 2, University of Franche-Comté, University of Nice
4
// Sophia Antipolis, University of Paris 3.
5
// 
6
// The TXM platform is free software: you can redistribute it
7
// and/or modify it under the terms of the GNU General Public
8
// License as published by the Free Software Foundation,
9
// either version 2 of the License, or (at your option) any
10
// later version.
11
// 
12
// The TXM platform is distributed in the hope that it will be
13
// useful, but WITHOUT ANY WARRANTY; without even the implied
14
// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15
// PURPOSE. See the GNU General Public License for more
16
// details.
17
// 
18
// You should have received a copy of the GNU General
19
// Public License along with the TXM platform. If not, see
20
// http://www.gnu.org/licenses.
21
// 
22
// 
23
// 
24
// $LastChangedDate:$
25
// $LastChangedRevision:$
26
// $LastChangedBy:$ 
27
//
28
package filters.FusionXmlHeaderBody;
29

    
30
/*
31
 * Copyright 2004-2005 The Apache Software Foundation.
32
 *
33
 *  Licensed under the Apache License, Version 2.0 (the "License");
34
 *  you may not use this file except in compliance with the License.
35
 *  You may obtain a copy of the License at
36
 *
37
 *      http://www.apache.org/licenses/LICENSE-2.0
38
 *
39
 *  Unless required by applicable law or agreed to in writing, software
40
 *  distributed under the License is distributed on an "AS IS" BASIS,
41
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
42
 *  See the License for the specific language governing permissions and
43
 *  limitations under the License.
44
 */
45
import java.io.IOException;
46
import java.io.InputStream;
47
import java.io.Reader;
48

    
49
// TODO: Auto-generated Javadoc
50
/**
51
 * Adapts a <code>Reader</code> as an <code>InputStream</code>. Adapted from
52
 * <CODE>StringInputStream</CODE>.
53
 */
54
public class ReaderInputStream extends InputStream {
55
        Reader input;
56

    
57
        /** The encoding. */
58
        String encoding = System.getProperty("file.encoding");
59

    
60
        /** The slack. */
61
        byte[] slack;
62

    
63
        /** The begin. */
64
        int begin;
65

    
66
        /**
67
         * Construct a <CODE>ReaderInputStream</CODE> for the specified
68
         * <CODE>Reader</CODE>.
69
         * 
70
         * @param reader
71
         *            <CODE>Reader</CODE>. Must not be <code>null</code>.
72
         */
73
        public ReaderInputStream(Reader reader) {
74
                input = reader;
75
        }
76

    
77
        /**
78
         * Construct a <CODE>ReaderInputStream</CODE> for the specified
79
         * <CODE>Reader</CODE>, with the specified encoding.
80
         * 
81
         * @param reader
82
         *            non-null <CODE>Reader</CODE>.
83
         * @param encoding
84
         *            non-null <CODE>String</CODE> encoding.
85
         */
86
        public ReaderInputStream(Reader reader, String encoding) {
87
                this(reader);
88
                if (encoding == null) {
89
                        throw new IllegalArgumentException("encoding must not be null");
90
                } else {
91
                        this.encoding = encoding;
92
                }
93
        }
94

    
95
        /**
96
         * Reads from the <CODE>Reader</CODE>, returning the same value.
97
         *
98
         * @return the value of the next character in the <CODE>Reader</CODE>.
99
         */
100
        public synchronized int read() throws IOException {
101
                if (input == null) {
102
                        throw new IOException("Stream Closed");
103
                }
104

    
105
                byte result;
106
                if (slack != null && begin < slack.length) {
107
                        result = slack[begin];
108
                        if (++begin == slack.length) {
109
                                slack = null;
110
                        }
111
                } else {
112
                        byte[] buf = new byte[1];
113
                        if (read(buf, 0, 1) <= 0) {
114
                                result = -1;
115
                        }
116
                        result = buf[0];
117
                }
118

    
119
                if (result < -1) {
120
                        result += 256;
121
                }
122

    
123
                return result;
124
        }
125

    
126
        /**
127
         * Reads from the <code>Reader</code> into a byte array.
128
         *
129
         * @param b the byte array to read into
130
         * @param off the offset in the byte array
131
         * @param len the length in the byte array to fill
132
         * @return the actual number read into the byte array, -1 at the end of the
133
         * stream
134
         */
135
        public synchronized int read(byte[] b, int off, int len) throws IOException {
136
                if (input == null) {
137
                        throw new IOException("Stream Closed");
138
                }
139

    
140
                while (slack == null) {
141
                        char[] buf = new char[len]; // might read too much
142
                        int n = input.read(buf);
143
                        if (n == -1) {
144
                                return -1;
145
                        }
146
                        if (n > 0) {
147
                                slack = new String(buf, 0, n).getBytes(encoding);
148
                                begin = 0;
149
                        }
150
                }
151

    
152
                if (len > slack.length - begin) {
153
                        len = slack.length - begin;
154
                }
155

    
156
                System.arraycopy(slack, begin, b, off, len);
157

    
158
                if ((begin += len) >= slack.length) {
159
                        slack = null;
160
                }
161

    
162
                return len;
163
        }
164

    
165
        /**
166
         * Marks the read limit of the StringReader.
167
         * 
168
         * @param limit
169
         *            the maximum limit of bytes that can be read before the mark
170
         *            position becomes invalid
171
         */
172
        public synchronized void mark(final int limit) {
173
                try {
174
                        input.mark(limit);
175
                } catch (IOException ioe) {
176
                        throw new RuntimeException(ioe.getMessage());
177
                }
178
        }
179

    
180
        /**
181
         * Available.
182
         *
183
         * @return the current number of bytes ready for reading
184
         */
185
        public synchronized int available() throws IOException {
186
                if (input == null) {
187
                        throw new IOException("Stream Closed");
188
                }
189
                if (slack != null) {
190
                        return slack.length - begin;
191
                }
192
                if (input.ready()) {
193
                        return 1;
194
                } else {
195
                        return 0;
196
                }
197
        }
198

    
199
        /**
200
         * Mark supported.
201
         *
202
         * @return false - mark is not supported
203
         */
204
        public boolean markSupported() {
205
                return false; // would be imprecise
206
        }
207

    
208
        /**
209
         * Resets the StringReader.
210
         *
211
         */
212
        public synchronized void reset() throws IOException {
213
                if (input == null) {
214
                        throw new IOException("Stream Closed");
215
                }
216
                slack = null;
217
                input.reset();
218
        }
219

    
220
        /**
221
         * Closes the Stringreader.
222
         *
223
         */
224
        public synchronized void close() throws IOException {
225
                if (input != null) {
226
                        input.close();
227
                        slack = null;
228
                        input = null;
229
                }
230
        }
231
}